From 57a6076aaf2e2d07f8774707724060aebe4c7ffb Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 15 Jul 2025 08:49:34 +0300 Subject: [PATCH 01/49] Update build script: remove "build" dir before creating a new build --- package.json | 3 +- yarn.lock | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 4836bfad5..99c00588a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "craco start --mode ${LOGICAL_ENV:-dev}", "start": "bash start.sh", - "build": "export CI=false && craco build --mode ${LOGICAL_ENV:-prod}", + "build": "rimraf ./build && export CI=false && craco build --mode ${LOGICAL_ENV:-prod}", "build:dev": "craco build --mode ${LOGICAL_ENV:-dev}", "demo": "npx http-server --port 443 -a 0.0.0.0 -S -C ./ssl/rootCA.crt -K ./ssl/rootCA.key -P https://local.topcoder-dev.com? --proxy-options.secure false ./build", "lint": "eslint -c ./src/.eslintrc.js 'src/**/*.{ts,tsx,js,jsx}'", @@ -189,6 +189,7 @@ "react-docgen-typescript": "^2.2.2", "react-hot-loader": "^4.3.3", "resolve-url-loader": "^5.0.0", + "rimraf": "^6.0.1", "sass-loader": "^13.3.3", "serve": "^14.0.1", "start-server-and-test": "^1.14.0", diff --git a/yarn.lock b/yarn.lock index 6fd04826d..afe2bf405 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2529,6 +2529,18 @@ resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== +"@isaacs/balanced-match@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29" + integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== + +"@isaacs/brace-expansion@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3" + integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA== + dependencies: + "@isaacs/balanced-match" "^4.0.1" + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -7722,6 +7734,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" @@ -9995,6 +10016,14 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" +foreground-child@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.2" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" @@ -10314,6 +10343,18 @@ glob@^10.0.0: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" +glob@^11.0.0: + version "11.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.3.tgz#9d8087e6d72ddb3c4707b1d2778f80ea3eaefcd6" + integrity sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA== + dependencies: + foreground-child "^3.3.1" + jackspeak "^4.1.1" + minimatch "^10.0.3" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -11410,6 +11451,13 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" + integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + jake@^10.8.5: version "10.8.5" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" @@ -12814,6 +12862,11 @@ lru-cache@^10.2.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" + integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -13542,6 +13595,13 @@ minimatch@3.1.2, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch dependencies: brace-expansion "^1.1.7" +minimatch@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" + integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== + dependencies: + "@isaacs/brace-expansion" "^5.0.0" + minimatch@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.1.tgz#6c9dffcf9927ff2a31e74b5af11adf8b9604b022" @@ -14261,6 +14321,14 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-to-regexp@0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" @@ -16543,6 +16611,14 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" + integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A== + dependencies: + glob "^11.0.0" + package-json-from-dist "^1.0.0" + rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -17439,7 +17515,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -17453,6 +17529,13 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -19291,7 +19374,7 @@ workbox-window@6.5.4: "@types/trusted-types" "^2.0.2" workbox-core "6.5.4" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -19309,6 +19392,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.0.1.tgz#2101e861777fec527d0ea90c57c6b03aac56a5b3" From 4326b8d20839bde7fdc6b3fc310179fba42cea86 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 16 Jul 2025 17:09:52 +0530 Subject: [PATCH 02/49] Add status message for no Applications --- .../tabs/copilot-applications/CopilotApplications.tsx | 8 ++++++-- .../tabs/copilot-applications/styles.module.scss | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx index 0ddc3f689..81349078f 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx @@ -90,7 +90,7 @@ const CopilotApplications: FC<{ return (
{ - tableData.length > 0 && ( + tableData.length > 0 ? ( - ) + ) : ( +
+ No Applications yet +
+ ) } ) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss index d31ba3f75..ab76a98e6 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss @@ -12,3 +12,11 @@ color: $teal-100; } } + +.noApplications { + margin-top: $sp-6; + display: flex; + justify-content: center; + align-items: center; + font-size: large; +} \ No newline at end of file From f9328c1fd37e48d5168b98a7e00e484d0a717122 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 16 Jul 2025 17:19:09 +0530 Subject: [PATCH 03/49] linting fixes --- .../tabs/copilot-applications/CopilotApplications.tsx | 2 +- .../tabs/copilot-applications/styles.module.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx index 81349078f..376a81eb8 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx @@ -102,7 +102,7 @@ const CopilotApplications: FC<{
No Applications yet
- ) + ) } ) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss index ab76a98e6..9476cf316 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss @@ -19,4 +19,4 @@ justify-content: center; align-items: center; font-size: large; -} \ No newline at end of file +} From f8efdd2d042320e14fd8880b9baf5449c0aed398 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 16 Jul 2025 22:05:11 +0200 Subject: [PATCH 04/49] fix: layout issues in mobile resolution --- .../apply-opportunity-modal/styles.module.scss | 8 ++++++++ .../pages/copilot-opportunity-details/styles.module.scss | 7 +++++++ .../tabs/opportunity-details/styles.module.scss | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss index 897a31420..d083f9e74 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss @@ -4,4 +4,12 @@ .info { margin-bottom: 12px; } + + &:global(.react-responsive-modal-modal) { + :global(.modal-body) { + @include ltemd { + height: 100%; + } + } +} } \ No newline at end of file diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss index 9844231ae..d50ce87a3 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss @@ -27,6 +27,13 @@ padding: 12px 0; } +@media (max-width: 767px) { + .infoRow { + flex-wrap: wrap; + margin: 0; + } +} + .infoText { display: flex; flex-direction: column; diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/opportunity-details/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/opportunity-details/styles.module.scss index 8debc451e..aad91a31d 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/opportunity-details/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/opportunity-details/styles.module.scss @@ -11,6 +11,13 @@ gap: 100px; } +@media (max-width: 767px) { + .content { + flex-direction: column; + gap: 15px; + } +} + .content > div:first-child { flex: 3; } From cc980c67a50de0763430233cd08f1e5ccfae7cea Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 16 Jul 2025 22:06:17 +0200 Subject: [PATCH 05/49] fix: layout issues in mobile resolution --- .../apply-opportunity-modal/styles.module.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss index d083f9e74..c4f79481a 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/apply-opportunity-modal/styles.module.scss @@ -6,10 +6,11 @@ } &:global(.react-responsive-modal-modal) { + :global(.modal-body) { @include ltemd { height: 100%; } } -} + } } \ No newline at end of file From 8d519f42917c86cfcba15d3967a96368e267e818 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Wed, 16 Jul 2025 22:18:24 +0200 Subject: [PATCH 06/49] fix: layout issues in mobile resolution --- .../pages/copilot-opportunity-details/styles.module.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss index d50ce87a3..1e82fa9ca 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/styles.module.scss @@ -17,6 +17,12 @@ color: $teal-100; } +@media (max-width: 767px) { + .header { + line-height: 48px; + } +} + .infoRow { display: flex; From 8968136b293bc62bf05a05e82f37b0525b7a6ebf Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Thu, 17 Jul 2025 16:40:12 +0530 Subject: [PATCH 07/49] PM-1315 Fix issues on Copilot request form --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 3 ++- .../src/pages/copilot-request-form/styles.module.scss | 6 +++++- .../form-input/input-select-react/InputSelectReact.tsx | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 53d98eecb..153b82239 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -250,8 +250,8 @@ const CopilotRequestForm: FC<{}> = () => {

Copilot Request

Hi, - {profile?.firstName} {' '} + {profile?.firstName} ! This form is to request a copilot for your project. Please fill in the details below.

@@ -273,6 +273,7 @@ const CopilotRequestForm: FC<{}> = () => { label='Project' placeholder='Start typing the name of the project' dirty + isClearable error={formErrors.projectId} /> diff --git a/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss b/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss index d8f32e4d7..7f22b73b6 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss @@ -50,7 +50,11 @@ $gradient: linear-gradient( .skillsWrapper { border: 1px solid #aaaaaa; - border-radius: 0.375rem; + border-radius: 0.375rem; + } + + .skillsWrapper:hover { + border-color: #137D60; } .skillsError { diff --git a/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.tsx b/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.tsx index 224f73928..0aea4daa5 100644 --- a/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.tsx +++ b/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.tsx @@ -48,6 +48,7 @@ interface InputSelectReactProps { readonly async?: boolean readonly loadOptions?: (inputValue: string, callback: (option: any) => void) => void readonly filterOption?: (option: InputSelectOption, value: string) => boolean + readonly isClearable?: boolean } /** @@ -105,11 +106,12 @@ const InputSelectReact: FC = props => { // throw the proper event type to the form handler (needs name & form element on target) function handleSelect(option: unknown): void { + const selectedOption = option as InputSelectOption | null props.onChange({ target: { form: findParentFrom(wrapRef.current as HTMLDivElement), name: props.name, - value: (option as InputSelectOption).value, + value: selectedOption?.value || '', }, } as ChangeEvent) } @@ -162,6 +164,7 @@ const InputSelectReact: FC = props => { formatCreateLabel={props.createLabel} onCreateOption={props.onCreateOption} onBlur={handleBlur} + isClearable={props.isClearable} backspaceRemovesValue isDisabled={props.disabled} filterOption={props.filterOption} From 42fc635021b1fb7bc808283704e68961247b411d Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 17 Jul 2025 15:34:24 +0200 Subject: [PATCH 08/49] fix: UI issues in opportunities and requests list --- .../src/pages/copilot-opportunity-list/styles.module.scss | 6 ++++++ .../pages/copilot-requests/CopilotRequestsPage.module.scss | 6 ++++++ .../lib/components/content-layout/ContentLayout.module.scss | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-list/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-list/styles.module.scss index fabdab748..ed569a42f 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-list/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-list/styles.module.scss @@ -7,6 +7,12 @@ gap: 8px; } +@media (max-width: 767px) { + .title { + min-width: 200px; + } +} + .skillPill { background-color: #d6d6d6; color: #333; diff --git a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss index 8465678e4..b36172f28 100644 --- a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss +++ b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss @@ -7,6 +7,12 @@ padding: $sp-2 0; } +@media (max-width: 767px) { + .title { + min-width: 200px; + } +} + .viewRequestIcon { color: $turq-180; padding: 0 $sp-1; diff --git a/src/libs/ui/lib/components/content-layout/ContentLayout.module.scss b/src/libs/ui/lib/components/content-layout/ContentLayout.module.scss index 7cc8a3ac9..628902a35 100644 --- a/src/libs/ui/lib/components/content-layout/ContentLayout.module.scss +++ b/src/libs/ui/lib/components/content-layout/ContentLayout.module.scss @@ -36,6 +36,12 @@ color: $black-100; } } + + @media (max-width: 767px) { + .page-header { + flex-direction: column; + } + } } } } From 2b676832b0119e59e73999466b7f4d902bf0748a Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Mon, 21 Jul 2025 16:41:16 +0530 Subject: [PATCH 09/49] PM-1321 Fix alignment issues on copilot form --- .../src/pages/copilot-request-form/index.tsx | 1 + .../copilot-request-form/styles.module.scss | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 53d98eecb..8343147c4 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -330,6 +330,7 @@ const CopilotRequestForm: FC<{}> = () => { customRadius noCaps leftAlignText + textWrap /> {formErrors.complexity && (

diff --git a/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss b/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss index d8f32e4d7..e7ecacc0e 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-request-form/styles.module.scss @@ -42,6 +42,29 @@ $gradient: linear-gradient( margin-bottom: 1rem; } + @media (max-width: 768px) { + .formRadioBtn { + display: grid; + align-items: start; + grid-template-columns: 1fr 1fr; + gap: 1rem; + } + + .formRadioBtn > *:nth-child(2), + .formRadioBtn > *:nth-child(3) { + grid-column: 2; + } + + .formRadioBtn > *:nth-child(1) { + grid-column: 1; + grid-row: 1 / span 2; + } + + .formRadioBtn > *:nth-child(3) { + grid-row: 2; + } +} + .complexity { display: flex; flex-direction: column; From 9eb0db8313f48ebb6744db5462ef49f375ab897d Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Mon, 21 Jul 2025 22:34:41 +0530 Subject: [PATCH 10/49] PM-1384 Fix date picker in copilot form --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 2 ++ .../form-input/input-date-picker/InputDatePicker.tsx | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 53d98eecb..28fa17cd9 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -376,6 +376,8 @@ const CopilotRequestForm: FC<{}> = () => { error={formErrors.startDate} dirty minDate={new Date()} + maxDate={new Date(new Date().setFullYear(new Date().getFullYear() + 2))} + minYear={new Date()} />

How many weeks will you need the copilot for?

= (props: InputDatePickerProps) const datePickerRef = useRef>(null) const years = useMemo(() => { const maxYear = getYear(props.maxDate ? props.maxDate : new Date()) + 1 - return range(1979, maxYear, 1) + const minYear = getYear(props.minYear ? props.minYear : 1979) + return range(minYear, maxYear, 1) }, [props.maxDate]) const [stateHasFocus, setStateHasFocus] = useState(false) From 472569b9cf694b8a0c5c6f86fbec6eef2421127a Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Mon, 21 Jul 2025 20:58:56 +0200 Subject: [PATCH 11/49] fix: show apply as copilot button for user who is both copilot and admin --- .../src/pages/copilot-opportunity-details/index.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx index 644e8c8cb..c5c934f57 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx @@ -65,6 +65,7 @@ const CopilotOpportunityDetails: FC<{}> = () => { [profile], ) const { data: copilotApplications }: { data?: CopilotApplication[] } = useCopilotApplications(opportunityId) + const appliedCopilotApplications = useMemo(() => copilotApplications?.filter(item => item.userId === profile?.userId ), [copilotApplications, profile]) const { data: members }: { data?: FormattedMembers[]} = useMembers( copilotApplications ? copilotApplications?.map(item => item.userId) : [], ) @@ -164,8 +165,8 @@ const CopilotOpportunityDetails: FC<{}> = () => { title='Copilot Opportunity' buttonConfig={ isCopilot - && copilotApplications - && copilotApplications.length === 0 + && appliedCopilotApplications + && appliedCopilotApplications.length === 0 && opportunity?.status === 'active' && opportunity?.canApplyAsCopilot ? applyCopilotOpportunityButton : undefined } @@ -173,8 +174,8 @@ const CopilotOpportunityDetails: FC<{}> = () => { opportunity?.status === 'active' && isAdminOrPM ? cancelCopilotOpportunityButton : undefined } - infoComponent={(isCopilot && !(copilotApplications - && copilotApplications.length === 0 + infoComponent={(isCopilot && !(appliedCopilotApplications + && appliedCopilotApplications.length === 0 ) && opportunity?.status === 'active' && !!application) && (
From b9353f050993be4ac74ca2e82db07d932218aff5 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Mon, 21 Jul 2025 22:09:10 +0200 Subject: [PATCH 12/49] fix: lint --- .../copilots/src/pages/copilot-opportunity-details/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx index c5c934f57..5ecf58dd0 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx @@ -65,7 +65,10 @@ const CopilotOpportunityDetails: FC<{}> = () => { [profile], ) const { data: copilotApplications }: { data?: CopilotApplication[] } = useCopilotApplications(opportunityId) - const appliedCopilotApplications = useMemo(() => copilotApplications?.filter(item => item.userId === profile?.userId ), [copilotApplications, profile]) + const appliedCopilotApplications = useMemo( + () => copilotApplications?.filter(item => item.userId === profile?.userId), + [copilotApplications, profile], + ) const { data: members }: { data?: FormattedMembers[]} = useMembers( copilotApplications ? copilotApplications?.map(item => item.userId) : [], ) From e6bb39b9ee0b8b62558ea9f120be1ec6abb6da14 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Mon, 21 Jul 2025 22:30:22 +0200 Subject: [PATCH 13/49] fix: notes column --- .../tabs/copilot-applications/CopilotApplications.tsx | 2 +- .../tabs/copilot-applications/styles.module.scss | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx index 376a81eb8..29f8e0aca 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx @@ -54,7 +54,7 @@ const tableColumns: TableColumn[] = [ label: 'Notes', propertyName: 'notes', renderer: (copilotApplication: CopilotApplication) => ( -
+
{copilotApplication.notes}
), diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss index 9476cf316..43efc6329 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/styles.module.scss @@ -20,3 +20,14 @@ align-items: center; font-size: large; } + +.notes { + text-align: left; + max-width: 200px; +} + +@media (max-width: 767px) { + .notes { + min-width: 200px; + } +} \ No newline at end of file From e7deb627d8c7d2cae061c734baae91a79281af10 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 22 Jul 2025 00:03:03 +0300 Subject: [PATCH 14/49] PM-1498 - support for opportunity title --- .../copilots/src/models/CopilotOpportunity.ts | 1 + src/apps/copilots/src/models/CopilotRequest.ts | 1 + .../pages/copilot-opportunity-details/index.tsx | 2 +- .../src/pages/copilot-opportunity-list/index.tsx | 2 +- .../src/pages/copilot-request-form/index.tsx | 16 ++++++++++++++++ .../CopilotRequestModal.tsx | 4 ++++ .../src/pages/copilot-requests/index.tsx | 5 +++++ 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/models/CopilotOpportunity.ts b/src/apps/copilots/src/models/CopilotOpportunity.ts index b53545377..5f3747061 100644 --- a/src/apps/copilots/src/models/CopilotOpportunity.ts +++ b/src/apps/copilots/src/models/CopilotOpportunity.ts @@ -15,6 +15,7 @@ export interface CopilotOpportunity { numHoursPerWeek: number, numWeeks: number, overview: string, + opportunityTitle: string, paymentType: string, otherPaymentType: string, requiresCommunication: 'yes' | 'no', diff --git a/src/apps/copilots/src/models/CopilotRequest.ts b/src/apps/copilots/src/models/CopilotRequest.ts index e295bda9b..f4b4bd381 100644 --- a/src/apps/copilots/src/models/CopilotRequest.ts +++ b/src/apps/copilots/src/models/CopilotRequest.ts @@ -13,6 +13,7 @@ export interface CopilotRequest { numHoursPerWeek: number, numWeeks: number, overview: string, + opportunityTitle: string, paymentType: string, otherPaymentType: string, requiresCommunication: 'yes' | 'no', diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx index 644e8c8cb..120cf2155 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx @@ -194,7 +194,7 @@ const CopilotOpportunityDetails: FC<{}> = () => { ) }

- {opportunity?.projectName} + {opportunity?.opportunityTitle ?? opportunity?.projectName}

diff --git a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx index 9c9bf4d3e..7f3be943d 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx @@ -25,7 +25,7 @@ const tableColumns: TableColumn[] = [ propertyName: 'projectName', renderer: (copilotOpportunity: CopilotOpportunity) => (
- {copilotOpportunity.projectName} + {copilotOpportunity.opportunityTitle}
), type: 'element', diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index ea0f14daa..07463b495 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -248,6 +248,7 @@ const CopilotRequestForm: FC<{}> = () => {

Copilot Request

+

Hi, {' '} @@ -262,6 +263,21 @@ const CopilotRequestForm: FC<{}> = () => { Resolve the errors on the form before submitting

)} + +

Copilot Opprotunity Ttitle

+ +

Select the project you want the copilot for

= props => {
Project
{props.project?.name}
+
+
Title
+
{props.request.opportunityTitle}
+
Opportunity details
{ }, type: 'element', }, + { + label: 'Title', + propertyName: 'opportunityTitle', + type: 'text', + }, { label: 'Type', propertyName: 'type', From 596ca361af03308ed012ceeff030f8eb9e821403 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 22 Jul 2025 00:07:51 +0300 Subject: [PATCH 15/49] typo --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 07463b495..ff96e1ed3 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -264,7 +264,7 @@ const CopilotRequestForm: FC<{}> = () => {

)} -

Copilot Opprotunity Ttitle

+

Copilot Opportunity Title

Date: Tue, 22 Jul 2025 15:25:21 +0530 Subject: [PATCH 16/49] fix linting error --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 28fa17cd9..8d637368d 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -376,7 +376,9 @@ const CopilotRequestForm: FC<{}> = () => { error={formErrors.startDate} dirty minDate={new Date()} - maxDate={new Date(new Date().setFullYear(new Date().getFullYear() + 2))} + maxDate={new Date(new Date() + .setFullYear(new Date() + .getFullYear() + 2))} minYear={new Date()} />

How many weeks will you need the copilot for?

From b784334d6c2b070a9e3ce3f073ec78a851f480f7 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 22 Jul 2025 13:49:17 +0300 Subject: [PATCH 17/49] PM-1499 - allow pms and admins to edit copilot requests --- src/apps/copilots/src/copilots.routes.tsx | 7 +++ .../src/pages/copilot-request-form/index.tsx | 61 ++++++++++++++++--- .../CopilotRequestModal.module.scss | 4 ++ .../CopilotRequestModal.tsx | 17 +++++- .../src/pages/copilot-requests/index.tsx | 12 ++++ .../copilots/src/services/copilot-requests.ts | 15 +++-- 6 files changed, 99 insertions(+), 17 deletions(-) diff --git a/src/apps/copilots/src/copilots.routes.tsx b/src/apps/copilots/src/copilots.routes.tsx index 1a3f9a9e4..ba479d965 100644 --- a/src/apps/copilots/src/copilots.routes.tsx +++ b/src/apps/copilots/src/copilots.routes.tsx @@ -35,6 +35,13 @@ export const childRoutes = [ rolesRequired: [UserRole.administrator, UserRole.projectManager] as UserRole[], route: '/requests/new', }, + { + authRequired: true, + element: , + id: 'CopilotRequestEditForm', + rolesRequired: [UserRole.administrator, UserRole.projectManager] as UserRole[], + route: '/requests/edit/:requestId', + }, { authRequired: true, element: , diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index ff96e1ed3..7725ba985 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -1,7 +1,7 @@ -import { FC, useContext, useMemo, useState } from 'react' +import { FC, useContext, useEffect, useMemo, useState } from 'react' import { bind, debounce, isEmpty } from 'lodash' import { toast } from 'react-toastify' -import { useNavigate } from 'react-router-dom' +import { Params, useNavigate, useParams } from 'react-router-dom' import classNames from 'classnames' import { profileContext, ProfileContextData } from '~/libs/core' @@ -9,21 +9,58 @@ import { Button, IconSolid, InputDatePicker, InputMultiselectOption, InputRadio, InputSelect, InputSelectReact, InputText, InputTextarea } from '~/libs/ui' import { InputSkillSelector } from '~/libs/shared' -import { getProjects } from '../../services/projects' +import { getProjects, ProjectsResponse, useProjects } from '../../services/projects' import { ProjectTypes, ProjectTypeValues } from '../../constants' -import { saveCopilotRequest } from '../../services/copilot-requests' +import { CopilotRequestResponse, saveCopilotRequest, useCopilotRequest } from '../../services/copilot-requests' import styles from './styles.module.scss' + +const editableFields = [ + 'projectId', + 'opportunityTitle', + 'copilotUsername', + 'complexity', + 'requiresCommunication', + 'paymentType', + 'otherPaymentType', + 'projectType', + 'overview', + 'skills', + 'startDate', + 'numWeeks', + 'tzRestrictions', + 'numHoursPerWeek', +] + // eslint-disable-next-line const CopilotRequestForm: FC<{}> = () => { const { profile }: ProfileContextData = useContext(profileContext) const navigate = useNavigate() + const routeParams: Params = useParams() const [formValues, setFormValues] = useState({}) const [isFormChanged, setIsFormChanged] = useState(false) const [formErrors, setFormErrors] = useState({}) const [paymentType, setPaymentType] = useState('') + const { data: copilotRequestData }: CopilotRequestResponse = useCopilotRequest(routeParams.requestId) + + useEffect(() => { + if (copilotRequestData) { + setFormValues(copilotRequestData) + } + }, [copilotRequestData]) + + const { data: projects = [] }: ProjectsResponse = useProjects(undefined, { + filter: { id: copilotRequestData?.projectId }, + isPaused: () => !copilotRequestData?.projectId, + }) + + const projectOptions = useMemo(() => projects.map(p => ({ + label: p.name, + value: p.id, + })), [projects]) + const projectTypes = ProjectTypes ? ProjectTypes.map(project => ({ label: project, value: ProjectTypeValues[project], @@ -198,9 +235,10 @@ const CopilotRequestForm: FC<{}> = () => { if (isEmpty(updatedFormErrors)) { const cleanedFormValues: any = Object.fromEntries( Object.entries(formValues) - .filter(([, value]) => value !== ''), // Excludes null and undefined + // Excludes null and undefined + .filter(([field, value]) => editableFields.includes(field) && value !== ''), ) - saveCopilotRequest(cleanedFormValues) + saveCopilotRequest({ ...cleanedFormValues, id: copilotRequestData?.id }) .then(() => { toast.success('Copilot request sent successfully') setFormValues({ @@ -254,7 +292,13 @@ const CopilotRequestForm: FC<{}> = () => { {' '} {profile?.firstName} ! - This form is to request a copilot for your project. Please fill in the details below. + {' '} + { + copilotRequestData?.id + ? 'Use this form to update the copilot request for your project.' + : 'This form is to request a copilot for your project.' + + ' Please fill in the details below.' + }

{ !isEmpty(formErrors) && ( @@ -291,6 +335,7 @@ const CopilotRequestForm: FC<{}> = () => { dirty isClearable error={formErrors.projectId} + options={projectOptions} />

What type of project are you working on?

@@ -504,7 +549,7 @@ const CopilotRequestForm: FC<{}> = () => {
+
+ + + +
{props.request.status === 'approved' && (
diff --git a/src/apps/copilots/src/services/copilot-requests.ts b/src/apps/copilots/src/services/copilot-requests.ts index be46ffa75..af45f6276 100644 --- a/src/apps/copilots/src/services/copilot-requests.ts +++ b/src/apps/copilots/src/services/copilot-requests.ts @@ -1,7 +1,7 @@ import useSWR, { SWRResponse } from 'swr' import { EnvironmentConfig } from '~/config' -import { xhrGetAsync, xhrPostAsync } from '~/libs/core' +import { xhrGetAsync, xhrPatchAsync, xhrPostAsync } from '~/libs/core' import { buildUrl } from '~/libs/shared/lib/utils/url' import { CopilotRequest } from '../models/CopilotRequest' @@ -23,6 +23,7 @@ function copilotRequestFactory(data: any): CopilotRequest { createdAt: new Date(data.createdAt), data: undefined, opportunity: data.copilotOpportunity?.[0], + startDate: new Date(data.data?.startDate), } } @@ -54,8 +55,8 @@ export type CopilotRequestResponse = SWRResponse * @param {string} requestId - The unique identifier of the copilot request. * @returns {CopilotRequestResponse} - The response containing the copilot request data. */ -export const useCopilotRequest = (requestId: string): CopilotRequestResponse => { - const url = buildUrl(`${baseUrl}/copilots/requests/${requestId}`) +export const useCopilotRequest = (requestId?: string): CopilotRequestResponse => { + const url = requestId && buildUrl(`${baseUrl}/copilots/requests/${requestId}`) const fetcher = (urlp: string): Promise => xhrGetAsync(urlp) .then(copilotRequestFactory) @@ -74,12 +75,14 @@ export const useCopilotRequest = (requestId: string): CopilotRequestResponse => */ export const saveCopilotRequest = (request: CopilotRequest) : Promise => { - const url = `${baseUrl}/${request.projectId}/copilots/requests` + const url = request.id + ? `${baseUrl}/copilots/requests/${request.id}` : `${baseUrl}/${request.projectId}/copilots/requests` + const requestData = { - data: request, + data: { ...request, id: undefined }, } - return xhrPostAsync(url, requestData, {}) + return request.id ? xhrPatchAsync(url, requestData) : xhrPostAsync(url, requestData, {}) } /** From 11dc02335de69153d49210a09b103279a5c720cd Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Wed, 23 Jul 2025 07:38:05 +0300 Subject: [PATCH 18/49] Update validation for copilot opportunity title --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index ead78cd85..c2401917d 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -168,6 +168,11 @@ const CopilotRequestForm: FC<{}> = () => { const updatedFormErrors: { [key: string]: string } = {} const fieldValidations: { condition: boolean; key: string; message: string }[] = [ + { + condition: !formValues.opportunityTitle || formValues.opportunityTitle.length < 7, + key: 'opportunityTitle', + message: 'The title for the opportunity must be at least 10 characters', + }, { condition: !formValues.projectId, key: 'projectId', message: 'Project is required' }, { condition: !formValues.complexity, key: 'complexity', message: 'Selection is required' }, { From c781613c3b2d4dfabd5a1d749334f1856613f448 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Wed, 23 Jul 2025 07:38:56 +0300 Subject: [PATCH 19/49] length --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index c2401917d..6901a8171 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -171,7 +171,7 @@ const CopilotRequestForm: FC<{}> = () => { { condition: !formValues.opportunityTitle || formValues.opportunityTitle.length < 7, key: 'opportunityTitle', - message: 'The title for the opportunity must be at least 10 characters', + message: 'The title for the opportunity must be at least 7 characters', }, { condition: !formValues.projectId, key: 'projectId', message: 'Project is required' }, { condition: !formValues.complexity, key: 'complexity', message: 'Selection is required' }, From 8d7cb5752a7ac877de6115c5102d49c11811929a Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Wed, 23 Jul 2025 11:23:20 +0300 Subject: [PATCH 20/49] PM-1498 - qa fixes --- .../copilots/src/pages/copilot-request-form/index.tsx | 10 ++++++++-- .../copilot-requests/CopilotRequestsPage.module.scss | 5 +++++ src/apps/copilots/src/pages/copilot-requests/index.tsx | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 6901a8171..17d345f66 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -116,7 +116,12 @@ const CopilotRequestForm: FC<{}> = () => { oldFormValues[key] = Array.isArray(value) ? [...value] : [] break default: - value = event.target.value + if (event.type === 'blur') { + value = event.target.value?.trim() + } else { + value = event.target.value + } + break } @@ -169,7 +174,7 @@ const CopilotRequestForm: FC<{}> = () => { const fieldValidations: { condition: boolean; key: string; message: string }[] = [ { - condition: !formValues.opportunityTitle || formValues.opportunityTitle.length < 7, + condition: (formValues.opportunityTitle?.trim().length ?? 0) < 7, key: 'opportunityTitle', message: 'The title for the opportunity must be at least 7 characters', }, @@ -322,6 +327,7 @@ const CopilotRequestForm: FC<{}> = () => { placeholder='Enter a title for the opportunity' value={formValues.opportunityTitle?.toString()} onChange={bind(handleFormValueChange, this, 'opportunityTitle')} + onBlur={bind(handleFormValueChange, this, 'opportunityTitle')} error={formErrors.opportunityTitle} tabIndex={0} forceUpdateValue diff --git a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss index b36172f28..aa032c0c8 100644 --- a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss +++ b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss @@ -22,3 +22,8 @@ color: $turq-140; } } + +.opportunityTitle > * { + display: block; + white-space: break-spaces; +} diff --git a/src/apps/copilots/src/pages/copilot-requests/index.tsx b/src/apps/copilots/src/pages/copilot-requests/index.tsx index e98cadd50..648b420fd 100644 --- a/src/apps/copilots/src/pages/copilot-requests/index.tsx +++ b/src/apps/copilots/src/pages/copilot-requests/index.tsx @@ -183,6 +183,7 @@ const CopilotRequestsPage: FC = () => { type: 'element', }, { + className: styles.opportunityTitle, label: 'Title', propertyName: 'opportunityTitle', type: 'text', From bab6dc01aab6be85aad2ff24378e850901c23d56 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Wed, 23 Jul 2025 11:32:18 +0300 Subject: [PATCH 21/49] use pre-wrap --- .../src/pages/copilot-requests/CopilotRequestsPage.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss index aa032c0c8..bde7159db 100644 --- a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss +++ b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss @@ -25,5 +25,5 @@ .opportunityTitle > * { display: block; - white-space: break-spaces; + white-space: pre-wrap; } From 7d2b0114b6e1f690380d5fd594ff3ab56826dcb2 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 23 Jul 2025 17:26:58 +0530 Subject: [PATCH 22/49] PM-1496 Show payment type in opportunity details --- .../src/pages/copilot-opportunity-details/index.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx index 11b7f5331..40091545c 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/index.tsx @@ -259,6 +259,16 @@ const CopilotOpportunityDetails: FC<{}> = () => { {opportunity?.tzRestrictions}
+
+ +
+ Payment + + {opportunity?.paymentType === 'standard' + ? opportunity.paymentType : opportunity?.otherPaymentType} + +
+
{ initialized && ( From 699f7868116d68e3687db8aaae934ef4c6fcea11 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Wed, 23 Jul 2025 22:53:49 +0530 Subject: [PATCH 23/49] PM-1495 Fix global font color for inputs --- .../form-input/input-select-react/InputSelectReact.module.scss | 2 +- .../form-groups/form-input/input-select/InputSelect.module.scss | 2 +- .../form-groups/form-input/input-text/InputText.module.scss | 2 +- .../form-input/input-textarea/InputTextarea.module.scss | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.module.scss b/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.module.scss index 3fe20ea51..761a49e51 100644 --- a/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.module.scss +++ b/src/libs/ui/lib/components/form/form-groups/form-input/input-select-react/InputSelectReact.module.scss @@ -77,7 +77,7 @@ &:global(__single-value) { @extend .body-small; - color: $black-60; + color: $black-100; white-space: break-spaces; word-break: break-all; text-align: left; diff --git a/src/libs/ui/lib/components/form/form-groups/form-input/input-select/InputSelect.module.scss b/src/libs/ui/lib/components/form/form-groups/form-input/input-select/InputSelect.module.scss index d3673be51..16505e78b 100644 --- a/src/libs/ui/lib/components/form/form-groups/form-input/input-select/InputSelect.module.scss +++ b/src/libs/ui/lib/components/form/form-groups/form-input/input-select/InputSelect.module.scss @@ -5,7 +5,7 @@ align-items: center; margin-top: $sp-1; cursor: pointer; - color: $black-60; + color: $black-100; &-icon { margin-left: auto; diff --git a/src/libs/ui/lib/components/form/form-groups/form-input/input-text/InputText.module.scss b/src/libs/ui/lib/components/form/form-groups/form-input/input-text/InputText.module.scss index 555e29b8e..2ef89273c 100644 --- a/src/libs/ui/lib/components/form/form-groups/form-input/input-text/InputText.module.scss +++ b/src/libs/ui/lib/components/form/form-groups/form-input/input-text/InputText.module.scss @@ -3,7 +3,7 @@ .form-input-text { @extend .body-small; - color: $black-60; + color: $black-100; box-sizing: border-box; border: 0; width: 100%; diff --git a/src/libs/ui/lib/components/form/form-groups/form-input/input-textarea/InputTextarea.module.scss b/src/libs/ui/lib/components/form/form-groups/form-input/input-textarea/InputTextarea.module.scss index 0b5e6eee4..078aa5a13 100644 --- a/src/libs/ui/lib/components/form/form-groups/form-input/input-textarea/InputTextarea.module.scss +++ b/src/libs/ui/lib/components/form/form-groups/form-input/input-textarea/InputTextarea.module.scss @@ -4,7 +4,7 @@ .form-input-textarea { @include font-roboto; @extend .body-small; - color: $black-60; + color: $black-100; box-sizing: border-box; border: none; outline: none; From c26a6663ff3d1da58f31867769fd6e8643b294f2 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Thu, 24 Jul 2025 13:41:56 +0300 Subject: [PATCH 24/49] PM-1499 - update copilot form request --- src/apps/copilots/src/pages/copilot-request-form/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 17d345f66..7aa9eb3b3 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -100,6 +100,8 @@ const CopilotRequestForm: FC<{}> = () => { return updatedErrors }) + + setIsFormChanged(true) } function handleFormValueChange( From 02e5b80ec70878de7b0d04a0c4a0dd3dcbac613b Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Thu, 24 Jul 2025 17:19:01 +0530 Subject: [PATCH 25/49] PM-1496 Show other payment type in list --- .../copilots/src/pages/copilot-opportunity-list/index.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx index 7f3be943d..7ba5eb598 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx @@ -102,7 +102,13 @@ const tableColumns: TableColumn[] = [ { label: 'Payment', propertyName: 'paymentType', - type: 'text', + renderer: (copilotOpportunity: CopilotOpportunity) => ( +
+ {copilotOpportunity.paymentType === 'standard' + ? copilotOpportunity.paymentType : copilotOpportunity.otherPaymentType} +
+ ), + type: 'element', }, ] From d5d3e08539e151a17c5b204390ac7cda4a657971 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 25 Jul 2025 10:35:43 +0300 Subject: [PATCH 26/49] PM-1499 - make sure canceled & fulfilled requests are not editable --- .../CopilotRequestsPage.module.scss | 5 ++++ .../src/pages/copilot-requests/index.tsx | 30 ++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss index bde7159db..8c5108caa 100644 --- a/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss +++ b/src/apps/copilots/src/pages/copilot-requests/CopilotRequestsPage.module.scss @@ -27,3 +27,8 @@ display: block; white-space: pre-wrap; } + +.disabled { + opacity: 0.5; + pointer-events: none; +} diff --git a/src/apps/copilots/src/pages/copilot-requests/index.tsx b/src/apps/copilots/src/pages/copilot-requests/index.tsx index 648b420fd..faeb80158 100644 --- a/src/apps/copilots/src/pages/copilot-requests/index.tsx +++ b/src/apps/copilots/src/pages/copilot-requests/index.tsx @@ -1,6 +1,7 @@ import { FC, useCallback, useContext, useMemo } from 'react' import { find } from 'lodash' import { NavigateFunction, Params, useNavigate, useParams } from 'react-router-dom' +import classNames from 'classnames' import { Button, @@ -58,9 +59,15 @@ const CopilotTableActions: FC<{request: CopilotRequest}> = props => { navigate(copilotRoutesMap.CopilotRequestDetails.replace(':requestId', `${props.request.id}`)) }, [navigate, props.request.id]) + const isEditable = useMemo(() => !['canceled', 'fulfilled'].includes(props.request.status), [props.request.status]); + const editRequest = useCallback(() => { + if (!isEditable) { + return + } + navigate(copilotRoutesMap.CopilotRequestEditForm.replace(':requestId', `${props.request.id}`)) - }, [navigate, props.request.id]) + }, [navigate, props.request.id, isEditable]) const copilotOpportunityId = props.request.opportunity?.id @@ -82,13 +89,20 @@ const CopilotTableActions: FC<{request: CopilotRequest}> = props => {
-
- - - +
+ {isEditable ? ( + + + + ) : ( + + )}
{props.request.status === 'approved' && ( From dbf2f6912dcbce70f6bef617b22c21f7bca34019 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 25 Jul 2025 10:39:17 +0300 Subject: [PATCH 27/49] lint --- src/apps/copilots/src/pages/copilot-requests/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-requests/index.tsx b/src/apps/copilots/src/pages/copilot-requests/index.tsx index faeb80158..b61630075 100644 --- a/src/apps/copilots/src/pages/copilot-requests/index.tsx +++ b/src/apps/copilots/src/pages/copilot-requests/index.tsx @@ -59,7 +59,7 @@ const CopilotTableActions: FC<{request: CopilotRequest}> = props => { navigate(copilotRoutesMap.CopilotRequestDetails.replace(':requestId', `${props.request.id}`)) }, [navigate, props.request.id]) - const isEditable = useMemo(() => !['canceled', 'fulfilled'].includes(props.request.status), [props.request.status]); + const isEditable = useMemo(() => !['canceled', 'fulfilled'].includes(props.request.status), [props.request.status]) const editRequest = useCallback(() => { if (!isEditable) { From 8c4446460d577da46fa28d5fd4cd344dac4066dd Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 25 Jul 2025 11:59:42 +0300 Subject: [PATCH 28/49] PM-1381 - past projects for copilot applicant --- .../CopilotApplications.tsx | 6 ++++++ src/apps/copilots/src/services/members.ts | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx index 29f8e0aca..d5d1b1013 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/CopilotApplications.tsx @@ -35,6 +35,11 @@ const tableColumns: TableColumn[] = [ propertyName: 'activeProjects', type: 'text', }, + { + label: 'Past Projects', + propertyName: 'pastProjects', + type: 'text', + }, { label: 'Status', propertyName: 'status', @@ -81,6 +86,7 @@ const CopilotApplications: FC<{ fulfilment: member?.copilotFulfillment || 0, handle: member?.handle, opportunityStatus: props.opportunity.status, + pastProjects: member?.pastProjects || 0, } }) .sort((a, b) => (b.fulfilment || 0) - (a.fulfilment || 0)) : []) diff --git a/src/apps/copilots/src/services/members.ts b/src/apps/copilots/src/services/members.ts index 85b05a16c..7ee8787d4 100644 --- a/src/apps/copilots/src/services/members.ts +++ b/src/apps/copilots/src/services/members.ts @@ -12,6 +12,7 @@ interface Member { COPILOT: { activeProjects: number, fulfillment: number, + projects: number; } }[] } @@ -19,6 +20,7 @@ interface Member { export interface FormattedMembers extends Member { copilotFulfillment: number, activeProjects: number, + pastProjects: number; } export type MembersResponse = SWRResponse @@ -40,11 +42,16 @@ export const getMembersByUserIds = async ( ) } -const membersFactory = (members: Member[]): FormattedMembers[] => members.map(member => ({ - ...member, - activeProjects: member.stats?.find(item => item.COPILOT?.activeProjects)?.COPILOT?.activeProjects || 0, - copilotFulfillment: member.stats?.find(item => item.COPILOT?.fulfillment)?.COPILOT?.fulfillment || 0, -})) +const membersFactory = (members: Member[]): FormattedMembers[] => members.map(member => { + const copilotStats = member.stats?.find(item => item.COPILOT)?.COPILOT ?? {} as Member['stats'][0]['COPILOT'] + + return { + ...member, + activeProjects: copilotStats.activeProjects || 0, + copilotFulfillment: copilotStats.fulfillment || 0, + pastProjects: copilotStats.projects || 0, + } +}) /** * Custom hook to fetch members by list of user ids From 5deb9549503d89f58457b194d23e397b318b2258 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 25 Jul 2025 12:03:01 +0300 Subject: [PATCH 29/49] lint --- src/apps/copilots/src/services/members.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/copilots/src/services/members.ts b/src/apps/copilots/src/services/members.ts index 7ee8787d4..3ab23b867 100644 --- a/src/apps/copilots/src/services/members.ts +++ b/src/apps/copilots/src/services/members.ts @@ -12,7 +12,7 @@ interface Member { COPILOT: { activeProjects: number, fulfillment: number, - projects: number; + projects: number, } }[] } From fa3371c02860cd0e33d0a9ea798b196cd3b00b90 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 25 Jul 2025 13:31:05 +0300 Subject: [PATCH 30/49] Fix the edit button in the copilot request modal --- .../copilot-request-modal/CopilotRequestModal.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-requests/copilot-request-modal/CopilotRequestModal.tsx b/src/apps/copilots/src/pages/copilot-requests/copilot-request-modal/CopilotRequestModal.tsx index d7e6b6274..202f61924 100644 --- a/src/apps/copilots/src/pages/copilot-requests/copilot-request-modal/CopilotRequestModal.tsx +++ b/src/apps/copilots/src/pages/copilot-requests/copilot-request-modal/CopilotRequestModal.tsx @@ -21,9 +21,15 @@ const CopilotRequestModal: FC = props => { const confirmModal = useConfirmationModal() const navigate = useNavigate() + const isEditable = useMemo(() => !['canceled', 'fulfilled'].includes(props.request.status), [props.request.status]) + const editRequest = useCallback(() => { + if (!isEditable) { + return + } + navigate(copilotRoutesMap.CopilotRequestEditForm.replace(':requestId', `${props.request.id}`)) - }, [navigate, props.request.id]) + }, [isEditable, navigate, props.request.id]) const confirm = useCallback(async ({ title, content, action }: any) => { const confirmed = await confirmModal.confirm({ content, title }) @@ -55,7 +61,9 @@ const CopilotRequestModal: FC = props => { title='Copilot Request' buttons={( <> -
From 82c5f6a8c8d02de971421febfc3bd294b5204dc5 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 31 Jul 2025 08:04:42 +0200 Subject: [PATCH 41/49] fix: lint --- .../tabs/copilot-applications/AlreadyMemberModal.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx index ffe85a614..9b06737c4 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx @@ -33,15 +33,20 @@ const AlreadyMemberModal: FC = props => ( project with ${props.copilotApplication.existingMembership?.role} role.`} { - props.copilotApplication.existingMembership + props.copilotApplication.existingMembership && ['copilot', 'manager'].includes(props.copilotApplication.existingMembership.role) &&
Click 'Confirm' to accept and complete this opportunity.
} { - props.copilotApplication.existingMembership + props.copilotApplication.existingMembership && ['observer', 'customer'].includes(props.copilotApplication.existingMembership.role) - &&
Click 'Confirm' to accept by updating project role to 'Copilot' and complete this opportunity
+ && ( +
+ Click 'Confirm' to accept by updating project role to 'Copilot' + and complete this opportunity +
+ ) }
From ba2fa07bab47327f64085502fbf8280dee56b4f3 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Thu, 31 Jul 2025 18:07:29 +0530 Subject: [PATCH 42/49] PM-1532 Fix sorting on title --- src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx index 7ba5eb598..c780e25cf 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx @@ -22,7 +22,7 @@ import styles from './styles.module.scss' const tableColumns: TableColumn[] = [ { label: 'Title', - propertyName: 'projectName', + propertyName: 'opportunityTitle', renderer: (copilotOpportunity: CopilotOpportunity) => (
{copilotOpportunity.opportunityTitle} From c999669f69773de33e8d637593552b74865e95c7 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 31 Jul 2025 15:49:14 +0200 Subject: [PATCH 43/49] fix: lint --- .../tabs/copilot-applications/AlreadyMemberModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx index 9b06737c4..4980328ed 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx @@ -34,13 +34,13 @@ const AlreadyMemberModal: FC = props => ( { props.copilotApplication.existingMembership - && ['copilot', 'manager'].includes(props.copilotApplication.existingMembership.role) + && ['observer', 'customer'].includes(props.copilotApplication.existingMembership.role) &&
Click 'Confirm' to accept and complete this opportunity.
} { props.copilotApplication.existingMembership - && ['observer', 'customer'].includes(props.copilotApplication.existingMembership.role) + && ['copilot', 'manager'].includes(props.copilotApplication.existingMembership.role) && (
Click 'Confirm' to accept by updating project role to 'Copilot' From 536bbdc706a468359d7bde0c95bd17b818504c80 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Thu, 31 Jul 2025 16:12:11 +0200 Subject: [PATCH 44/49] fix: revert back to old code --- .../tabs/copilot-applications/AlreadyMemberModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx index 4980328ed..9b06737c4 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-details/tabs/copilot-applications/AlreadyMemberModal.tsx @@ -34,13 +34,13 @@ const AlreadyMemberModal: FC = props => ( { props.copilotApplication.existingMembership - && ['observer', 'customer'].includes(props.copilotApplication.existingMembership.role) + && ['copilot', 'manager'].includes(props.copilotApplication.existingMembership.role) &&
Click 'Confirm' to accept and complete this opportunity.
} { props.copilotApplication.existingMembership - && ['copilot', 'manager'].includes(props.copilotApplication.existingMembership.role) + && ['observer', 'customer'].includes(props.copilotApplication.existingMembership.role) && (
Click 'Confirm' to accept by updating project role to 'Copilot' From 2383f9840e465f65e54720f426646eebf2bff205 Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Fri, 1 Aug 2025 12:13:40 +0530 Subject: [PATCH 45/49] PM-1518 Fix 429 too many requests error --- src/apps/copilots/src/services/projects.ts | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/apps/copilots/src/services/projects.ts b/src/apps/copilots/src/services/projects.ts index 45b26131e..85b32f9cf 100644 --- a/src/apps/copilots/src/services/projects.ts +++ b/src/apps/copilots/src/services/projects.ts @@ -11,6 +11,8 @@ const baseUrl = `${EnvironmentConfig.API.V5}/projects` export type ProjectsResponse = SWRResponse +const sleep = (ms: number): Promise<()=> void> => new Promise(resolve => { setTimeout(resolve, ms) }) + /** * Custom hook to fetch and manage projects data. * @@ -24,13 +26,26 @@ export const useProjects = (search?: string, config?: {isPaused?: () => boolean, const params = { name: search, ...config?.filter } const url = buildUrl(baseUrl, params) - const fetcher = (): Promise => { - if (config?.filter?.id && Array.isArray(config.filter.id)) { - const chunks = chunk(config.filter.id, 20) - return Promise.all( - chunks.map(page => xhrGetAsync(buildUrl(baseUrl, { ...params, id: page }))), - ) - .then(responses => responses.flat()) + const fetcher = async (): Promise => { + const ids = config?.filter?.id + + if (Array.isArray(ids)) { + const idChunks = chunk(ids, 20) + const allResults: Project[] = [] + + for (const chunkIds of idChunks) { + // eslint-disable-next-line no-await-in-loop + const response = await xhrGetAsync( + buildUrl(baseUrl, { ...params, id: chunkIds }), + ) + allResults.push(...response) + + // Rate limit: delay 200ms between calls + // eslint-disable-next-line no-await-in-loop + await sleep(200) + } + + return allResults } return xhrGetAsync(url) From f26509e875b71f46f566e53bdff30c01914d526e Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Fri, 1 Aug 2025 12:32:26 +0530 Subject: [PATCH 46/49] PM-1555 Remove sorting from Payment column --- src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx index c780e25cf..045ff0192 100644 --- a/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx +++ b/src/apps/copilots/src/pages/copilot-opportunity-list/index.tsx @@ -100,6 +100,7 @@ const tableColumns: TableColumn[] = [ type: 'number', }, { + isSortable: false, label: 'Payment', propertyName: 'paymentType', renderer: (copilotOpportunity: CopilotOpportunity) => ( From 3a9b115c1267979d9c4f33f245c767aae13b988d Mon Sep 17 00:00:00 2001 From: himaniraghav3 Date: Fri, 1 Aug 2025 13:25:54 +0530 Subject: [PATCH 47/49] Remove dropdown icon if not more than one in list --- src/libs/ui/lib/components/tabs-navbar/TabsNavbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ui/lib/components/tabs-navbar/TabsNavbar.tsx b/src/libs/ui/lib/components/tabs-navbar/TabsNavbar.tsx index 0b2d8f019..9d0ea8c76 100644 --- a/src/libs/ui/lib/components/tabs-navbar/TabsNavbar.tsx +++ b/src/libs/ui/lib/components/tabs-navbar/TabsNavbar.tsx @@ -125,7 +125,7 @@ const TabsNavbar: FC = (props: TabsNavbarProps) => { handleActivateTab={handleActivateTab} handleActivateChildTab={handleActivateChildTab} /> - + {props.tabs.length > 1 && }
From 5b0abec171ec4890010b58646865c6ec80f12495 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Fri, 1 Aug 2025 21:19:19 +0200 Subject: [PATCH 48/49] feat --- .../src/pages/copilot-request-form/index.tsx | 42 ++++++++++++++++--- src/apps/copilots/src/services/projects.ts | 5 +++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/apps/copilots/src/pages/copilot-request-form/index.tsx b/src/apps/copilots/src/pages/copilot-request-form/index.tsx index 750c86f04..b93dd89e9 100644 --- a/src/apps/copilots/src/pages/copilot-request-form/index.tsx +++ b/src/apps/copilots/src/pages/copilot-request-form/index.tsx @@ -1,7 +1,7 @@ import { FC, useContext, useEffect, useMemo, useState } from 'react' import { bind, debounce, isEmpty } from 'lodash' import { toast } from 'react-toastify' -import { Params, useNavigate, useParams } from 'react-router-dom' +import { Params, useNavigate, useParams, useSearchParams } from 'react-router-dom' import classNames from 'classnames' import { profileContext, ProfileContextData } from '~/libs/core' @@ -9,9 +9,10 @@ import { Button, IconSolid, InputDatePicker, InputMultiselectOption, InputRadio, InputSelect, InputSelectReact, InputText, InputTextarea } from '~/libs/ui' import { InputSkillSelector } from '~/libs/shared' -import { getProjects, ProjectsResponse, useProjects } from '../../services/projects' +import { getProject, getProjects, ProjectsResponse, useProjects } from '../../services/projects' import { ProjectTypes, ProjectTypeValues } from '../../constants' import { CopilotRequestResponse, saveCopilotRequest, useCopilotRequest } from '../../services/copilot-requests' +import { Project } from '../../models/Project' import styles from './styles.module.scss' @@ -37,11 +38,13 @@ const CopilotRequestForm: FC<{}> = () => { const { profile }: ProfileContextData = useContext(profileContext) const navigate = useNavigate() const routeParams: Params = useParams() + const [params] = useSearchParams() const [formValues, setFormValues] = useState({}) const [isFormChanged, setIsFormChanged] = useState(false) const [formErrors, setFormErrors] = useState({}) const [paymentType, setPaymentType] = useState('') + const [projectFromQuery, setProjectFromQuery] = useState() const { data: copilotRequestData }: CopilotRequestResponse = useCopilotRequest(routeParams.requestId) @@ -51,15 +54,42 @@ const CopilotRequestForm: FC<{}> = () => { } }, [copilotRequestData]) + const fetchProject = async (): Promise => { + const projectId = params.get('projectId') + + if (!projectId) { + return + } + + const project = await getProject(projectId as string) + + setFormValues((prevValues: any) => ({ + ...prevValues, + projectId: project.id, + })) + setIsFormChanged(true) + setProjectFromQuery(project) + } + + useEffect(() => { + fetchProject() + }, [params]) + const { data: projects = [] }: ProjectsResponse = useProjects(undefined, { filter: { id: copilotRequestData?.projectId }, isPaused: () => !copilotRequestData?.projectId, }) - const projectOptions = useMemo(() => projects.map(p => ({ - label: p.name, - value: p.id, - })), [projects]) + const projectOptions = useMemo(() => { + const projectsFromResponse = projects.map(p => ({ + label: p.name, + value: p.id, + })) + + return projectFromQuery + ? [...projectsFromResponse, { label: projectFromQuery.name, value: projectFromQuery.id }] + : projectsFromResponse + }, [projects, projectFromQuery]) const projectTypes = ProjectTypes ? ProjectTypes.map(project => ({ label: project, diff --git a/src/apps/copilots/src/services/projects.ts b/src/apps/copilots/src/services/projects.ts index 85b32f9cf..096c373ef 100644 --- a/src/apps/copilots/src/services/projects.ts +++ b/src/apps/copilots/src/services/projects.ts @@ -58,6 +58,11 @@ export const useProjects = (search?: string, config?: {isPaused?: () => boolean, }) } +export const getProject = (projectId: string): Promise => { + const url = `${baseUrl}/${projectId}` + return xhrGetAsync(url) +} + export const getProjects = (search?: string, filter?: any): Promise => { const params = { name: `"${search}"`, ...filter } const url = buildUrl(baseUrl, params) From 4da8cb05932b827ca9730bbf7cc477d04f2dd4b4 Mon Sep 17 00:00:00 2001 From: Hentry Martin Date: Fri, 1 Aug 2025 21:21:42 +0200 Subject: [PATCH 49/49] fix: circle ci config updates --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c8df4fd99..93ebaa7d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -222,7 +222,7 @@ workflows: - LVT-256 - CORE-635 - feat/system-admin - - pm-1506_1 + - pm-1365_1 - deployQa: context: org-global