Compare commits

..
Author SHA1 Message Date
sriram veeraghantaandGitHub 1dcea9bcc8 Merge pull request #4569 from makeplane/preview
release: v0.20-dev
2024-05-23 19:55:06 +05:30
NikhilandGitHub b57432818d [WEB - 1408] dev: add logo prop and accounts migration (#4558)
* dev: add logo prop and accounts migration

* dev: add default values for id_token

* dev: update is_active as read only field

* dev: delete all sessions when deactivating account

* dev: add issue description binary

* dev: add logo props for team
2024-05-23 18:08:35 +05:30
Prateek ShouryaandGitHub 6a3c4eb512 [WEB-1216] chore: update module empty state size for consistency. (#4565) 2024-05-23 16:47:34 +05:30
Prateek ShouryaandGitHub ddc28d37d3 [WEB-1404] chore: auth and onboarding improvements (#4564)
* chore: `switch account` modal revamp.

* chore: workspace invitation page message display logic update.

* chore: update `showDeleteAccountModal` state to `showSwitchAccountModal`.
2024-05-23 16:45:23 +05:30
Anmol Singh BhatiaandGitHub 073d453752 chore: plane logo asset updated (#4562) 2024-05-23 14:45:40 +05:30
Prateek ShouryaandGitHub 7089474c11 [WEB-1240] chore: toast messages updates (#4561)
* [WEB-1240] fix: toast messages inconsistency in sub-issues.

* [WEB-1241] chore: update draft issue creation toast message.

* chore: minor logic improvement.
2024-05-23 14:28:11 +05:30
Prateek ShouryaandGitHub 780caf59a0 [WEB-1404] chore: space app infinite loader and scroll fix. (#4559)
* [WEB-1404] chore: space app infinite loader and scroll fix.

* chore: revert back `isLoading` initail state to `true` in user store.
2024-05-23 14:27:16 +05:30
guru_sainathandGitHub c9e6ead3af chore: handled suppert email validation in the admin app (#4560) 2024-05-23 14:04:53 +05:30
sriram veeraghanta d17492319b fix: updating docker urls and base paths 2024-05-23 13:38:20 +05:30
sriram veeraghanta c26c8cfe19 fix: nginx conf file updated by removing rewrites for space location 2024-05-22 20:52:02 +05:30
2b27f39727 [WEB-1380] chore: fix sidebar expanding issue on sign out. (#4557)
* [WEB-1380] chore: fix sidebar expanding issue on sign out.

* chore: update sign-out redirect url.

* dev: update signout view and fix the entrypoint on docker-compose-local

* chore: remove localStorage reset logic for `app_sidebar_collapsed` on sign-out.

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
2024-05-22 20:39:31 +05:30
Anmol Singh BhatiaandGitHub 577996b34a chore: space app logo redirection updated (#4556) 2024-05-22 20:24:47 +05:30
rahulrameshaandGitHub 2a83ac7376 upgrade cmdk version to 1.0 to fix a critical issue (#4554) 2024-05-22 18:53:40 +05:30
Anmol Singh BhatiaandGitHub 5381d0bc35 [WEB-1404] chore: auth improvements (#4553)
* chore: auth page logo and tab head title updated

* chore: auth page logo and tab head title updated

* chore: code refactor

* chore: space app existing user auth validation
2024-05-22 18:49:58 +05:30
Prateek ShouryaandGitHub 63a6be2143 [WEB-1404] chore: auth ui / ux fixes (#4552)
* chore: update deactivated account alert message to show support email if available in env.

* chore: clear error_info on email check.

* chore: fix log-in / sign-up forms alignment and minor ux copy fix.

* fix: auth redirection to `/sign-in` issue.

* chore: update `back to sign in` url in forgot password screen.
2024-05-22 17:31:56 +05:30
rahulrameshaandGitHub ca73a11868 improve error overlay while dragging over a group (#4551) 2024-05-22 17:15:37 +05:30
794183b640 [WEB-1343] chore: add and remove modules in kanban view (#4549)
* chore: removing and adding an issue to module

* chore: removed empty module validation

* modules single API call

* chore: removed the script

---------

Co-authored-by: rahulramesha <rahulramesham@gmail.com>
2024-05-22 17:07:08 +05:30
e99a7accec WEB-1344 chore: Add storybook (#4490)
* Add storybbok integration for UI package

* Exclude stories from tailwind config

* Update gitignore

* chore: disable lint stage

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-05-22 16:36:31 +05:30
rahulrameshaandGitHub c0961586a3 change color of quick add button (#4541) 2024-05-22 16:00:19 +05:30
Satish GandhamandGitHub 6236adf4bc [WEB-1390] chore: Add pre commit hook to check for lint and formatting errors (#4537)
* Add pre commit hook

* Add comments
2024-05-22 15:50:15 +05:30
Prateek ShouryaandGitHub b084844565 [WEB-1401] chore: toast refactor in space app. (#4546)
* [WEB-1401] chore: toast refactor in space app.

* fix: build errors in space app.
2024-05-22 15:39:28 +05:30
Prateek ShouryaandGitHub 1912f6948c [WEB-1386] chore: fix update view button to right even if no filters are applied. (#4548) 2024-05-22 15:37:19 +05:30
rahulrameshaandGitHub fa332a9ba7 fix infinite loop for sub issues (#4550) 2024-05-22 15:36:11 +05:30
9013497a5a fix: authentication views updated with new workflow (#4547)
* dev: update email check endpoint

* fix: auth magic login check

* chore: updated the error code handler and handled authentication workflow

* dev: add magic link login

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: guru_sainath <gurusainath007@gmail.com>
2024-05-22 14:49:06 +05:30
sriram veeraghanta 509d5fe554 fix: docker entrypoint 2024-05-22 13:00:45 +05:30
sriram veeraghanta 9591ccccaa fix: create sync pr workflow 2024-05-22 12:48:47 +05:30
sriram veeraghanta a644d38218 chore: docker entry file name changes 2024-05-22 12:46:41 +05:30
Aaryan KhandelwalandGitHub 639d24bd5a [WEB-1262] refactor: custom hook for common dropdown logic (#4420)
* refactor: custom hook for common dropdown logic

* chore: clear query for label dropdowns
2024-05-22 12:45:51 +05:30
f13c190676 [WEB-1396] chore: remove/ disable all actionable items from deploy url in case url is embedded using Iframe. (#4544)
* fix: is in iframe validation check

* chore: remove/ disable all actionable items from deploy url in case url is embeded using Iframe.

* chore: remove copy issue link option if clipboard write access is not granted.

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-05-22 12:39:34 +05:30
Prateek ShouryaandGitHub 0c80cf3d54 fix: enable toast in admin app. (#4545) 2024-05-22 12:34:57 +05:30
rahulrameshaandGitHub 6eca4a1f1f fix unassigned issues count in analytics page (#4542) 2024-05-22 12:33:36 +05:30
sriram veeraghanta 1c377163d2 fix: converting takeoff scripts to docker entry points 2024-05-22 12:25:27 +05:30
rahulrameshaandGitHub e6d626fbc5 fix list view visual alignments (#4543) 2024-05-22 11:34:15 +05:30
Prateek ShouryaandGitHub 709cd9dd6c [WEB-1177] fix: sub-issues count mutation. (#4516)
* [WEB-1177] fix: sub-issues count mutation.

* chore: refactor sub_issues_count mutation logic.

* fix: build errors.
2024-05-21 17:14:41 +05:30
Prateek ShouryaandGitHub 8a960e269f [WEB-1063] style: fix activity/ comment overflow issue. (#4540) 2024-05-21 16:36:33 +05:30
Anmol Singh BhatiaandGitHub 846991332a [WEB-1385] style: oauth button enhancement (#4539)
* style: oauth button enhancement

* style: space app applied issue filter section styling updated

* style: space app sidebar icon consistency

* chore: issue title input improvement

* fix: create workspace and invite workspace theme issue

* fix: member invite modal improvement
2024-05-21 16:29:30 +05:30
rahulrameshaandGitHub afc2ca65cf [WEB-1138] feat: List lssue Layout Drag and Drop (#4536)
* List Dnd Complete feature

* fix minor bugs in list dnd

* remove double overlay in kanban post refactor

* add missing dependencies to useEffects

* make provision to add to the last issue of the group

* show current child issues to also be disabled if the parent issue is being dragged

* fix last issue border

* fix code static analysis suggestions

* prevent context menu on drag handle
2024-05-21 16:25:57 +05:30
NikhilandGitHub 0f5294c5e2 [WEB - 1387]dev: custom csrf failure view (#4531)
* dev: custom csrf view

* dev: update template to use only css for styling
2024-05-21 15:04:10 +05:30
NikhilandGitHub 410f04c327 dev: rest framework throttling (#4534) 2024-05-21 15:03:01 +05:30
guru_sainathandGitHub 4feec35773 [WEB-1301] chore: handled issues count in project, module, and cycle issues (#4538)
* chore: handled issues count in project, module, and cycle issues

* chore: changed the typo from getIssuesCount to issuesCount
2024-05-21 14:55:29 +05:30
sriram veeraghanta e2ac60e259 fix: adding redirect rules to old signup page 2024-05-21 13:43:54 +05:30
Anmol Singh BhatiaandGitHub f77761b4f9 [WEB-1385] chore: auth screen and space app improvement (#4529)
* chore: instance sign in page alginment

* chore: strength indicator color updated

* chore: confirm password input improvement

* chore: space issue sidebar comment section validation added
2024-05-20 19:03:23 +05:30
sriram veeraghanta c58e241159 chore: update package version 2024-05-20 16:18:11 +05:30
guru_sainathandGitHub 4c5d66d6d1 fix: onboarded steps validation in web app (#4527) 2024-05-20 16:12:56 +05:30
guru_sainathandGitHub 1355873e32 fix: next_path enabled for oauth auth (#4526) 2024-05-20 16:00:32 +05:30
Anmol Singh BhatiaandGitHub 836452f074 [WEB-1319] chore: user default cover image (#4525)
* chore: user default cover image updated

* chore: space app issue sidebar coment section heading updated
2024-05-20 15:43:48 +05:30
rahulrameshaandGitHub 3bfa8f5f88 revert the commented out code, fixing the subIssue mutation (#4524) 2024-05-20 15:42:55 +05:30
Anmol Singh BhatiaandGitHub f8a443d6a6 chore: reset password error handling (#4523) 2024-05-20 14:50:11 +05:30
NikhilandGitHub 35f3716cb5 fix: magic code 500 error on wrong code or expired code (#4521) 2024-05-20 12:56:29 +05:30
sriram veeraghanta 193076636a fix: instance god-mode redirection 2024-05-20 12:53:43 +05:30
NikhilandGitHub efe62bccf3 chore: delete workspace invitation on user deactivation (#4514) 2024-05-20 12:29:49 +05:30
NikhilandGitHub e951cc3cf4 dev: add pg port to configuration (#4517) 2024-05-20 12:29:03 +05:30
2138257da0 [WEB-1319] fix: handled magic sign_in and sign_up error codes in authentication (#4518)
* dev: differentiate error codes for magic code

* fix: handled auth error_codes for magic_sign_in and magic_sign_up

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
2024-05-20 12:23:48 +05:30
guru_sainathandGitHub 603ebeb123 chore: handled the auto reload issue in auth-wrapper and instance wrapper (#4520) 2024-05-20 12:10:54 +05:30
Anmol Singh BhatiaandGitHub b4b111e297 [WEB-1319] chore: auth fixes and enhancement (#4519)
* chore: onboarding invite member button overflow fix

* chore: change password enhancement
2024-05-20 12:05:19 +05:30
rahulrameshaandGitHub edf8109735 [WEB-1249] chore: New Kanban column design changes (#4509)
* new Kanban column design changes

* fix minor build error
2024-05-20 11:38:28 +05:30
Prateek ShouryaandGitHub fe4dea1474 [WEB-1361] fix: comments access specifier mutation issue. (#4515) 2024-05-20 11:32:00 +05:30
Aaryan KhandelwalandGitHub 915ea8a81c fix: page title not displaying (#4513) 2024-05-19 21:40:50 +05:30
sriram veeraghanta 87610399c4 Merge branch 'fix/instance-layouts' of github.com:makeplane/plane into preview 2024-05-18 16:25:51 +05:30
sriram veeraghanta 31ca9e447d fix: instance config errors 2024-05-18 16:22:53 +05:30
Anmol Singh Bhatia 895fbcd5a7 chore: auth mobile screen responsiveness 2024-05-17 20:43:54 +05:30
sriram veeraghanta 69ce0031d0 fix: instance admin layout 2024-05-17 20:32:40 +05:30
Aaryan KhandelwalandGitHub 1178c3b14d fix: show untitle for blank page titles (#4505) 2024-05-17 19:40:12 +05:30
NikhilandGitHub cbca2c78ee [WEB - 1370] dev: remove session save and add callback for providers (#4506)
* dev: remove session save and add callback for providers

* dev: make session save every request as env variable
2024-05-17 19:39:40 +05:30
guru_sainathandGitHub 6f05ec7e74 chore: after signout intead of redirecting to login page we are navigating to the same page where he logged out (#4507) 2024-05-17 19:38:48 +05:30
Bavisetti NarayanandGitHub e3e7c99e11 chore: user favorite sequence (#4501) 2024-05-17 18:51:47 +05:30
Bavisetti NarayanandGitHub fc31186aec chore: snoozed inbox issue (#4487) 2024-05-17 18:19:17 +05:30
guru_sainathandGitHub 564625ee22 fix: handled workspaceSlug and projectId in issue voting component (#4503) 2024-05-17 17:51:14 +05:30
NikhilandGitHub a150a9d268 fix: cache invalidation on set password (#4504) 2024-05-17 17:49:35 +05:30
guru_sainathandGitHub 1bf80847f5 fix: resolved build errors and implemented signout button (#4502) 2024-05-17 16:54:58 +05:30
85b54d2490 dev: migrations (#4489)
* dev: estimates and pages migrations

* dev: favorite and user migrations

* chore: workspace base model

* chore: workspace user properties

* chore: removed unused variables

* chore: favorite view set changes

* chore: default sequence id

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-05-17 15:59:55 +05:30
Anmol Singh BhatiaandGitHub 38f5ecbdf2 [WEB-1330] chore: show password toggle improvement (#4471)
* chore: show password toggle improvement

* fix: merge conflict
2024-05-17 15:51:34 +05:30
NikhilandGitHub 8d860396bd dev: auth callback for runing user post authentication workflows (#4498) 2024-05-17 15:27:34 +05:30
Samuel TorresandGitHub 61e83ed808 Fix state patch api search by external id (#4495) 2024-05-17 15:26:10 +05:30
Manish GuptaandGitHub f7ccf01426 fix: selfhost back to tar.gz (#4500)
* fix: selfhost back to tar.gz

* fix
2024-05-17 15:24:21 +05:30
rahulrameshaandGitHub 90b50a4162 New Minor UX changes to Kanban (#4499) 2024-05-17 14:33:21 +05:30
guru_sainathandGitHub 2988d5e429 [WEB-1319] chore: handled redirection when user is not logged in (#4497)
* chore: handled redirection when user is not logged in

* dev: handle url redirection in space app

* dev: remove user from redis on successful code matching
2024-05-17 14:27:49 +05:30
Aaryan KhandelwalandGitHub c2e293cf3b [WEB-1310] chore: page title can be blank (#4486)
* chore: page title can be blank

* chore: handle undefined page name in the helper function
2024-05-17 12:56:44 +05:30
4c16ed8b23 [WEB-1336] fix: issue dates conflict in the calendar layout (#4480)
* fix: calendar dnd for due dates before issue start date

* chore: start date in calender view

* fix: add existing issues to calendar layout

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-05-17 12:45:28 +05:30
Anmol Singh BhatiaandGitHub f9de1e790c chore: nested issue highlighting improvement (#4488) 2024-05-17 12:17:43 +05:30
Aaryan KhandelwalandGitHub c054b18ad5 chore: prevent route change on canceling confirm dialog (#4493) 2024-05-17 11:36:50 +05:30
Aaryan KhandelwalandGitHub 8fae076fd6 chore: disccard changes made after creating issue (#4484) 2024-05-17 11:35:37 +05:30
sriram veeraghanta 8522db630e fix: build errors 2024-05-17 00:32:23 +05:30
Aaryan KhandelwalandGitHub f547692fe6 chore: hide bot accounts from the collabortors list (#4482) 2024-05-16 23:59:28 +05:30
Anmol Singh BhatiaandGitHub 0c04c3dc14 chore: unwanted loader (#4485) 2024-05-16 23:57:13 +05:30
Aaryan KhandelwalandGitHub 26188f208b [WEB-1204] fix: Kanban and calendar drag and drop in mobile (#4408)
* chore: don't show context menu on mobile devices

* fix: drag and drop in mobile

* chore: default show more options in mobile

* fix: dnd in calendar layout
2024-05-16 23:42:54 +05:30
Anmol Singh BhatiaandGitHub 33079c826d [WEB-1319] chore: instance not ready pages improvement (#4492)
* chore: instance not ready pages improvement

* fix: magic sign up

* chore: issue mutation spinner and command k spinner updated

* chore: forgot password email input disabled

* chore: forgot password email input disabled revert

* chore: unused asset removed
2024-05-16 23:41:30 +05:30
Anmol Singh BhatiaandGitHub 9bf1863f33 [WEB-1345] chore: auth and loader responsiveness (#4494)
* chore: logo spinner improvement

* chore: auth header action improvement
2024-05-16 23:35:53 +05:30
Anmol Singh BhatiaandGitHub fd4aa38dc2 fix: email preferences form reset (#4464) 2024-05-16 19:42:18 +05:30
sriram veeraghanta e6142d8247 fix: adding new apple touch icon 2024-05-16 19:37:37 +05:30
Prateek ShouryaandGitHub a1667f9a0f chore: minor auth related improvements (#4483)
* chore: show `(optional)` in label of non-required fields.

* chore: fix github auth button text color.

* chore: minor ui/ ux improvement in oauth options.
2024-05-16 19:36:09 +05:30
guru_sainathandGitHub 9b92fd4a16 chore: handled ui and preloading in init page (#4491) 2024-05-16 19:28:37 +05:30
sriram veeraghanta 7569c03cec fix: update site manifest with new logo 2024-05-16 18:45:11 +05:30
sriram veeraghanta 669faf7c72 fix: update package info 2024-05-16 17:51:10 +05:30
rahulrameshaandGitHub 1ad7011aac [WEB-1249] feat: Kanban multi dragndrop (#4479)
* Kanban multi dnd

* complete Kanban multi dnd

* add proper brackets to if conditions
2024-05-16 17:29:01 +05:30
guru_sainathandGitHub bab52a2672 [WEB-1319] chore: New authentication workflow (#4481)
* chore: New authentication workflow

* chore: resolved build erros and updated imports in auth

* chore: code optimisation for query param util

* chore: added client for auth forms
2024-05-16 17:17:04 +05:30
37cc8d7b77 [WEB - 1333]fix: session age for admin and user (#4477)
* dev: fix session token save on admin and remove session save every request

* dev: update session cookie age to environment variable

* fix: adding save every request django session

* dev:  nginx configuration

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-05-16 16:17:05 +05:30
sriram veeraghanta e9d80efbc9 fix: build errors 2024-05-16 16:00:47 +05:30
de27cd589a chore: fethc csrf token every time before changing password (#4474)
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
2024-05-16 13:21:01 +05:30
guru_sainathandGitHub 507d7da717 fix: issue peekoverview handled state and query parameters handlers (#4475) 2024-05-16 13:14:36 +05:30
2bf2e98b00 [WEB-1319] fix: handled issue filters mutation and updated the useParams with useSearchParams (#4473)
* chore: updated issue filters in space

* chore: persisting the query params even when we switch layouts

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-05-16 13:07:47 +05:30
Aaryan KhandelwalandGitHub 8ecc461fb1 style: update space and admin app colors (#4465) 2024-05-16 11:35:31 +05:30
Aaryan KhandelwalandGitHub e044a8c2ac chore: encode email before passing it as a query param (#4468) 2024-05-16 11:32:48 +05:30
Anmol Singh BhatiaandGitHub 92c5ccef3d fix: my activity user image overflow (#4469) 2024-05-16 05:09:33 +05:30
sriram veeraghanta 1fac702096 fix: build errors 2024-05-16 05:01:14 +05:30
Anmol Singh BhatiaandGitHub 3bfe0950eb chore: custom theme input placeholder improvement (#4472) 2024-05-16 04:39:26 +05:30
Anmol Singh BhatiaandGitHub 68faced79d chore: no issues found dark mode asset updated (#4466) 2024-05-16 04:35:35 +05:30
Aaryan KhandelwalandGitHub 12cd22bba0 chore: sign out after deactivating account (#4476) 2024-05-16 04:24:50 +05:30
sriram veeraghanta a195f1bf7e fix: space user validation check 2024-05-16 04:03:43 +05:30
Bavisetti NarayanandGitHub b14d44049c [WEB-1328] chore: magic sign-in redirection (#4470)
* chore: magic signin redirection

* chore: expired magic code error message
2024-05-15 22:10:47 +05:30
sriram veeraghanta 0b84142dce Merge branch 'preview' of github.com:makeplane/plane into preview 2024-05-15 22:09:48 +05:30
sriram veeraghanta 7714825bab fix: adding new spinner 2024-05-15 22:09:16 +05:30
NikhilandGitHub 89f2e37b14 [WEB - 1315] fix: user sign up and sign in on a deactivated account (#4460)
* dev: remove email host user and email host password

* dev: fix user account deactivation error

* dev: fix caching issue of last workspace

* dev: add exclude for instances endpoint

* dev: update url redirection for auth
2024-05-15 22:08:54 +05:30
sriram veeraghanta b78a064305 refactor: admin and added new spinner 2024-05-15 21:26:57 +05:30
Anmol Singh BhatiaandGitHub 5ccb4f7d19 [WEB-1324] chore: change password page improvement (#4462)
* chore: change password page improvement

* chore: confirm password input improvement
2024-05-15 19:11:31 +05:30
Anmol Singh BhatiaandGitHub 061d52727e chore: project analytics improvement (#4457) 2024-05-15 18:43:07 +05:30
rahulrameshaandGitHub 69c9ae212b fix profile issues filter (#4461) 2024-05-15 18:42:43 +05:30
sriram veeraghanta 0587c50ced fix: github setup workflow 2024-05-15 17:42:30 +05:30
guru_sainathandGitHub e1197f2b8f chore: handled multiple children rendering in the space layout (#4459) 2024-05-15 16:28:38 +05:30
Ramesh Kumar ChandraandGitHub 751a4a3b21 [WEB-1311] fix: Issue link copy shortcut macOS (#4455)
* chore: issue link copy shortcut in macos

* chore: dynamic shortcut key render in shortcut pop up

* chore: changing button depending on the os
2024-05-15 15:55:44 +05:30
sriram veeraghanta a2fbd6132b refactor: publish boards 2024-05-15 02:25:38 +05:30
sriram veeraghanta 2b196ba1f1 fix: window workflow build error 2024-05-14 22:51:07 +05:30
sriram veeraghanta 8f6d9b8aca fix: build errors 2024-05-14 22:09:29 +05:30
sriram veeraghanta bcc4524f7f fix: admin auth related fixes 2024-05-14 20:55:07 +05:30
9b7b23f5a2 [WEB-1309] fix: auth fixes (#4456)
* dev: magic link login and email password disable

* dev: user account deactivation

* dev: change nginx conf routes

* feat: changemod space

* fix: space app dir fixes

* dev: invalidate cache for instances when creating workspace

* dev: update email templates for test email

* dev: fix build errors

* fix: auth fixes and improvement (#4452)

* chore: change password api updated and missing password error code added

* chore: auth helper updated

* chore: disable send code input suggestion

* chore: change password function updated

* fix: application error on sign in page

* chore: change password validation added and enhancement

* dev: space base path in web

* dev: admin user deactivated

* dev: user and instance admin session endpoint

* fix: last_workspace_id endpoint updated

* fix: magic sign in and email password check added

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: guru_sainath <gurusainath007@gmail.com>
2024-05-14 20:53:51 +05:30
ab6f1ef780 [WEB-1298] chore: project cycle revamp (#4454)
* chore: cycle endpoint changes

* chore: completed cycle icon updated

* chore: project cycle list revamp and code refactor

* chore: cycle page improvement

* chore: added created by in retrieve endopoint

* fix: build error

* chore: cycle list page disclosure button improvement

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-05-14 19:22:08 +05:30
sriram veeraghantaandGitHub febf19ccc0 feat: converting space app to use nextjs app dir (#4451)
* feat: changemod space

* fix: space app dir fixes

* fix: build errors
2024-05-14 14:26:54 +05:30
sriram veeraghanta 087d54a261 fix: worflow update 2024-05-14 14:26:23 +05:30
Bavisetti NarayanandGitHub c2ce3ada14 chore: update issue link (#4450) 2024-05-14 13:49:14 +05:30
dbc0d7019b [WEB - 1302]dev: nginx headers and auth error codes. (#4449)
* dev: add nginx headers

* fix: handled error messages in admin

---------

Co-authored-by: guru_sainath <gurusainath007@gmail.com>
2024-05-14 13:46:05 +05:30
Manish GuptaandGitHub 2593dc8afc added optional env FORCE_CPU and updated README (#4446) 2024-05-14 13:45:04 +05:30
Satish GandhamandGitHub 18ba4009e0 - Stop the default behavior on the custom menu button. (#4440)
- Refactor menu click handler function
2024-05-13 13:05:10 +05:30
Aaryan KhandelwalandGitHub 198a2a63f2 [WEB-1271] fix: show only joined projects in the filters list (#4417) 2024-05-13 12:06:34 +05:30
sriram veeraghanta 3723ece8d5 fix: postcss upgrade to latest version 2024-05-11 18:55:47 +05:30
sriram veeraghanta 91a66a757a fix: console warnings 2024-05-11 17:47:00 +05:30
Anmol Singh BhatiaandGitHub 4aed6e7aed fix: issue layout application error (#4437) 2024-05-11 16:29:53 +05:30
sriram veeraghanta 16d8dfc86e fix: build errors 2024-05-11 15:14:59 +05:30
Anmol Singh BhatiaandGitHub 3355be9c9c [WEB-1254] chore: list layout indentation enhancement and cycle list page ui improvement (#4435)
* chore: list layout indentation improvement

* chore: cycle list layout spacing and date ui updated

* chore: platform ui improvement
2024-05-11 14:47:56 +05:30
sriram veeraghanta 2ef3c06da0 fix: redirection issues and instance validation changes 2024-05-10 19:34:40 +05:30
M. PalanikannanandGitHub 0ad8bf7664 [WEB-1118] fix: table selections using drag handle fixed (#4429)
* fix: table selections in using drag handle fixed

* fix: not show drag handles for empty p tags
2024-05-10 17:32:23 +05:30
88ebda42ff fix: authentication redirection and UI (#4432)
* dev: update python version

* dev: handle magic code attempt exhausted

* dev: update app, space and god mode redirection paths

* fix: handled signup and signin workflow

* chore: auth input error indication and autofill styling improvement

* dev: add app redirection urls

* dev: update redirections

* chore: onboarding improvement

* chore: onboarding improvement

* chore: redirection issue in space resolved

* chore: instance empty state added

* dev: fix app, space, admin redirection in docker setitngs

---------

Co-authored-by: guru_sainath <gurusainath007@gmail.com>
Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
2024-05-10 17:30:38 +05:30
M. PalanikannanandGitHub 2d1201cc92 fix: button click propagation stopped (#4430) 2024-05-10 16:41:13 +05:30
rahulrameshaandGitHub b725c69882 list and spreadsheet sub issues mutation issue (#4415) 2024-05-10 16:14:15 +05:30
Manish GuptaandGitHub 74eb50aa1a selfhosting fixes for custom branch and platform (#4431) 2024-05-10 16:08:04 +05:30
Anmol Singh BhatiaandGitHub dc77e4afdb chore: project publish modal improvement (#4422) 2024-05-10 15:25:16 +05:30
sriram veeraghanta 27315a8aa2 Merge branch 'preview' of github.com:makeplane/plane into preview 2024-05-10 15:24:32 +05:30
Anmol Singh BhatiaandGitHub da78933c61 [WEB-1274] chore: issue spreadsheet enhancement (#4423)
* chore: border and background remove from cycle and module select

* choe: indentation improvement
2024-05-10 15:24:18 +05:30
sriram veeraghanta 0ab2a98777 Merge branch 'preview' of github.com:makeplane/plane into preview 2024-05-10 15:24:13 +05:30
sriram veeraghanta 40560109b5 fix: admin app redirections 2024-05-10 15:23:51 +05:30
Anmol Singh BhatiaandGitHub 0037377c8f chore: project card enhancement (#4424) 2024-05-10 15:22:01 +05:30
Anmol Singh BhatiaandGitHub 0af55e7bbb [WEB-1250] chore: module list enhancement (#4425)
* chore: move module sub-header to app header

* chore: gantt header improvement, remove title

* chore: progress indicator size reduced

* chore: replace members with lead and updated start and end date ui
2024-05-10 15:21:05 +05:30
Anmol Singh BhatiaandGitHub 57eda34082 chore: notification action item enhancement (#4426) 2024-05-10 15:19:59 +05:30
Anmol Singh BhatiaandGitHub e396424db7 [WEB-1251] chore: view list enhancement (#4427)
* chore: moved search query to mobx store

* chore: moved view sub-header to app header

* chore: created by avatar added in view item list
2024-05-10 15:19:05 +05:30
sriram veeraghanta 243680132e fix: space re-directions 2024-05-10 03:46:45 +05:30
547a76ae55 fix: admin and space redirections (#4419)
* dev: add admin and space base url

* fix: formatting

* dev: add app,space and admin base url to the api env

* fix: updated app base urls redirection

* dev: add change password endpoint

* dev: add none as default for base url

* dev: space password management endpoints

* fix: docker env update

* fix: docker and env settings

* fix: docker changes

* fix: next config update

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: guru_sainath <gurusainath007@gmail.com>
2024-05-10 02:32:42 +05:30
sriram veeraghanta 2320b33189 Merge branch 'preview' of github.com:makeplane/plane into preview 2024-05-09 21:06:08 +05:30
sriram veeraghanta 45bb1153ee fix: removing deploy with nginx env 2024-05-09 21:05:51 +05:30
Anmol Singh BhatiaandGitHub b8768d7274 fix: spreadsheet layout sticky column (#4416)
* fix: spreadsheet layout sticky column

* fix: spreadsheet layout sticky column
2024-05-09 19:06:39 +05:30
58bf056ddb fix: auth redirection issues in the web, space and admin apps (#4414)
* fix: login redirection

* dev: log the user out when deactivating the account

* dev: update redirect uris for google and github

* fix: redirection url and invitation api and add redirection to god mode in nginx

* dev: add reset password redirection

* dev: update nginx headers

* dev: fix setup sh and env example and put validation for use minio when fetching project covers

* dev: stabilize dev setup

* fix: handled redirection error in web, space, and admin apps

* fix: resovled build errors

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
2024-05-09 17:46:31 +05:30
rahulrameshaandGitHub 692f570258 [WEB-1134] fix: module link mutation issue (#4413)
* fix module link mutation issue

* reference moduleDetails?.link_module inside a prop of Disclosure instead of in a div
2024-05-09 16:49:24 +05:30
Anmol Singh BhatiaandGitHub 11cd9f57d7 chore: applied filters update view button alignment improvement (#4407) 2024-05-09 15:52:56 +05:30
Aaryan KhandelwalandGitHub 3a66986785 [WEB-1256] fix: accept image as a valid comment (#4409)
* fix: accept image as a valid comment

* fix: update space app helper function
2024-05-09 15:52:17 +05:30
rahulrameshaandGitHub d8ab3e0087 [WEB-1139] chore: Calendar pragmatic dnd (#4410)
* replace Pragmatic DND for calendar

* remove unnecessary check
2024-05-09 15:51:49 +05:30
sriram veeraghanta 9d2d9c59ca fix: workflow updates 2024-05-09 02:52:00 +05:30
sriram veeraghanta cfdcda4445 fix: build test workflow update 2024-05-09 01:41:48 +05:30
sriram veeraghanta 230fd961c7 feat: adding admin service to workflow 2024-05-09 00:56:18 +05:30
+2 59335618b4 feat: session auth implementation (#4411)
* feat: session authentication and god-mode implementation (#4302)

* dev: move authentication to base class for credentials

* chore: new account creation

* dev: return error as query parameter

* dev: accounts and profile endpoints for user

* fix: user store updates

* fix: store fixes

* fix: type fixes

* dev: set is_password_autoset and is_email_verifier for auth providers

* dev: move all auth configuration to different apps

* dev: fix circular imports

* dev: remove unused imports

* dev: fix imports for authentication

* dev: update endpoints to use rest framework api viewa

* fix: onboarding fixes

* dev: session model changes

* fix: session model and add check for last name first name and avatar

* dev: fix referer redirect

* dev: remove auth imports

* dev: fix imports

* dev: update migrations

* fix: instance admin login

* comflict: conflicts resolved

* dev: fix import errors and email check endpoint

* fix: error messages and redirects after login

* dev: configs api

* fix: is github enabled boolean

* dev: merge config and instance api

* conflict: merge conflict resolved

* dev: instance admin sign up endpoint

* dev: enable magic link login

* dev: configure instance variables for github and google enabled

* chore: typo fixes

* fix: god mode docker file changes

* build-error: resolved build errors

* fix: docker compose changes

* dev: add email credential check endpoint

* fix: minor package changes

* fix: docker related changes

* dev: add nginx rules in the nginx template

* dev: refactor the url patterns

* fix: docker changes

* fix: docker files for god-mode

* fix: static export

* fix: nginx conf

* dev: smtp sender refused exception

* fix: godmode fixes

* chore: god mode revamp.

* dev: add csrf secured flag

* fix: oauth redirect uri and session settings

* chore: god mode app changes.  (#3982)

* chore: send test email functionality.

* style: authentication methods page UI revamp.

* chore: create workspace popup.

* fix: user me endpoint

* dev: fix redirection after authentication

* dev: handle god mode redirection

* fix: redirections

* fix: auth related hooks

* fix: store related fixes

* dev: fix session authentication for rest apis

* fix: linting errors

* fix: removing references of useStore=

* dev: fix redirection and password validation

* dev: add useUser hook

* fix: build fixes and lint issues

* fix: removing useApplication hook

* fix: build errors

* fix: delete unused files

* fix: auth build fixes

* fix: bugfixes

* dev: alter avatar to support more than 255 chars

* dev: fix profile endpoint and increase session expiry time and update session on every request

* chore: resolved the migration

* chore: resolved merge conflicts

* dev: error codes and error messages for the auth flow

* dev: instance admin sign up and sign in endpoint

* dev: use zxcvbn to validate password strength

* dev: add extra parameters when error handling on instance god mode

* chore: auth init

* chore: signin/ signup form ui updates and password strength meter.

* chore: update password fields.

* chore: validations and error handling.

* chore: updated sign-up form

* chore: updated workflow and updated the code structure

* chore: instance empty state for god-mode.

* chore: instance and auth wrappers update

* fix: renaming godmode

* fix: docker changes

* chore: updated authentication wrappers

* chore: updated the authentication workflow and rendered all pages

* fix: build errors

* fix: docker related fixes

* fix: tailing slash added to space and admin for valid nginx locations

* chore: seperate pages for signup and login

* git-action modified for admin file changes

* feature build action updated for admin app

* self host modified

* chore: resolved build errors and handled signin and signup in a seperate route

* chore: sign-in and sign-up revamp.

* fix: migration conflicts

* dev: migrations

* chore: handled redirection

* dev: admin url

* dev: create seperate endpoint for instance admin me

* dev: instance admin endpoint

* git action fixed

* chore: handled auth wrappers

* dev: add serializer and remove print logs

* fix: build errors

* dev: fix migrations

* dev: instance folder structuring

* fix: linting errors

* chore: resolved build errors

* chore: updated store and auth workflow and updates api service types

* chore: Replaced Next Link with Anchoer tag for god-mode redirection

* add 3333 port to allowed origins

* make password login working again

* dev: fix redirection, add admin signout endpoint and fix email credential check endpoint

* fix unique code sign in

* fix small build error

* enable sign out

* dev: add google client secret variable to configure instance

* dev: add referer for redirection

* fix origin urls for oauths

* admin setup and login separation

* dev: fix user redirection and tour completed endpoint

* fix build errors

* dev: add set password endpoint

* dev: remove user creation logic for redirection

* fix unique code page

* fix forgot password

* chore: onboarding revamp.

* dev: fix workspace slug redirection in login

* chore: invited user onboarding flow update.

* chore: fix switch or delete account modal.

* fix members exception

* refactor auth flows and add invitations to auth flow

* fix sig in sign up url

* fix action url

* fix build errors

* dev: fix user set password when logging in

* dev: reset password endpoint

* chore: confirm password validation for signup and onboarding.

* enable reset password

* fix build error

* chore: minor UI updates.

* chore: forgot and reset password UI revamp.

* fix authentication re directions

* dev: auth redirections

* change url paths for signup and signin

* dev: make the user logged in when changing passwords

* dev: next path redirection for web and space app

* dev: next path for magic sign in endpoint

* dev: github space endpoint

* chore: minor ui updates and fixes in web app.

* set password screen

* fix multiple unique code generation

* dev: next path base redirection

* dev: remove print logs

* dev: auth space endpoints

* fix build errors

* dev: invalidate cache on configuration update, god mode exception errors and authentication failed code

* dev: fix space endpoints and add extra endpoints

* chore: space auth revamp.

* dev: add sign up for space app

* fix: build errors.

* fix: auth redirection logic.

* chore: space app onboarding revamp.

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com>
Co-authored-by: Manish Gupta <manish@mgupta.me>
Co-authored-by: = <=>
Co-authored-by: rahulramesha <rahulramesham@gmail.com>

* chore: updated file structure for admin

* chore: updated admin-sidebar

* chore: auth error handling

* chore: onboarding UI updates and dark mode fixes.

* chore: add `user personalization` step to onboarding profile setup screen.

* chore: fix minor UI bugs

* chore: authentication workflow changes

* chore: handled signin workflow

* style: switch or delete account workflow

* chore: god mode redirection URL

* feat(dashboard): improve label readability (#4321)

change none label for all time in dashbard filters

* chore: god-mode redirection

* chore: onboarding ui updates and accept invitation workflow updates.

* chore: rename unique code auth form.

* style: space auth ux copy.

* chore: updated intance and auth wrapper logic

* chore: update default layout style.

* chore: update confirm password.

* chore: backend redirection

* style: update banner ui

* chore: minor ui updates and validation fix.

* chore: removed old auth hook

* chore: handled auth wrapper

* chore: handled store loaders in the user

* chore: handled logs

* chore: add loading spinners for all auth and onboarding form buttons.

* chore: add background pattern in admin auth forms and minor ui fixes.

* chore: UI changes and revamp components for authentication

* chore: auth UI consistency in web, space and admin.

* chore: resolved build errors

* chore: removed old auth hooks

* chore: handled lint errors in use accounts

* chore: updated authentication wrapper logic in web app

* [WEB -1149] dev: update dependencies (#4333)

* dev: upgrade dependencies remove unwanted dependency and add ruff as local dependency

* dev: add comments

* chore: authentication wrapper fetch user

* chore: updated store loader

* chore: removed old auth wrapper and replaced the imports with new auth wrapper

* chore: join workspace invitation workflow updates

* chore: build error resolved in deploy

* chore: handled onboarding step error in web app

* chore: SMTP Name and Password validation removed

* chore: handled seo and signout logic and new user popup

* chore: added redirection to plane in the sidebar

* chore: resolved build errors

* dev: admin session cookie update

* chore: updated cookie session time for admin

* dev: add start date and end date to projects (#4355)

* chore: add email security dropdown and remove SMTP username and password validation.

* chore: add tooltip to admin sidebar help-section.

* chore: add dropdown to collapsed admin sidebar.

* chore: profile themning

* chore: updated page error messages and theme in command palette

* dev: add email validation in email check apis

* dev: remove start date and end date from project

* chore: updated space folder structure and updated the store hooks

* dev: error codes for authentication

* chore: handled authentication in space and web apps

* chore: banner redirect handling the email

* dev: god mode error codes

* chore: updated error codes

* chore: updated onboarding images

* dev: signout endpoints and saving login domain while creating sessions

* feat: Self Host Data Backup (#4383)

* feat: implemented backup , support for docker-compose tool, readme updated

* minor fix in shell script

* codacy fixes

* chore: handled build errors in web

* chore: updated react, react-dom, and next versions

* chore: updated password autioset in the signin

* dev: add logo prop to views and pages

* chore: updated api service and handled the set password in store

* chore: handled build errors and code cleanup

* dev: return 401 when the session is not valid

* dev: users/me exception for api

* chore: installed lodash in space app

* dev: add auth route in nginx

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com>
Co-authored-by: Manish Gupta <manish@mgupta.me>
Co-authored-by: rahulramesha <rahulramesham@gmail.com>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
Co-authored-by: Daniel Alba <56451942+redrum15@users.noreply.github.com>
Co-authored-by: Nikhil <118773738+pablohashescobar@users.noreply.github.com>
2024-05-08 23:01:20 +05:30
sriram veeraghanta ae43d05714 fix: upgrading posthog 2024-05-08 19:27:48 +05:30
Anmol Singh BhatiaandGitHub e604cfeec9 [WEB-1040] fix: list layout indentation fix (#4406) 2024-05-08 17:28:28 +05:30
Aaryan KhandelwalandGitHub 32e601a8e6 chore: remove description trim logic (#4396) 2024-05-08 15:42:52 +05:30
Bavisetti NarayanandGitHub 50e3174ea8 chore: email templates (#4392) 2024-05-08 15:41:41 +05:30
Aaryan KhandelwalandGitHub f2749f693f [WEB-1211] fix: inbox issue description revalidate (#4388) 2024-05-08 14:47:18 +05:30
Aaryan KhandelwalandGitHub 3b17dc51ba [WEB-1208] fix: todo list item word break (#4405) 2024-05-08 14:44:18 +05:30
Anmol Singh BhatiaandGitHub 2aaf0a1637 [WEB-1040] chore: list layout sub issue nesting implementation (#4404) 2024-05-08 14:39:27 +05:30
sriram veeraghanta f09dd3d782 Merge branch 'preview' of github.com:makeplane/plane into preview 2024-05-08 14:24:48 +05:30
sriram veeraghanta 2cbb2db02e fix: community edition label 2024-05-08 14:24:19 +05:30
Aaryan KhandelwalandGitHub f7babd682e dev: upgrade lucide-react version to the latest one (#4397) 2024-05-08 14:01:05 +05:30
Anmol Singh BhatiaandGitHub a46c507ca1 [WEB-1040] chore: spreadsheet indentation improvement (#4391)
* chore: spreadsheet indentation improvement

* chore: spreadsheet layout sub issu nesting improvement

* chore: sub issue spacing improvement

* chore: spreadsheet layout sub issue toggle button improvement
2024-05-08 13:59:51 +05:30
Prateek ShouryaandGitHub 10efd8d1d9 [WEB-1236] chore: add Create page button to public/ private page empty state. (#4401) 2024-05-08 13:43:08 +05:30
Prateek ShouryaandGitHub 6efa135e9e [WEB-1217] style: fix inconsistency in height of project type and lead dropdown in create project modal. (#4400) 2024-05-08 13:42:40 +05:30
Aaryan KhandelwalandGitHub 6793b9e6fa [WEB-] chore: show code block copy button only on hover (#4361) 2024-05-08 13:42:11 +05:30
Prateek ShouryaandGitHub 760063ec75 [WEB-1182] style: fix inbox state filter title. (#4399) 2024-05-08 13:41:58 +05:30
Prateek ShouryaandGitHub 1cbbddb1be [WEB-1215] chore: display favorite module filter in applied filter section. (#4402)
* [WEB-1215] chore: display `favorite module` filter in applied filter section.

* fix: build errors.
2024-05-08 13:40:58 +05:30
Aaryan KhandelwalandGitHub cc4bb385fe [WEB-] chore: trigger command k from input fields and editors (#4362) 2024-05-08 13:40:25 +05:30
rahulrameshaandGitHub 13e6a67321 [WEB-1140] chore: Gantt pragmatic dnd (#4390)
* Gantt Drag and drop migration and enable Dnd in Modules and Cycles Gantt

* fix minor UI and code issues
2024-05-08 13:38:58 +05:30
Bavisetti NarayanandGitHub b8f1734738 fix: draft archive issues (#4393) 2024-05-07 20:31:44 +05:30
Bavisetti NarayanandGitHub d946c51ef1 chore: created by key changed (#4389) 2024-05-07 19:22:00 +05:30
NikhilandGitHub a40517015b [WEB - 1213] fix: module webhook (#4385)
* dev: fix module webhook

* dev: correct the comment

* dev: handle does not exist exception
2024-05-07 15:51:08 +05:30
Aaryan KhandelwalandGitHub 967ad77078 fix: set focus on editor conditionally after image upload (#4387) 2024-05-07 15:49:11 +05:30
Prateek ShouryaandGitHub f5f683b8b8 [WEB-1086] chore: update toast messages for consistency. (#4384) 2024-05-07 15:03:24 +05:30
Anmol Singh BhatiaandGitHub 2aef40b7c5 [WEB-1176] chore: filter dropdown indicator and code refactor (#4379)
* chore: filter dropdown indicator and code refactor

* chore: code refactor

* chore: code refactor

* chore: code refactor

* chore: refactor calculateTotalFilters function with typescript generics
2024-05-07 14:56:19 +05:30
1eba6c24cd [WEB-859] chore: inbox sidebar improvement (#4381)
* chore: added created by field in inbox issue

* chore: inbox sidebar list item created by avatar added

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-05-07 14:10:27 +05:30
Prateek ShouryaandGitHub a46eccf300 [WEB-1117] chore: add tool tip for Snooze under Notification Panel. (#4377) 2024-05-07 14:08:02 +05:30
Aaryan KhandelwalandGitHub 780b239ecb [WEB-1142] chore: optimistically add issue to cycle/modules (#4334)
* chore: optimistically add issue to cycle and module

* chore: update toast alerts

* refactor: module issue store

* chore: added addCycleToIssueFunction
2024-05-07 14:05:56 +05:30
Anmol Singh BhatiaandGitHub a85517de99 [WEB-1098] chore: dropdowns enhancement (#4375) 2024-05-07 14:02:48 +05:30
P BandGitHub fb68b77068 Changed tagline, description, and disclaimer (#4382)
- Minor grammatical and language corrections
- Another update coming soon
2024-05-07 13:56:03 +05:30
Aaryan KhandelwalandGitHub 20e7dc68e6 [WEB-1127] style: create and delete modals' consistency (#4345)
* style: update modals typography, alignment

* style: made the modal separator full width

* style: delete modals consistency

* style: update the remaining delete modals

* chore: delete modal secondary button text

* style: update the remaining create modals

* chore: update cancel button text

* chore: created modal core

* style: modals responsiveness
2024-05-07 12:44:36 +05:30
5ef51edad7 [WEB-1134] fix: module link create and delete mutation (#4373)
* fix: module link create and delete mutation

* chore: module link mutation store updates

* chore: code refactor

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
2024-05-06 17:56:35 +05:30
Bavisetti NarayanandGitHub 06a664f6b9 [WEB-1151] fix: email notification for mentions (#4360)
* chore: mention notification

* chore: mention filters
2024-05-06 16:07:56 +05:30
Anmol Singh BhatiaandGitHub cdab12e4b6 [WEB-1157] chore: label select improvement (#4370) 2024-05-06 15:30:58 +05:30
Anmol Singh BhatiaandGitHub 59f1cc1962 [WEB-1114] chore: recent activity message updated (#4371) 2024-05-06 15:28:33 +05:30
Anmol Singh BhatiaandGitHub 562e50815d [WEB-1007] chore: invalid issue error empty state added (#4372) 2024-05-06 15:27:56 +05:30
rahulrameshaandGitHub 463f4781ae [WEB-1137] fix: Firefox distorted vertical text (#4376) 2024-05-06 15:22:45 +05:30
Bavisetti NarayanandGitHub 653005bb3b [WEB-1206] chore: bulk delete api logs (#4374)
* chore: bulk delete api logs

* chore: deletion time change
2024-05-06 15:19:03 +05:30
NikhilandGitHub f1fda4ae4a [WEB - 1122] fix: webhook for issues, issue comments, projects, cycles and modules. (#4330)
* dev: update webhook logic for issues

* dev: update issue webhooks for cycle and module

* dev: webhook for comment

* dev: issue attachment webhooks

* dev: add logging

* dev: add inbox issue webhooks

* dev: update the webhook send task

* dev: project webhooks for api

* dev: webhooks update for projects, cycles and modules

* dev: fix webhook on cycle and module create from external apis
2024-05-06 14:13:49 +05:30
Aaryan KhandelwalandGitHub fb74875cde [WEB-1181] chore: added a loader for page description (#4358)
* chore: add loader for page description

* chore: added skeleton loader

* fix: title loader margin

* chore: increased laoder width
2024-05-03 23:12:44 +05:30
sriram veeraghantaandGitHub da957e06b6 Merge pull request #4349 from makeplane/preview
release: v0.19-dev
2024-05-03 20:36:07 +05:30
c96225c812 [WEB-1183] fix: updated global issues filter while updating global view (#4357)
* chore: Updated global issues filter while updating global view

* fix: globale view modal clear all

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
2024-05-03 20:29:11 +05:30
Aaryan KhandelwalandGitHub 527ecd7d22 style: make edito height according to the content height (#4347) 2024-05-03 19:20:13 +05:30
rahulrameshaandGitHub acd8f8d2d6 [WEB-1173] fix: order by for last updated when issue is updated (#4353)
* update the issue's updated at date when issue is updated

* sort issue's updated and created at regardless of the date format.

* move the logic to date time helpers

* revert back the third variable in update issue
2024-05-03 19:08:20 +05:30
Anmol Singh BhatiaandGitHub f4cc103238 [WEB-1175] fix: modal context (#4352)
* fix: modal context

* chore: code refactor
2024-05-03 17:58:15 +05:30
Aaryan KhandelwalandGitHub 89f2f87b97 fix: decrease gantt full size z-index (#4354) 2024-05-03 17:38:21 +05:30
sriram veeraghanta eed047bfe3 chore: update version 2024-05-03 17:23:12 +05:30
Aaryan KhandelwalandGitHub 8cf4260219 fix: dropdowns should close on tab key (#4351) 2024-05-03 15:39:14 +05:30
rahulrameshaandGitHub 1b55411919 [WEB-1136] chore: Kanban drag and drop improvements (#4350)
* Kanban DnD improvement

* minor fixes for kanban dnd improvement

* change scroll duration

* fix feedback on the UX

* add highlight before drop

* add toast message explain drag and drop is currently disabled

* Change warning dnd message

* add comments

* fix minor build error
2024-05-03 15:12:06 +05:30
NikhilandGitHub dc5edca34d chore: update the default name that is added to instance (#4348) 2024-05-03 14:35:36 +05:30
Anmol Singh BhatiaandGitHub 2884b0e22e fix: inbox issue header quick action validation (#4344) 2024-05-03 14:17:21 +05:30
Aaryan KhandelwalandGitHub 091fdb89ac chore: hide display properties in the calendar layout (#4346) 2024-05-03 14:16:27 +05:30
Anmol Singh BhatiaandGitHub a678844073 [WEB-859] [WEB-1162] chore: issue detail improvement and assignees filter fix (#4342)
* chore: created by option added to inbox issue detail section

* chore: issue detail page improvement

* fix: inbox assignee filter key
2024-05-02 20:39:43 +05:30
Bavisetti NarayanandGitHub 4cb5c4d9df chore: workspace module list endpoint (#4343) 2024-05-02 19:18:41 +05:30
Aaryan KhandelwalandGitHub 45c9dfb3cf chore: update useCallback dependencies (#4341) 2024-05-02 19:18:08 +05:30
M. PalanikannanandGitHub 4c78cd7c7e fix: inbox create issue comment fixed (#4340) 2024-05-02 18:22:00 +05:30
Aaryan KhandelwalandGitHub c4229c9d55 fix: quick actions dropdown disabled state (#4335) 2024-05-02 16:13:58 +05:30
Aaryan KhandelwalandGitHub 42c4c46939 [WEB-1154] fix: delete attachment modal logic (#4338)
* fix: delete attachment modal logic

* chore: remove console log

* chore: update delete attachment button type
2024-05-02 16:13:04 +05:30
Anmol Singh BhatiaandGitHub 6918393b63 fix: existing issue list modal loading flicker (#4337) 2024-05-02 16:11:38 +05:30
Aaryan KhandelwalandGitHub 6196c750f1 fix: issue description persistence (#4331) 2024-05-01 19:55:37 +05:30
Anmol Singh BhatiaandGitHub ed6dd37043 fix: module sub-header empty state validation (#4329) 2024-05-01 18:36:11 +05:30
efa3eda85e [WEB-1145] chore: updated sub issue count in cycles, modules and project (#4328)
* chore: total issue count

* chore: removed the migration file

* fix: issue count

---------

Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
2024-05-01 18:24:54 +05:30
Aaryan KhandelwalandGitHub eb0877a3c8 [WEB-1135] chore: store page full width information in local storage (#4327)
* chore: store page full width information in local storage

* chore: update page types
2024-05-01 18:10:39 +05:30
Aaryan KhandelwalandGitHub 73fd6e641c chore: show display name character in avatar (#4326) 2024-05-01 18:05:24 +05:30
Aaryan KhandelwalandGitHub 34dd19cb00 chore: default pages sorting order (#4325) 2024-05-01 18:04:41 +05:30
Anmol Singh BhatiaandGitHub ecc277c571 [WEB-1101] chore: workspace view quick action enhancement (#4324)
* chore: workspace view quick action enhancement

* fix: issue quick action height
2024-05-01 18:03:13 +05:30
Bavisetti NarayanandGitHub d69f025b9a [WEB-1132] fix: display datetime fields in user time zone format (#4323)
* fix: user timezone response

* chore: removed unused variables
2024-05-01 18:01:53 +05:30
Aaryan KhandelwalandGitHub ed4a0518fc [WEB-1119] style: editor typography, borders and alignment throughout the platform (#4322)
* chore: new font sizes

* chore: update space app editor border

* chore: issue detials page x-padding

* chore: editor width
2024-05-01 18:01:30 +05:30
rahulrameshaandGitHub 2e2747c1f9 fix kanban collapsed vertical writing mode in firefox (#4320) 2024-05-01 12:21:26 +05:30
Daniel Albaandsriram veeraghanta aa09ec7cd4 feat(dashboard): improve label readability (#4321)
change none label for all time in dashbard filters
2024-05-01 00:10:52 +05:30
Anmol Singh BhatiaandGitHub 037ddd8bdb fix: project view application error (#4319) 2024-04-30 20:14:35 +05:30
Anmol Singh BhatiaandGitHub d1978be778 [WEB-1100] fix: bug fixes and enhancement (#4318)
* fix: inbox issue description

* chore: outline heading removed from page toc

* chore: label setting page ui improvement

* fix: update issue modal description resetting

* chore: project page head title improvement
2024-04-30 19:39:50 +05:30
Aaryan KhandelwalandGitHub d2717a221c [WEB-1110] dev: custom context menu for issues, cycles, modules, views, pages and projects (#4267)
* dev: context menu

* chore: handle menu position on close

* chore: project quick actions

* chore: add more options to the project context menu

* chore: cycle item context menu

* refactor: context menu folder structure

* chore: module custom context menu

* chore: view custom context menu

* chore: issues custom context menu

* chore: reorder options

* chore: issues custom context menu

* chore: render the context menu in a portal
2024-04-30 18:59:07 +05:30
sriram veeraghanta cb6ecc86cc fix: sync action variable names 2024-04-30 17:53:35 +05:30
sriram veeraghanta 6972a520ce chore: rename workflows 2024-04-30 17:30:35 +05:30
Aaryan KhandelwalandGitHub 4f4f1d92e8 fix: issue description placeholder (#4312) 2024-04-30 17:21:52 +05:30
Anmol Singh BhatiaandGitHub 87a606446f [WEB-1093] chore: padding and borders consistency (#4315)
* chore: global list layout and list item component added

* chore: project view list layout consistency

* chore: project view sub header consistency

* chore: pages list layout consistency

* chore: project view sub header improvement

* chore: list layout item component improvement

* chore: module list layout consistency

* chore: cycle list layout consistency

* chore: issue list layout consistency

* chore: header height consistency

* chore: sub header consistency

* chore: list layout improvement

* chore: inbox sidebar improvement

* fix: cycle quick action

* chore: inbox selected issue improvement

* chore: label option removed from pages filter

* chore: inbox create issue modal improvement
2024-04-30 17:21:24 +05:30
Aaryan KhandelwalandGitHub 1b79517f07 [WEB-1111] chore: added a helper function to check if issue is peeked (#4305)
* chore: added a helper function to check if issue is peeked

* chore: make the kanban block observer

* chore: rename isIssuePeekd helper function
2024-04-30 17:20:02 +05:30
e5681534d7 [WEB-1065] chore: workspace view and empty filter improvement (#4308)
* chore: workspace view layout improvement

* fix: empty applied filters

* chore: code refactor

* chore: code refactor

* fix: build errors

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-04-29 19:45:06 +05:30
Anmol Singh BhatiaandGitHub 03065d2c1d [WEB-1094] chore: inbox sidebar mobile responsiveness (#4309)
* chore: inbox sidebar mobile responsiveness

* chore: code refactor
2024-04-29 19:38:46 +05:30
Anmol Singh BhatiaandGitHub 5d3c64752c fix: switch toggle ui (#4311) 2024-04-29 18:59:05 +05:30
Anmol Singh BhatiaandGitHub 4104f87d41 fix: view, api token and estimate modal description height (#4310) 2024-04-29 18:58:31 +05:30
sriram veeraghanta 32d14d7000 fix: auto merge workflow fixes 2024-04-29 18:50:44 +05:30
sriram veeraghanta 1c4ca42603 fix: auto merge workflow fixes 2024-04-29 18:46:50 +05:30
sriram veeraghanta 3077cc410e Merge branch 'preview' of github.com:makeplane/plane into preview 2024-04-29 18:33:29 +05:30
sriram veeraghanta 392075a9eb fix: workflow fixes 2024-04-29 18:33:09 +05:30
Anmol Singh BhatiaandGitHub c252650c9a chore: project pages order by option improvement (#4307) 2024-04-29 18:24:58 +05:30
sriram veeraghanta 16b43c7b02 fix: pr check validation in workflow 2024-04-29 16:58:54 +05:30
sriram veeraghanta 354c3d95ce Merge branch 'preview' of github.com:makeplane/plane into preview 2024-04-29 16:48:04 +05:30
sriram veeraghanta 9739aa574d chore: remove comments from workflows 2024-04-29 16:47:49 +05:30
Bhavya GogriandGitHub a6b0a7fa8e make redis version same as the one in selfhosted docker-compose (#4183) 2024-04-29 16:42:25 +05:30
sriram veeraghanta 7fdaa64b90 fix: workflow fixes 2024-04-29 16:17:22 +05:30
sriram veeraghanta 6072c8b550 fix: revert the auto merge workflow changes 2024-04-29 16:13:52 +05:30
Aaryan KhandelwalandGitHub 84fd1dca4b [WEB-436] chore: added h4 to h6 heading options (#4304)
* chore: added h4 to h6 heading options

* fix: build errors
2024-04-29 16:04:37 +05:30
sriram veeraghanta 49a6c9582c fix: autommerge fixes 2024-04-29 14:09:36 +05:30
sriram veeraghanta 245a0e92ee fix: automerge workflow 2024-04-29 13:43:16 +05:30
709d3a115b [WEB-711] style: profile and its settings pages responsiveness (#4022)
* [WEB-711] style: profile and its settings pages responsiveness

* chore: linting issues fix

* fix: mobile-view padding

---------

Co-authored-by: LAKHAN BAHETI <lakhanbaheti9@gmail.com>
2024-04-29 12:59:49 +05:30
9c8b4afc20 [WEB-808] style: workspace settings mobile responsiveness (#4047)
* [WEB-808] style: workspace settings mobile responsiveness

* fix: scroll on mobile-view

* responsiveness fixes

---------

Co-authored-by: LAKHAN BAHETI <lakhanbaheti9@gmail.com>
2024-04-29 12:59:04 +05:30
Lakhan BahetiandGitHub 0c880bbbc8 [WEB-704] fix: inbox responsiveness (#4275)
* chore: inbox responsiveness

* fix: sidebar in full view

* style: border theme

* condition update
2024-04-29 00:54:35 +05:30
Ramesh Kumar ChandraandGitHub ea436c925a projects list responsiveness (#4279) 2024-04-29 00:54:02 +05:30
Lakhan BahetiandGitHub 4bccbc9804 pages responsiveness (#4287) 2024-04-29 00:52:43 +05:30
Aaryan KhandelwalandGitHub ac4bb1c1b4 refactor: remove unused icon files (#4297)
* refactor: remove unused icon files

* refactor: attachment icons folder structure
2024-04-29 00:51:31 +05:30
Aaryan KhandelwalandGitHub 0e3d5cc4eb fix: incomplete cycle issues auth (#4299) 2024-04-29 00:50:15 +05:30
rahulrameshaandGitHub 6ac3cb9b31 [WEB-1073] fix: Kanban dnd to work as tested on Chrome, Safari and Firefox (#4301)
* fix Kanban dnd to work as tested on Chrome Safari and Firefox

* fix edge cases

* revert back unintentional change
2024-04-29 00:48:50 +05:30
Aaryan KhandelwalandGitHub e75947a5f4 fix: double slashes in the global issues layout routes (#4298) 2024-04-26 18:32:20 +05:30
Anmol Singh BhatiaandGitHub e4777157a2 fix: project active cycle progress (#4296) 2024-04-26 18:30:38 +05:30
Anmol Singh BhatiaandGitHub 0605b5f60c chore: show sub-issue option added in profile display filter (#4295) 2024-04-26 18:30:02 +05:30
Aaryan KhandelwalandGitHub ad27184a91 [WEB-1072] fix: pages UI improvements (#4294)
* fix: outline alignment

* fix: textarea auto-resize logic
2024-04-26 18:29:18 +05:30
Aaryan KhandelwalandGitHub f87bb95236 chore: clear search term on escape key (#4289) 2024-04-26 18:27:32 +05:30
Anmol Singh BhatiaandGitHub f2fa6452c9 fix: cycle and module quick action z-index (#4293) 2024-04-26 14:56:51 +05:30
Anmol Singh BhatiaandGitHub 80461e6484 chore: filter member option sorting improvement (#4285) 2024-04-26 13:21:08 +05:30
Anmol Singh BhatiaandGitHub 88165a8fdb chore: module and cycle sidebar stats item filter implementation (#4286) 2024-04-26 12:58:27 +05:30
Anmol Singh BhatiaandGitHub 42cceb5e65 fix: filter state option order (#4284) 2024-04-26 12:57:36 +05:30
Anmol Singh BhatiaandGitHub 15c7deb2db fix: existing and parent issue modal empty state flicker (#4281) 2024-04-24 20:48:44 +05:30
Anmol Singh BhatiaandGitHub e60ef36bfe fix: module and cycle event propagation (#4280) 2024-04-24 20:20:41 +05:30
sriram veeraghanta bc2c97b9c3 Merge branch 'develop' of github.com:makeplane/plane into develop 2024-04-24 17:43:02 +05:30
Michael ErmerandGitHub 7f99b9a554 feat(api/issuesBySequenceId): add api to retrieve issue based on its sequence identitifier (#4170) 2024-04-24 17:42:12 +05:30
Aaryan KhandelwalandGitHub b74a0ea4d3 fix: list layout block border color (#4278) 2024-04-24 17:33:12 +05:30
sriram veeraghanta d9f11733ad Merge branches 'preview' and 'develop' of github.com:makeplane/plane into preview 2024-04-24 17:24:07 +05:30
Anmol Singh BhatiaandGitHub 87aab74579 chore: delete label modal content updated (#4276) 2024-04-24 17:21:52 +05:30
Bavisetti NarayanandGitHub d5dd971fb4 chore: state triage filter (#4277) 2024-04-24 16:28:35 +05:30
Anmol Singh BhatiaandGitHub 1789b8ddeb fix: observer added to empty state component (#4274) 2024-04-24 16:27:01 +05:30
sriram veeraghanta 1caa109c16 fix: update actions ubuntu version 2024-04-24 15:32:56 +05:30
Lakhan BahetiandGitHub b711fedb65 [WEB-1046] fix: user activity overflow & repsonsiveness (#4262)
* fix: activity responsiveness

* fix: activity icon placement

* fix: build
2024-04-24 15:20:32 +05:30
Anmol Singh BhatiaandGitHub deaa63488b chore: project date filter updated (#4273) 2024-04-24 15:18:13 +05:30
Anmol Singh BhatiaandGitHub 87737dbfbe chore: input character limit error message improvement (#4271) 2024-04-24 15:17:50 +05:30
Anmol Singh BhatiaandGitHub fc1cffd524 chore: active cycle stats improvement (#4268) 2024-04-24 15:17:04 +05:30
Anmol Singh BhatiaandGitHub 6e574515e0 fix: module delete modal outside click event propagation (#4265) 2024-04-24 15:16:47 +05:30
Anmol Singh BhatiaandGitHub d87edede79 chore: created by added in issue sidebar and peek overview (#4264) 2024-04-24 15:16:30 +05:30
Anmol Singh BhatiaandGitHub 196724214b chore: applied filter responsiveness (#4263) 2024-04-24 15:16:00 +05:30
Anmol Singh BhatiaandGitHub 695892d66e chore: issue filter member options improvement (#4261) 2024-04-24 15:15:10 +05:30
Anmol Singh BhatiaandGitHub a4e5138d1c [WEB-1047] chore: create page modal improvement (#4266)
* chore: create page modal improvement

* chore: create page modal improvement
2024-04-23 19:59:34 +05:30
NikhilandGitHub f174a96ef2 dev: update python runtime (#4259) 2024-04-23 13:42:48 +05:30
sriram veeraghanta 5e53279734 Merge branch 'develop' of github.com:makeplane/plane into preview 2024-04-23 13:27:49 +05:30
Anmol Singh BhatiaandGitHub bf852739cd fix: preserve initial value on create more issues (#4258) 2024-04-23 13:25:27 +05:30
Anmol Singh BhatiaandGitHub f17e4c73a2 [WEB-1015] fix: kanban layout cycle and module quick add (#4252)
* fix: kanban layout cycle and module quick add

* fix: kanban layout cycle and module quick add
2024-04-23 13:07:20 +05:30
Bavisetti NarayanandGitHub aee48f6fa4 [WEB-1042] fix: dashboard collaborators active issue count (#4256)
* chore: recent collaborators based on workspace

* chore: removed the duplicate issue
2024-04-23 13:04:14 +05:30
Anmol Singh BhatiaandGitHub f7d6219bd1 [WEB-1038] fix: kanban layout drag permission validation (#4255)
* fix: kanban layout drag permission validation

* chore: code refactor
2024-04-23 13:03:30 +05:30
NikhilandGitHub 75d14ce1ef fix: workspace redirection when logging in (#4254) 2024-04-23 13:02:48 +05:30
Anmol Singh BhatiaandGitHub 9659da5b31 [WEB-1034] fix: inbox issue user activity (#4251)
* fix: inbox issue user activity

* chore: code refactor

* fix: sentry issue
2024-04-23 13:01:26 +05:30
Anmol Singh BhatiaandGitHub 51ade1295c fix: comment text editor user mention validation addded (#4250) 2024-04-23 13:00:58 +05:30
Anmol Singh BhatiaandGitHub ac3def2929 fix: calendar header action alignment (#4249) 2024-04-23 12:59:48 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
098a1950c7 chore(deps): bump gunicorn in /apiserver/requirements (#4247)
Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 21.2.0 to 22.0.0.
- [Release notes](https://github.com/benoitc/gunicorn/releases)
- [Commits](https://github.com/benoitc/gunicorn/compare/21.2.0...22.0.0)

---
updated-dependencies:
- dependency-name: gunicorn
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 12:58:28 +05:30
03fd5feda6 [WEB-1035] fix: peek module auto closing (#4246)
* fix: peek module auto closing

* chore: code refactor

* chore: code refactor

* chore: code refactor

* chore: archived at in module

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-04-23 12:58:01 +05:30
Anmol Singh BhatiaandGitHub 270f7c4503 fix: sign in redirection flicker (#4245) 2024-04-23 12:57:10 +05:30
Anmol Singh BhatiaandGitHub beff8536c9 fix: filter custom date select toggle (#4244) 2024-04-23 12:56:21 +05:30
Anmol Singh BhatiaandGitHub 5d8c5b22e8 chore: kanban layout sub-group ui revamp & sub-group icon fix (#4243) 2024-04-23 12:55:42 +05:30
Anmol Singh BhatiaandGitHub 60663821df chore: list layout issue block improvement (#4241) 2024-04-23 12:55:19 +05:30
Prateek ShouryaandGitHub 302da646a8 [WEB-857] chore: update issue priority text color for custom theme in spreadsheet layout. (#4235) 2024-04-23 12:54:19 +05:30
Anmol Singh BhatiaandGitHub e0e8ce633b [WEB-1027] fix: overflow & alignment fixes (#4234)
* fix: list layout issue title overflow

* fix: project feature toggle modal project name overflow

* fix: app sidebar project section alignment

* fix: issue title textarea

* fix: create issue modal project select overflow

* fix: module and cycle applied filters overflow fix
2024-04-23 12:53:52 +05:30
Prateek ShouryaandGitHub f77d2d8c0a [WEB-643] chore: update issue activity tabs. (#4232)
* remove `updates` tab.
* make `comments` as primary tab.
2024-04-23 12:52:31 +05:30
Prateek ShouryaandGitHub c50a0602f7 [WEB-871] chore: update leave project modal message in members settings page. (#4230)
* [WEB-871] chore: update leave project modal message in members settings page.

* fix: build errors.
2024-04-23 12:51:20 +05:30
Prateek ShouryaandGitHub 38daf72361 [WEB-872] chore: add tooltip to peek overview header icons. (#4229) 2024-04-23 12:49:29 +05:30
sriram veeraghantaandGitHub a0b9596cb4 Merge pull request #4239 from makeplane/preview
chore:version update
2024-04-19 12:01:15 +05:30
sriram veeraghanta c1e5c0d4eb chore:version update 2024-04-19 11:59:30 +05:30
sriram veeraghantaandGitHub f71e8a3a0f Merge pull request #4238 from makeplane/preview
release: v0.18-dev
2024-04-19 11:56:03 +05:30
Prateek ShouryaandGitHub 086d14609c [WEB-1028] fix: enable comments and issue reactions for guest/ viewer. (#4231) 2024-04-18 20:36:24 +05:30
NikhilandGitHub cb9fda8557 fix: caching login when member joins a workspace from the email (#4237) 2024-04-18 20:34:59 +05:30
sriram veeraghanta 7da2cb143f Merge branch 'preview' of github.com:makeplane/plane into develop 2024-04-17 20:33:18 +05:30
Aaryan KhandelwalandGitHub 0d70960e4e [WEB-1026] chore: clear search query on project change (#4225)
* chore: clear search query on project change

* fix: project query search
2024-04-17 20:32:25 +05:30
Anmol Singh BhatiaandGitHub 0c0bdd6969 [WEB-999] fix: inbox sentry error and accept modal fix (#4226)
* fix: inbox issue parent id sentry error

* fix: inbox issue accept parent id fix
2024-04-17 20:31:47 +05:30
Anmol Singh BhatiaandGitHub cdc73cedab chore: sign in page improvement (#4224) 2024-04-17 19:46:35 +05:30
bf9049a7a2 [WEB-987] fix: inbox issue activity (#4208)
* chore: inbox issue activity

* chore: dummy data script

* chore: inbox issue activity implementation

---------

Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
2024-04-17 19:43:22 +05:30
Aaryan KhandelwalandGitHub f0cb48006f [WEB-1024] fix: textarea component auto-resize (#4221)
* chore: updated resize hook logic

* fix: page title overflow issue

* chore: add length validation to page title
2024-04-17 19:41:34 +05:30
rahulrameshaandGitHub 10ed12e589 [WEB-1005] chore: pragmatic drag n drop implementation for labels (#4223)
* pragmatic drag n drop implementation for labels

* minor code quality improvements
2024-04-17 18:20:02 +05:30
Bavisetti NarayanandGitHub 68c870b791 [WEB-1023] chore: page mention transactions (#4222)
* chore: null validation for old value in pages

* chore: page transaction activity

* chore: serialized description_html
2024-04-17 18:18:14 +05:30
Anmol Singh BhatiaandGitHub 8e764004f0 fix: draft issue parent select query params (#4218) 2024-04-17 14:53:24 +05:30
1880eb7704 [WEB-1019] chore: error state for unauthorized pages (#4219)
* chore: private page access

* chore: add error state for private pages

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-04-17 14:53:01 +05:30
M. PalanikannanandGitHub 1080094b01 fix: tab key behaviour fixed for tabIndex containing editors with lists' and code blocks' tab key (#4216) 2024-04-16 21:48:30 +05:30
Anmol Singh BhatiaandGitHub d307c727ea fix: profile activity application error (#4214) 2024-04-16 20:35:37 +05:30
M. PalanikannanandGitHub ec5667194f fix: unnecessary focus in editor on swr sync (#4215) 2024-04-16 20:35:10 +05:30
Anmol Singh BhatiaandGitHub 1549f3a808 chore: calendar layout quick add menu placement improvement (#4213) 2024-04-16 20:24:13 +05:30
sriram veeraghanta 0705d2559b fix: issue template version from text area to input 2024-04-16 18:58:05 +05:30
sriram veeraghanta a36836abd7 fix: issue template update 2024-04-16 18:55:51 +05:30
27db8699c8 [WEB-480] fix: code block paste from VSCode and indentation (#4198)
* fix: stroing the transactions in page

* fix: page details changes

* chore: page response change

* chore: removed duplicated endpoints

* chore: optimised the urls

* chore: removed archived and favorite pages

* chore: revamping pages store and components

* mentions loading state part done

* fixed mentions not showing in modals

* removed comments and cleaned up types

* removed unused types

* reset: head

* chore: pages store and component updates

* style: pages list item UI

* fix: improved colors and drag handle width

* fix: slash commands are no more shown in the code blocks

* fix: cleanup/hide drag handles post drop

* fix: hide/cleanup drag handles post drag start

* fix: aligning the drag handles better with the node post css changes of the length

* fix: juggling back and forth of drag handles in ordered and unordered lists

* chore: fix imports, ts errors and other things

* fix: clearing nodes to default node i.e paragraph before converting it to other types of nodes

For more reference on what this does, please refer https://tiptap.dev/docs/editor/api/commands/clear-nodes

* chore: clearNodes after delete in case of selections being present

* fix: hiding link selector in the bubble menu if inline code block is selected

* chore: filtering, ordering and searching implemented

* chore: updated pages store and updated UI

* chore: new core editor just for document editor created

* chore: removed setIsSubmitting prop in doc editor

* fix: fixed submitting state for image uploads

* refactor: setShouldShowAlert removed

* refactor: rerenderOnPropsChange prop removed

* chore: type inference magic in ref to expose an api for controlling editor menu items from outside

* fix: naming imports

* chore: change names of the exposed functions and removing old types

* refactor: remove debouncedUpdatesEnabled prop;

* refactor: editor heading markings now parsed using html

* chore: removed unrelated components from the document editor

* refactor: page details granular components

* fix: remove onActionCompleteHandler

* refactor: removed rerenderOnProps change prop

* feat: added getMarkDown function

* chore: update dropdown option actions

* fix: sidebar markings update logic

* chore: add image and to-do list actions to the toolbar

* fix: handling refs and populating them via callbacks

* feat: scroll to node api exposed

* cleaning up editor refs when the editor is destroyed

* feat: scrolling added to read only instance of the editor

* fix: markings logic

* fix: build errors with types

* fix: build erros

* fix: subscribing to transactions of editor via ref

* chore: remove debug statements

* fix: type errors

* fix: temporary different slash commands for document editor

* chore: inline code extension style

* chore: remove border from readOnly editor

* fix: editor bottom padding

* chore: pages improvements

* chore: handle Enter key on the page title

* feat: added loading indicator logic in mentions

* fix: mentions and slash commands now work well with multiple editors in one place

* refactor: page store structure, filtering logic

* feat: added better seperation in inline code blocks

* feat: list autojoining added

* fix: pages folder structure

* fix: image refocus from external parts

* working lists somewhat

* chore: implement page reactions

* fix: build errors

* fix: build errors

* fixed drag handles stuff

* task list item fixed

* working

* fix: working on multiple nested lists

* chore: remove debug statements

* fix: Tab key on first list item handled to not go out of editor focus

* feat: threshold auto scroll support added and multi nested list selection fixed

* fix: caret color bug with improved inline code blocks

* fix: node range error when bulk deleting with list

* fix: removed slash commands from working in code blocks

* chore: update typography margins

* chore: new field added in page model

* fix: better type inference in slash commands

* chore: code block UI

* feat: image insertion at correct position using ref added

* feat: added improved mentions support for space

* fix: type errors in mentions for comments in web app

* sync: core with document-core

* fix: build errors

* fix: fallback for appendTo not being able to find active container instantly

* fix: page store

* fix: page description

* fix: css quality issues

* chore: code cleanup

* chore: removed placeholder text in codeblocks

* chore: archived pages response change

* chore: archived pages response change

* fix: initial pages list fetch

* fix: pages list filters and ordering

* chore: add access change option in the quick actions dropdown

* fix: inline code block caret fixed

* regression: removing extra text

* chore: caret color removed

* feat: copy code button added in code blocks

* fix: initial load of page details

* fix: initial load of page details

* fix: image resizing weird behavior on click/expanding it too much fixed now

* chore: copy page response

* fix: todo list spacing

* chore: description html in the copy page

* chore: handle latest description on refetch

* fix: saner scroll behaviours

* fix: block menu positioning

* fix: updated empty string description

* feat: tab change sync support added

* fix: infinite rerendering with markings

* fix: block menu finally

* fix: intial load on reload bug fixed

* fix: nested lists alignment

* fix: editor padding

* fix: first level list items copyable

* chore: list spacing

* fix: title change

* fix: pages list block items interaction

* fix: saving chip position

* fix: delete action from block menu to focus properly

* fix: margin-bottom as 0 to avoid weird spacing when a paragraph node follows a list node

* style: table, chore: lite text editor toolbar

* fix: page description tab sync

* fix: lists spacing and alignment

* refactor: document editor props

* feat: rich text editor wrapper created and migrated core

* feat: created wrapper around lite text editor and merged core

* chore: add lite text editor toolbar

* fix: build errors

* fix: type errors and addead live updation of toolbar

* chore: pages migration

* fix: inbox issue

* refactor: remove redundant package

* refactor: unused files

* fix: add dompurify to space app

* fix: inline code margin

* fix: editor className props

* fix: build errors

* fix: traversing up the tree before assuming the parent is not a list item

* fix: drag handle positions for list items fixed

* fix: removed focus at end logic after deleting block

* fix: image wrapper overflow scroll fix with block menu's position

* fix: selection and deletion logic for nested lists fixed!!

* fix: hiding the block menu while scrolling in the document/app

* fix: merge conflicts resolved from develop

* fix: inbox issue description

* chore: move page title to the web app

* fix: handling edge cases for table selection

* chore: lint issues

* refactor: list item functions moved to same file

* refactor: use mention hook

* fix: added try catch blocks for mention suggestions

* chore: remove unused code

* fix: remove console logs

* fix: remove console logs

* fix: code block paste handler

* fix: tracking image uploading status to prevent sync rerenders

* chore: remove unnecessary props

* fix: code block pasting logic from vs code handled properly

* feat: additional checks for doc bounds

* fix: type of cancel button changed to button instead of default submit

* feat: editor focus on saved position while syncing via swr

* fix: type errors

* fix: changing names of plugins and removing packages

* fix: readonly editor synced

* removed console logs

* fix: stringifying instead of dom injection

* fix: use-editor try catch error handling

* fix: editor container click in try catch

* fix: some more error handling

* chore: removed commented out code

* fix: backspace error handling

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
2024-04-16 18:50:45 +05:30
Anmol Singh BhatiaandGitHub 59772be014 fix: issue comment validation (#4211) 2024-04-16 18:50:26 +05:30
Anmol Singh BhatiaandGitHub 2ab4d99c15 chore: issue kanban cursor improvement (#4212) 2024-04-16 18:49:46 +05:30
Bavisetti NarayanandGitHub 50825b574b chore: instance admin script (#4210) 2024-04-16 18:06:46 +05:30
rahulrameshaandGitHub e952d88905 fix spreadsheet labels dropdown keyboard navigation (#4209) 2024-04-16 18:06:02 +05:30
sriram veeraghanta 247720b0d4 Merge branch 'develop' of github.com:makeplane/plane into develop 2024-04-16 16:41:29 +05:30
sriram veeraghanta dce3f4bce8 fix: upgrading turbo 2024-04-16 16:41:15 +05:30
c18265c7cf [WEB-480] fix: image uploading with swr sync fixed for pages (#4187)
* fix: stroing the transactions in page

* fix: page details changes

* chore: page response change

* chore: removed duplicated endpoints

* chore: optimised the urls

* chore: removed archived and favorite pages

* chore: revamping pages store and components

* mentions loading state part done

* fixed mentions not showing in modals

* removed comments and cleaned up types

* removed unused types

* reset: head

* chore: pages store and component updates

* style: pages list item UI

* fix: improved colors and drag handle width

* fix: slash commands are no more shown in the code blocks

* fix: cleanup/hide drag handles post drop

* fix: hide/cleanup drag handles post drag start

* fix: aligning the drag handles better with the node post css changes of the length

* fix: juggling back and forth of drag handles in ordered and unordered lists

* chore: fix imports, ts errors and other things

* fix: clearing nodes to default node i.e paragraph before converting it to other types of nodes

For more reference on what this does, please refer https://tiptap.dev/docs/editor/api/commands/clear-nodes

* chore: clearNodes after delete in case of selections being present

* fix: hiding link selector in the bubble menu if inline code block is selected

* chore: filtering, ordering and searching implemented

* chore: updated pages store and updated UI

* chore: new core editor just for document editor created

* chore: removed setIsSubmitting prop in doc editor

* fix: fixed submitting state for image uploads

* refactor: setShouldShowAlert removed

* refactor: rerenderOnPropsChange prop removed

* chore: type inference magic in ref to expose an api for controlling editor menu items from outside

* fix: naming imports

* chore: change names of the exposed functions and removing old types

* refactor: remove debouncedUpdatesEnabled prop;

* refactor: editor heading markings now parsed using html

* chore: removed unrelated components from the document editor

* refactor: page details granular components

* fix: remove onActionCompleteHandler

* refactor: removed rerenderOnProps change prop

* feat: added getMarkDown function

* chore: update dropdown option actions

* fix: sidebar markings update logic

* chore: add image and to-do list actions to the toolbar

* fix: handling refs and populating them via callbacks

* feat: scroll to node api exposed

* cleaning up editor refs when the editor is destroyed

* feat: scrolling added to read only instance of the editor

* fix: markings logic

* fix: build errors with types

* fix: build erros

* fix: subscribing to transactions of editor via ref

* chore: remove debug statements

* fix: type errors

* fix: temporary different slash commands for document editor

* chore: inline code extension style

* chore: remove border from readOnly editor

* fix: editor bottom padding

* chore: pages improvements

* chore: handle Enter key on the page title

* feat: added loading indicator logic in mentions

* fix: mentions and slash commands now work well with multiple editors in one place

* refactor: page store structure, filtering logic

* feat: added better seperation in inline code blocks

* feat: list autojoining added

* fix: pages folder structure

* fix: image refocus from external parts

* working lists somewhat

* chore: implement page reactions

* fix: build errors

* fix: build errors

* fixed drag handles stuff

* task list item fixed

* working

* fix: working on multiple nested lists

* chore: remove debug statements

* fix: Tab key on first list item handled to not go out of editor focus

* feat: threshold auto scroll support added and multi nested list selection fixed

* fix: caret color bug with improved inline code blocks

* fix: node range error when bulk deleting with list

* fix: removed slash commands from working in code blocks

* chore: update typography margins

* chore: new field added in page model

* fix: better type inference in slash commands

* chore: code block UI

* feat: image insertion at correct position using ref added

* feat: added improved mentions support for space

* fix: type errors in mentions for comments in web app

* sync: core with document-core

* fix: build errors

* fix: fallback for appendTo not being able to find active container instantly

* fix: page store

* fix: page description

* fix: css quality issues

* chore: code cleanup

* chore: removed placeholder text in codeblocks

* chore: archived pages response change

* chore: archived pages response change

* fix: initial pages list fetch

* fix: pages list filters and ordering

* chore: add access change option in the quick actions dropdown

* fix: inline code block caret fixed

* regression: removing extra text

* chore: caret color removed

* feat: copy code button added in code blocks

* fix: initial load of page details

* fix: initial load of page details

* fix: image resizing weird behavior on click/expanding it too much fixed now

* chore: copy page response

* fix: todo list spacing

* chore: description html in the copy page

* chore: handle latest description on refetch

* fix: saner scroll behaviours

* fix: block menu positioning

* fix: updated empty string description

* feat: tab change sync support added

* fix: infinite rerendering with markings

* fix: block menu finally

* fix: intial load on reload bug fixed

* fix: nested lists alignment

* fix: editor padding

* fix: first level list items copyable

* chore: list spacing

* fix: title change

* fix: pages list block items interaction

* fix: saving chip position

* fix: delete action from block menu to focus properly

* fix: margin-bottom as 0 to avoid weird spacing when a paragraph node follows a list node

* style: table, chore: lite text editor toolbar

* fix: page description tab sync

* fix: lists spacing and alignment

* refactor: document editor props

* feat: rich text editor wrapper created and migrated core

* feat: created wrapper around lite text editor and merged core

* chore: add lite text editor toolbar

* fix: build errors

* fix: type errors and addead live updation of toolbar

* chore: pages migration

* fix: inbox issue

* refactor: remove redundant package

* refactor: unused files

* fix: add dompurify to space app

* fix: inline code margin

* fix: editor className props

* fix: build errors

* fix: traversing up the tree before assuming the parent is not a list item

* fix: drag handle positions for list items fixed

* fix: removed focus at end logic after deleting block

* fix: image wrapper overflow scroll fix with block menu's position

* fix: selection and deletion logic for nested lists fixed!!

* fix: hiding the block menu while scrolling in the document/app

* fix: merge conflicts resolved from develop

* fix: inbox issue description

* chore: move page title to the web app

* fix: handling edge cases for table selection

* chore: lint issues

* refactor: list item functions moved to same file

* refactor: use mention hook

* fix: added try catch blocks for mention suggestions

* chore: remove unused code

* fix: remove console logs

* fix: remove console logs

* fix: tracking image uploading status to prevent sync rerenders

* chore: remove unnecessary props

* fix: type of cancel button changed to button instead of default submit

* feat: editor focus on saved position while syncing via swr

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
2024-04-16 15:52:31 +05:30
M. PalanikannanandGitHub 480aa906de [WEB - 480] fix: horizontal rule drag and drop (#4200)
* fix: horizontal rule parsing (with backwards compatibility) and ensuring correct selections

* fix: table drag handle position

* fix: code block drag handle positioning fixes

* fix: blockquote duplication, selection and deletion fixed

* fix: possible range errors and type errors
2024-04-16 15:51:05 +05:30
rahulrameshaandGitHub b9314889d7 fix empty blocks due to virtualization in rare cases (#4207) 2024-04-16 15:50:06 +05:30
sriram veeraghanta 01f7328714 Merge branch 'preview' of github.com:makeplane/plane into develop 2024-04-16 15:49:22 +05:30
rahulrameshaandGitHub 2311bd4f78 add a small min height for dropping issues incase tger are zero issues in the entire row of columns (#4206) 2024-04-16 15:48:32 +05:30
CoolCuandGitHub f729e46bb0 chore: fix some typos in comments (#4205)
Signed-off-by: CoolCu <coolcui@qq.com>
2024-04-16 15:48:11 +05:30
sriram veeraghanta 41d8005f0b Merge branch 'preview' of github.com:makeplane/plane into develop 2024-04-16 13:28:03 +05:30
17347013442andGitHub 320cb94e35 Update issue_details.ts (#4199)
You should implement the interface here, not yourself
2024-04-16 13:24:54 +05:30
Aaryan KhandelwalandGitHub 6eed2c202b chore: created a global mark as favorite component (#4203) 2024-04-16 13:23:50 +05:30
Anmol Singh BhatiaandGitHub 0a6d7713fb chore: issue comment empty state added (#4202) 2024-04-16 13:22:27 +05:30
Anmol Singh BhatiaandGitHub 18b573531f chore: member invite modal improvement (#4201) 2024-04-16 13:21:56 +05:30
sriram veeraghanta 963d078aba fix: codeql workflow update 2024-04-15 20:02:57 +05:30
Aaryan KhandelwalandGitHub abce0ed946 [WEB-735] chore: added a custom placeholder prop to all the editors (#4194)
* chore: added a custom placeholder prop to all the editors

* chore: inbox issue create modal placeholder
2024-04-15 20:00:02 +05:30
Anmol Singh BhatiaandGitHub 77b323f562 chore: cycle list page improvement (#4195) 2024-04-15 19:49:16 +05:30
Anmol Singh BhatiaandGitHub f4c528f535 chore: inbox issue attachment added (#4190) 2024-04-15 19:48:50 +05:30
NikhilandGitHub c670a31836 fix: remove caching when joining workspace (#4192) 2024-04-15 19:46:44 +05:30
54196aafc0 [WEB-989] chore: archived module and cycle sidebar details (#4191)
* chore: module and cycle archive

* fix: archived cycle sidebar details fetch

* fix: archived module sidebar details fetch

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-04-15 19:46:14 +05:30
7a4ee509da [WEB-999] chore: inbox issue bug fixes and improvement (#4188)
* chore: duplicate inbox issue header improvement

* chore: snooze inbox issue header action improvement

* fix: project inbox exception error

* chore: inbox issue modal improvement

* chore: code refactor

* chore: Updated the inbox issue mutation

---------

Co-authored-by: guru_sainath <gurusainath007@gmail.com>
2024-04-15 19:45:47 +05:30
Aaryan KhandelwalandGitHub 8454e4f1e0 [WEB-986] fix: editor slash command positioning (#4186)
* fix: table selected cell border

* chore: add syncing message when revalidating page data

* fix: slash command positioning

* fix: mentions list dropdown positioning
2024-04-15 19:45:03 +05:30
rahulrameshaandGitHub 7a21855ab6 [WEB-1004] feat: Pragmatic dnd implementation for Kanban (#4189)
* Pragmatic drag and drop implmentation of Kanban

* refactor pragmatic dnd implementation and fix bugs

* fix dnd for modules, cycles, draft and project views
2024-04-15 17:02:53 +05:30
sriram veeraghanta 384624a21b Merge branch 'develop' of github.com:makeplane/plane into preview 2024-04-15 12:54:06 +05:30
Aaryan KhandelwalandGitHub 7507cb0a0f [WEB-994] fix: pages list mutation between projects (#4179)
* fix: pages list mutation between projects

* fix: page tab logic

* chore: remove pageType from the project pages store

* chore: rename computed helper functions
2024-04-15 12:50:22 +05:30
Bavisetti NarayanandGitHub d58bc03db6 fix: pages and inbox issue in dummy data (#4177) 2024-04-15 12:49:58 +05:30
20b0edeaa6 [WEB-999] chore: updated UI improvements and workflow updates in the project inbox (#4180)
* chore: snoozed filter in the issue inbox filter

* chore: navigating to the next or previous issue when we accept, decline, or duplicate the issue in inbox

* chore: Implemented state, label, assignee and target_date in the inbox issue description and Implemented issue edit confirmation once we click accept the inbox issue

* chore: removed logs

* chore: inbox issue create response

* chore: update inbox issue response

* chore: updated inbox issue accept workflow and added issue properties in inbox issue create modal

* chore: resolved build errors and upgraded lucide react

* chore: updated inbox issue store hook

* chore: code cleanup and removed validation for inbox description

* fix: renamed the variable isLoading to loader in project-inbox store

* fix: updated set function for issue property update

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-04-15 12:49:14 +05:30
guru_sainathandGitHub a44a032683 [WEB-984] feat: integrated state filter in inbox issues filter (#4182)
* chore: added state filtering in the inbox filters

* chore: Clearing the issues when we apply filters
2024-04-15 12:48:43 +05:30
guru_sainathandGitHub 251a432d8a [WEB-1000] fix: handled edge case for color on custom analytics state_group (#4185)
* chore: handled edge case for color on custom analytics state_group

* fix: error handler
2024-04-13 22:18:34 +05:30
3e2355e223 [WEB-460] refactor: editors, chore: pages list improvement (#4090)
* fix: stroing the transactions in page

* fix: page details changes

* chore: page response change

* chore: removed duplicated endpoints

* chore: optimised the urls

* chore: removed archived and favorite pages

* chore: revamping pages store and components

* mentions loading state part done

* fixed mentions not showing in modals

* removed comments and cleaned up types

* removed unused types

* reset: head

* chore: pages store and component updates

* style: pages list item UI

* fix: improved colors and drag handle width

* fix: slash commands are no more shown in the code blocks

* fix: cleanup/hide drag handles post drop

* fix: hide/cleanup drag handles post drag start

* fix: aligning the drag handles better with the node post css changes of the length

* fix: juggling back and forth of drag handles in ordered and unordered lists

* chore: fix imports, ts errors and other things

* fix: clearing nodes to default node i.e paragraph before converting it to other types of nodes

For more reference on what this does, please refer https://tiptap.dev/docs/editor/api/commands/clear-nodes

* chore: clearNodes after delete in case of selections being present

* fix: hiding link selector in the bubble menu if inline code block is selected

* chore: filtering, ordering and searching implemented

* chore: updated pages store and updated UI

* chore: new core editor just for document editor created

* chore: removed setIsSubmitting prop in doc editor

* fix: fixed submitting state for image uploads

* refactor: setShouldShowAlert removed

* refactor: rerenderOnPropsChange prop removed

* chore: type inference magic in ref to expose an api for controlling editor menu items from outside

* fix: naming imports

* chore: change names of the exposed functions and removing old types

* refactor: remove debouncedUpdatesEnabled prop;

* refactor: editor heading markings now parsed using html

* chore: removed unrelated components from the document editor

* refactor: page details granular components

* fix: remove onActionCompleteHandler

* refactor: removed rerenderOnProps change prop

* feat: added getMarkDown function

* chore: update dropdown option actions

* fix: sidebar markings update logic

* chore: add image and to-do list actions to the toolbar

* fix: handling refs and populating them via callbacks

* feat: scroll to node api exposed

* cleaning up editor refs when the editor is destroyed

* feat: scrolling added to read only instance of the editor

* fix: markings logic

* fix: build errors with types

* fix: build erros

* fix: subscribing to transactions of editor via ref

* chore: remove debug statements

* fix: type errors

* fix: temporary different slash commands for document editor

* chore: inline code extension style

* chore: remove border from readOnly editor

* fix: editor bottom padding

* chore: pages improvements

* chore: handle Enter key on the page title

* feat: added loading indicator logic in mentions

* fix: mentions and slash commands now work well with multiple editors in one place

* refactor: page store structure, filtering logic

* feat: added better seperation in inline code blocks

* feat: list autojoining added

* fix: pages folder structure

* fix: image refocus from external parts

* working lists somewhat

* chore: implement page reactions

* fix: build errors

* fix: build errors

* fixed drag handles stuff

* task list item fixed

* working

* fix: working on multiple nested lists

* chore: remove debug statements

* fix: Tab key on first list item handled to not go out of editor focus

* feat: threshold auto scroll support added and multi nested list selection fixed

* fix: caret color bug with improved inline code blocks

* fix: node range error when bulk deleting with list

* fix: removed slash commands from working in code blocks

* chore: update typography margins

* chore: new field added in page model

* fix: better type inference in slash commands

* chore: code block UI

* feat: image insertion at correct position using ref added

* feat: added improved mentions support for space

* fix: type errors in mentions for comments in web app

* sync: core with document-core

* fix: build errors

* fix: fallback for appendTo not being able to find active container instantly

* fix: page store

* fix: page description

* fix: css quality issues

* chore: code cleanup

* chore: removed placeholder text in codeblocks

* chore: archived pages response change

* chore: archived pages response change

* fix: initial pages list fetch

* fix: pages list filters and ordering

* chore: add access change option in the quick actions dropdown

* fix: inline code block caret fixed

* regression: removing extra text

* chore: caret color removed

* feat: copy code button added in code blocks

* fix: initial load of page details

* fix: initial load of page details

* fix: image resizing weird behavior on click/expanding it too much fixed now

* chore: copy page response

* fix: todo list spacing

* chore: description html in the copy page

* chore: handle latest description on refetch

* fix: saner scroll behaviours

* fix: block menu positioning

* fix: updated empty string description

* feat: tab change sync support added

* fix: infinite rerendering with markings

* fix: block menu finally

* fix: intial load on reload bug fixed

* fix: nested lists alignment

* fix: editor padding

* fix: first level list items copyable

* chore: list spacing

* fix: title change

* fix: pages list block items interaction

* fix: saving chip position

* fix: delete action from block menu to focus properly

* fix: margin-bottom as 0 to avoid weird spacing when a paragraph node follows a list node

* style: table, chore: lite text editor toolbar

* fix: page description tab sync

* fix: lists spacing and alignment

* refactor: document editor props

* feat: rich text editor wrapper created and migrated core

* feat: created wrapper around lite text editor and merged core

* chore: add lite text editor toolbar

* fix: build errors

* fix: type errors and addead live updation of toolbar

* chore: pages migration

* fix: inbox issue

* refactor: remove redundant package

* refactor: unused files

* fix: add dompurify to space app

* fix: inline code margin

* fix: editor className props

* fix: build errors

* fix: traversing up the tree before assuming the parent is not a list item

* fix: drag handle positions for list items fixed

* fix: removed focus at end logic after deleting block

* fix: image wrapper overflow scroll fix with block menu's position

* fix: selection and deletion logic for nested lists fixed!!

* fix: hiding the block menu while scrolling in the document/app

* fix: merge conflicts resolved from develop

* fix: inbox issue description

* chore: move page title to the web app

* fix: handling edge cases for table selection

* chore: lint issues

* refactor: list item functions moved to same file

* refactor: use mention hook

* fix: added try catch blocks for mention suggestions

* chore: remove unused code

* fix: remove console logs

* fix: remove console logs

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Palanikannan1437 <73993394+Palanikannan1437@users.noreply.github.com>
2024-04-11 21:28:59 +05:30
sriram veeraghanta 8b6035d315 Merge branch 'preview' of github.com:makeplane/plane into develop 2024-04-11 20:27:44 +05:30
Bavisetti NarayanandGitHub b90ca97461 [WEB-983] chore: dummy data script (#4173)
* chore: dummy data script

* fix: lint issues

* chore: removed print statment
2024-04-11 20:27:05 +05:30
Anmol Singh BhatiaandGitHub b0ab17021f [WEB-943] chore: inbox cancelled issue header action improvement (#4172)
* chore: inbox cancelled issue header action improvement

* chore: code refactor
2024-04-11 20:26:23 +05:30
rahulrameshaandGitHub cd395fa3d2 [WEB-905] fix: make entire Kanban issue block clickable (#4175)
* make entire block clickable

* left align title tooltip on kanban block

* fix minor issue with kanban issue title

* disable click inside the quick actions
2024-04-11 20:21:03 +05:30
guru_sainathandGitHub 9e3fedd0df chore: Handled inbox issue sorting locally in inbox store (#4169) 2024-04-10 21:29:21 +05:30
Anmol Singh BhatiaandGitHub 5250c64be5 [WEB-937] fix: inbox issue hook render issue and code refactor (#4168)
* fix: inbox issue hook render issue and code refactor

* fix: inbox issue hook render issue and code refactor
2024-04-10 21:28:48 +05:30
Aaryan KhandelwalandGitHub 5c6170507e fix: drag handle position in the peek overview (#4167) 2024-04-10 21:28:06 +05:30
Anmol Singh BhatiaandGitHub 4f15c03f91 fix: api token expiry time (#4165) 2024-04-10 21:27:22 +05:30
Nico FrankeandGitHub 43534dcaed fix: email ssl setting not getting saved (#4161) 2024-04-10 20:01:22 +05:30
guru_sainathandGitHub cfbc1a91af chore: optimised issue loaders and added enum for issue status and current tab (#4164) 2024-04-10 19:55:16 +05:30
Anmol Singh BhatiaandGitHub 7aa1d750ea chore: issue comment mention user improvement (#4163) 2024-04-10 19:52:10 +05:30
Anmol Singh BhatiaandGitHub 91ed27837e chore: kanban card padding improvement (#4162) 2024-04-10 19:51:13 +05:30
f45c2d12fd [WEB-927, WEB-928] fix: inbox issue bug fixes and improvement (#4160)
* chore: inbox duplicate issue modal improvement

* chore: handled tab navigation in inbox issues and handled cross project inbox issues

* chore: fetch inbox issue activity once the issue is updated in inbox issue

* chore: disable duplicate inbox issue actions

* chore: duplicate issue mutation in the inbox issue

* chore: inbox create modal sidebar tab change updated

* chore: multiple date selection in the inbox issue filters

* chore: code refactor

* chore: removed project dependancy on the inbox store structure

---------

Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
2024-04-10 16:08:31 +05:30
d0cb00f28a [WEB-926] fix: issue description component update handled in peek overview, issue detail, and inbox issues (#4159)
* fix: issue description mutation

* fix: implemented same issue description logic for issue detail and inbox issue description

* fix: fixed parent issue title dissapearing while loading the issue detail page

* chore: code cleanup

* chore: handled exception when issue in not available in issue detail in issue store

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-04-10 14:58:46 +05:30
sriram veeraghanta c80638090f Merge branch 'preview' of github.com:makeplane/plane into preview 2024-04-10 14:04:38 +05:30
Anmol Singh BhatiaandGitHub 549790ee8a [WEB-905] chore: kanban card icon color improvement (#4156)
* chore: kanban card icon color improvement

* chore: kanban card clickable area improvement
2024-04-10 14:03:22 +05:30
1dac70ecbe [WEB-406] chore: project inbox improvement (#4151)
* chore: inbox issue status pill improvement

* chore: loader inconsistancy resolved

* chore: accepted and decline inbox issue validation

* chore: removed clear all button in applied filters

* chore: inbox issue create label improvement

* chore: updated label filter

* chore: updated fetching activites and comments

* chore: inbox filters date

* chore: removed the print statement

* chore: inbox date filter updated

* chore: handled custom date filter in inbox issue query params

* chore: handled custom date filter in inbox issue single select

* chore: inbox custom date filter updated

* chore: inbox sidebar filter improvement

* chore: inbox sidebar filter improvement

* chore: duplicate issue detail

* chore: duplicate inbox issue improvement

* chore: lint issue resolved

---------

Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-04-10 13:52:57 +05:30
Prateek ShouryaandGitHub 3c2b2e3ed6 [WEB-924] chore: remove Add Issues button from completed cycles header. (#4153)
* [WEB-924] chore: remove `Add Issues` button from completed cycles header.

* fix: analytics button.
2024-04-10 13:02:56 +05:30
Anmol Singh BhatiaandGitHub f805acbcef chore: workspace invite loader improvement (#4152) 2024-04-09 19:18:43 +05:30
sriram veeraghantaandGitHub b349de556a chore: security policy updated 2024-04-09 17:53:09 +05:30
Anmol Singh BhatiaandGitHub 699017014e fix: workspace invite empty state flicker (#4150) 2024-04-09 15:04:16 +05:30
Prateek ShouryaandGitHub 2d4547601d [WEB-903] fix: issue subscription button mutation. (#4149) 2024-04-09 15:03:49 +05:30
Prateek ShouryaandGitHub 9b918b727a [WEB-918] style: update size of state dropdown button for consistency. (#4144) 2024-04-09 13:39:01 +05:30
Anmol Singh BhatiaandGitHub 74a88fc028 [WEB-904] chore: feature validation empty state (#4145)
* chore: disable feature empty state added

* chore: disable feature empty state updated
2024-04-09 13:38:07 +05:30
Prateek ShouryaandGitHub e86397b649 [WEB-917] style: update urgent priority icon design. (#4146) 2024-04-09 13:37:18 +05:30
NikhilandGitHub 7e0520d1cf [WEB - 922]dev: fix workspace member caching (#4147)
* dev: fix workspace member caching

* fix: caching on debug
2024-04-09 13:36:08 +05:30
rahulrameshaandGitHub 95580d0c62 [WEB-881] fix: Sentry errors from previous build (#4142)
* Sentry Fix for "Non-Error promise rejection captured with value: Route change to url was aborted"

* Sentry fix for "undefined is not an object (evaluating 'n.response')"

* Possible Sentry Fix for "TypeError Function.entries(<anonymous>)"

* Possible Sentry fix for "null is not an object (evaluating 'e.type')"
2024-04-09 13:12:14 +05:30
guru_sainathandGitHub 03df410b52 fix: updated issue description rendering when we switch between two issues via sub-issue (#4143) 2024-04-08 20:23:16 +05:30
sriram veeraghanta c843a1757f fix: chat with us key handling 2024-04-08 19:39:43 +05:30
/dev/paulandGitHub 2ea6d70fac Changed the crips-wrapper to only use crisp when env is set (#4139) 2024-04-08 19:37:06 +05:30
/dev/paulandGitHub 7bec244a67 Added fonts loaded from Google Fonts locally (#4140)
* Added all fonts locally

* Included LICENSEs

* Changed code to match linter-rules
2024-04-08 19:29:05 +05:30
ddb07dbe5f [WEB-406] chore: project inbox revamp (#4141)
* chore: removed inbox id

* fix: inbox changes

* chore: resolved merge conflicts

* chore: inbox issue response changes

* chore: inbox issue filters

* fix: inbox implementation revamp

* fix: type fixes

* fix: pagination implementation

* fix: inbox fixes

* fix: pagination fixes

* fix: inbox Issues pagination fixes

* chore: triage state change

* fix: inbox fixes

* chore: filtering using boolean

* chore: total results in the pagination

* fix: inbox main content changes

* fix: develop pull fixes

* chore: resolved build erros in inbox issues

* dev: fix migrations

* chore: module, labels and assignee in inbox

* chore: inbox issue order by

* chore: inbox filters

* chore: inbox ui revamp

* chore: inbox type updated

* chore: updated filters

* chore: updated filter menmbers and date types in inbox issue filter

* chore: inbox issue filter updated

* chore: updated date filter in the inbox issue filter

* chore: moved the current tab state from local state to store

* chore: updated the filter and fetch request in the inbox issues

* chore: updated tab change handler

* chore: handled isEmpty in the issue filters query params

* chore: inbox sidebar updated

* chore: enabled create inbox issue in mobx

* chore: replaced the key inbox_status to status

* chore: inbox sidebar pagination

* chore: updated inbox issue services

* chore: inbox sidebar total count indicator

* chore: create inbox issue updated

* chore: updated inbox issue sidebar layout

* chore: rendering issue detail in inbox issue

* chore: inbox issue content updated

* chore: create inbox issue modal description improvement

* fix: updated delete functionality in inbox store

* chore: updated multiple inbox issue creation

* chore: handled loading, empty states and inbox user access permissions

* chore: updated rendering issues in the sidebar

* chore: inbox sidebar label improvement

* chore: handled empty states

* chore: disabled inbox empty state added

* chore: module, labels and assignee in list endpoint

* chore: labels in list endpoint

* chore: inboc issue serializer

* chore: representation in serializer

* chore: super function

* chore: inbox empty state updated

* chore: implemented applied filters

* chore: inbox empty state updated

* chore: update date formats in applied filters

* chore: inbox skeleton updated

* chore: ui changes in the siebar list item

* chore: removed the module and cycle ids

* chore: inbox sidebar tab

* chore: inbox actions

* chore: updated inbox issue header actions

* chore: updated inbox issue code cleanup

* chore: loader improvement

* chore: inbox sidebar improvement

* chore: inbox sidebar empty state flicker

* fix: inbox issue delete operation

* chore: inbox issue title and description update indicator added

* fix: resolved issue property rendering in initial load

* chore: inbox sidebar and detail header improvement

* fix: handling selected filter in the issue filters and applied filters

* chore: inbox issue detail improvement

* chore: inbox issue label updated

* chore: inbox issue sidebar improvement

* fix: handling issue description update when we move between the issues in inbox

* chore: removed inbox issue helpers file

* chore: boolean checked

* chore: resolved file change requests

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
2024-04-08 19:11:47 +05:30
NikhilandGitHub 9b0949148f [WEB - 883] fix: external apis (#3975)
* fix: external apis

* dev: remove descrypt in email password

* dev: add email as field in user serializer

* dev: fix linting errors

* dev: push commit to enable build triggers

* fix: formatting errors

* dev: remove instance value extraction
2024-04-08 18:46:05 +05:30
Prateek ShouryaandGitHub 8d009187ab [WEB-916] fix: description editor missing when using create more button in create issue modal. (#4137)
* [WEB-916] fix: description editor missing when using create more button in create issue modal.

* chore: handle edge cases.

* chore: handle edge cases.
2024-04-08 18:44:04 +05:30
Prateek ShouryaandGitHub 39b5a58ce8 chore: remove placeholder from estimate property if no estimates are selected. (#4125) 2024-04-08 18:38:39 +05:30
Anmol Singh BhatiaandGitHub 986f81e3ae [WEB-905] chore: issue peek overview and kanban layout improvement (#4135)
* chore: peek overview and kanban card improvement

* chore: peek overview improvement
2024-04-08 18:38:05 +05:30
Prateek ShouryaandGitHub fd2cacb0cd [WEB-854] style: update height of sidebar help section and quick add across all layout for consitency. (#4138) 2024-04-08 18:35:35 +05:30
NikhilandGitHub 4f138ac3f9 [WEB - 908] chore: remove user dependency in dockerfile (#4124)
* chore: remove user dependency from api container

* dev: remove user assignment from dockerfile

* dev: add logging configuration
2024-04-08 15:01:17 +05:30
NikhilandGitHub 2c8c139c62 [WEB - 898] fix: external webhooks (#4119)
* fix: project webhooks

* fix: issue and issue comment webhooks

* dev: remove module and cycle issue webhooks

* fix: linting errors
2024-04-08 14:59:50 +05:30
sriram veeraghanta 57f2445bb8 fix: ingest events 2024-04-06 17:13:24 +05:30
rahulrameshaandGitHub 90609b306f [WEB-914]: fix: Exception due to cycles and modules for undefined fields (#4127)
* fix cycle types

* fix module types
2024-04-05 20:05:55 +05:30
Bavisetti NarayanandGitHub 62dac421dc chore: archived cycles and mpdules (#4126) 2024-04-05 19:24:24 +05:30
guru_sainathandGitHub 3742ea91bf fix: issue description was not rendering in the issue create/edit modal (#4122) 2024-04-04 17:24:16 +05:30
Anmol Singh BhatiaandGitHub b4cc58d5dd [WEB-756] chore: spreadsheet layout cycle and module feature toggle validation (#4121)
* chore: spreadsheet layout cycle and module feature toggle validation added

* chore: project analytics cycle and module feature toggle validation added
2024-04-04 15:49:25 +05:30
CrsiandGitHub 71b73000d2 Dropped version info from docker-compose files (#4096)
According to the docker issue 11628
(https://github.com/docker/compose/issues/11628)
the 'version' field in docker-compose files is outdated.
It shows a warning like the following on hosts with a newer
Docker version:

```
WARN[0000] /srv/plane/docker-compose.yaml: `version` is obsolete
```

Also, the specs itself state the version was only informative:
https://github.com/compose-spec/compose-spec/blob/master/spec.md#version-and-name-top-level-elements

> The top-level `version` property is defined by the Compose
> Specification for backward compatibility. It is only informative.
> Compose doesn't use version to select an exact schema to
> validate the Compose file, but prefers the most recent schema
> when it's implemented.
2024-04-04 14:37:50 +05:30
Prateek ShouryaandGitHub 4cba7ff2f5 [WEB-848] fix: issue with parent child relation not being removed parent select dropwdown. (#4120) 2024-04-04 14:24:01 +05:30
NikhilandGitHub 840bc51537 fix: errors that were catched in sentry (#4114) 2024-04-03 21:05:33 +05:30
Prateek ShouryaandGitHub 0ab03c963c [WEB-869] chore: fix assignee and parent ui inconsistency in create issue modal. (#4113) 2024-04-03 20:57:44 +05:30
Prateek ShouryaandGitHub 1fb8791941 chore: increase data dropdown close icon size for consitency. (#4115) 2024-04-03 20:51:22 +05:30
Anmol Singh BhatiaandGitHub e9518ced89 [WEB-756] chore: module and cycle feature toggle validation (#4112)
* chore: cycle and module feature issue block validation

* chore: cycle and module feature display properties validation

* chore: cycle and module feature display filters validation

* chore: cycle and module feature project view validation
2024-04-03 20:49:02 +05:30
Anmol Singh BhatiaandGitHub bc0752f7e8 [WEB-850] chore: calendar layout add existing issue (#4094)
* chore: calendar layout add existing issue added in project issue

* chore: code refactor
2024-04-03 20:46:19 +05:30
Prateek ShouryaandGitHub 4c97098218 chore: archival of modules, cycles and issues enhancement. (#4100) 2024-04-03 18:19:34 +05:30
Anmol Singh BhatiaandGitHub 91d85ffed0 chore: issue block improvement (#4093) 2024-04-03 18:07:28 +05:30
Prateek ShouryaandGitHub d485446ee2 [WEB-652] fix: issue activities alignment in dashboard. (#4106) 2024-04-03 18:06:46 +05:30
Anmol Singh BhatiaandGitHub 92fd7b6977 chore: peek overview remove parent improvement (#4059) 2024-04-03 18:04:35 +05:30
Anmol Singh BhatiaandGitHub e7fc942514 [WEB-830] chore: project filter dropdown custom date select option improvement (#4069)
* chore: project filter dropdown custom date select option improvement

* fix: project filter custom date
2024-04-03 18:03:16 +05:30
Prateek ShouryaandGitHub 68ebcfd04e [842] chore: disable comments and reactions in archived issues. (#4101) 2024-04-03 18:02:07 +05:30
Prateek ShouryaandGitHub fed5916907 [WEB-848] fix: issue with parent child relation not being removed from update issue modal. (#4103) 2024-04-03 18:01:11 +05:30
sriram veeraghantaandGitHub 002fb4547b Merge pull request #4107 from makeplane/preview
release: v0.17-dev
2024-04-02 20:07:48 +05:30
sriram veeraghanta 204e4a8c6d fix: nextjs config sentry 2024-04-02 16:45:18 +05:30
Prateek ShouryaandGitHub bd470f7a90 chore: add Get started button to redirect to /god-mode to set up instance. (#4105) 2024-04-02 14:05:12 +05:30
Anmol Singh BhatiaandGitHub 84e73291cc fix: draft issue title logic (#4104) 2024-04-01 17:53:40 +05:30
SamandGitHub 1423955a34 docs: fix incorrect Docker guide link (#4098) 2024-04-01 16:13:36 +05:30
Prateek ShouryaandGitHub a771bab64c fix: display error message in project settings page. (#4099)
* chore: update `project title` to `project name` in create project modal.
2024-04-01 13:48:12 +05:30
M. PalanikannanandGitHub fafdac68f0 [WEB-876] fix: Multiple editor instances cause weird issues with Tippy (#4092)
* fix: tippy rendered properly when there are multiple editor instances

* enhancement: using cn to merge classes conditionally
2024-04-01 12:04:01 +05:30
Anmol Singh BhatiaandGitHub 3a466cfe40 [WEB-838] fix: cycle dropdown fetch (#4076)
* fix: workspace issue properties fetch

* fix: issue modal cycle fetch issue

* fix: issue modal cycle fetch issue

* chore: project issue properties hook updated
2024-03-28 20:29:35 +05:30
Manish GuptaandGitHub 86715f5b20 Chore: self host enhancements (#4091)
* latest changed to stable and .env changed to plane.env

* env changes

* script fix

* env changes

* sed fix

* codacy proposed fixes
2024-03-28 15:53:37 +05:30
Prateek ShouryaandGitHub 97fb08928f [WEB-834] fix: close shortcut modle on outside click. (#4078) 2024-03-28 15:04:56 +05:30
Prateek ShouryaandGitHub 8bdf8fa24f [WEB-836] fix: color picker overlapping with themes dropdown issue. (#4079) 2024-03-28 15:04:48 +05:30
Prateek ShouryaandGitHub f1530688f8 [WEB-843] fix: chat with us option not woking in command k modal. (#4080) 2024-03-28 15:04:41 +05:30
Prateek ShouryaandGitHub 265ce7778a [WEB-840] chore: remove make a copy option from draft issue quick action menu. (#4081) 2024-03-28 15:04:26 +05:30
Prateek ShouryaandGitHub 79d227b906 [WEB-839] chore: limit project identifier to 5 letters in project settings page. (#4082) 2024-03-28 15:04:16 +05:30
Prateek ShouryaandGitHub 5d4b3cea4c [WEB-833] chore: remove create a new issue option from command k modal if no projects are there. (#4083) 2024-03-28 14:32:16 +05:30
Prateek ShouryaandGitHub 2c510a7cb9 [WEB-852] chore: remove Estimate Demand data from the anaylytics. (#4084) 2024-03-28 14:31:52 +05:30
Prateek ShouryaandGitHub 478535422b [WEB-851] chore: update all instances of Dashboard with Home. (#4085) 2024-03-28 14:31:28 +05:30
sriram veeraghanta 35ca495f40 chore: remove develop builds on push 2024-03-28 14:05:04 +05:30
sriram veeraghanta 68fa7a485b chore: apiserver version changes 2024-03-28 13:59:52 +05:30
sriram veeraghanta ecfd3b68e3 chore: package version upgrade 2024-03-28 13:31:45 +05:30
Anmol Singh BhatiaandGitHub 9249e6d5b9 [WEB-849] fix: issue detail identifier and workspace settings (#4073)
* fix: issue detail identifier

* fix: workspace settings user role validation
2024-03-26 20:38:54 +05:30
NikhilandGitHub 30cee78170 dev: fix api security error (#4072) 2024-03-26 20:38:25 +05:30
NikhilandGitHub 4c46b075b4 fix: module endpoint validations (#4071) 2024-03-26 19:48:52 +05:30
sriram veeraghanta f3d9053d81 fix: unsafe external link fixes 2024-03-26 19:43:22 +05:30
sriram veeraghanta a136931168 fix: codeql workflow push and pull request chanages 2024-03-26 19:40:48 +05:30
sriram veeraghanta 5235b78cb8 fix: sentry config fixes 2024-03-26 19:24:42 +05:30
Bavisetti NarayanandGitHub 1c3619a4d6 chore: workspace estimate project filter (#4070) 2024-03-26 16:59:23 +05:30
Anmol Singh BhatiaandGitHub f3fd48dd43 chore: image picker popover improvement (#4068) 2024-03-26 16:30:57 +05:30
sriram veeraghanta c6f36a056b fix: adding workflow dispatch to codeql 2024-03-26 15:55:47 +05:30
Anmol Singh BhatiaandGitHub 51683e6b2f fix: active cycle stats empty state (#4067) 2024-03-26 15:53:52 +05:30
NikhilandGitHub fb189ca447 fix: cycle issue subquery filter when adding multiple assignees (#4066) 2024-03-26 15:49:44 +05:30
ea728a385f [WEB-831] fix: sentry issue and code refactor (#4063)
* chore: unnecessary console log removed

* chore: in_use sentry issue resolved

* chore: detail sentry issue resolved

* fix: updated project logo validation in project icon

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
2024-03-26 15:13:26 +05:30
NikhilandGitHub 7452e40134 fix: optimize cycles endpoint for sql (#4065) 2024-03-26 15:08:00 +05:30
Bavisetti NarayanandGitHub 599809dd2e chore: removed project from workspace estimate (#4064) 2024-03-26 14:59:28 +05:30
Anmol Singh BhatiaandGitHub ad5559afe4 fix: peek overview delete modal (#4062) 2024-03-25 19:21:00 +05:30
11c3d4fbd8 chore: issue reaction keys (#4061)
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-03-25 19:20:33 +05:30
Ramesh Kumar ChandraandGitHub 20795db9e8 chore: readme update (#4060) 2024-03-25 19:19:55 +05:30
sriram veeraghanta 7e9daf8a20 fix: bad html filtering regexp 2024-03-25 18:54:55 +05:30
igeniandGitHub 07106f9161 fixed bug with missed color #FFFFFF (#4050) 2024-03-25 16:22:20 +05:30
Anmol Singh BhatiaandGitHub 4b8a1353fc fix: kanban layout quick add (#4058) 2024-03-25 16:20:26 +05:30
Anmol Singh BhatiaandGitHub 8205961d2a [WEB-826] chore: integrations (#4057)
* fix: workspace integration page

* chore: remove integrations and code refactor
2024-03-25 16:19:45 +05:30
sriram veeraghanta 53c63c8a2b Merge branch 'preview' of github.com:makeplane/plane into develop 2024-03-25 14:19:35 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
564d64a30e chore(deps): bump follow-redirects from 1.15.4 to 1.15.6 (#4056)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 14:19:02 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
961fdc17d5 chore(deps): bump django in /apiserver/requirements (#4055)
Bumps [django](https://github.com/django/django) from 4.2.10 to 4.2.11.
- [Commits](https://github.com/django/django/compare/4.2.10...4.2.11)

---
updated-dependencies:
- dependency-name: django
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 14:18:24 +05:30
Anmol Singh BhatiaandGitHub 7e0037b06b [WEB-823] fix: quick add flicker and dropdown placement in calendar layout (#4054)
* chore: placement prop added in quick action menu

* fix: calenar layout quick action menu placement

* fix: calendar quick add flicker
2024-03-25 14:17:34 +05:30
Anmol Singh BhatiaandGitHub 9f9e508bb7 [WEB-812] chore: project active cycle stats empty state (#4053)
* chore: empty state asset and config file updated

* chore: empty state asset and config file updated

* chore: active cycle empty state implementation
2024-03-25 13:16:53 +05:30
Bavisetti NarayanandGitHub 2429ac053d [WEB-820] fix: state count in cycle and module (#4052)
* fix: state count in cycle and module

* fix: issue manager change
2024-03-25 13:15:53 +05:30
Aaryan KhandelwalandGitHub 31b2fa2c14 fix: profile activity load more button (#4049) 2024-03-22 20:46:13 +05:30
guru_sainathandGitHub ec837a42d5 fix: handled undefined condition on issue title when we are converting into draft (#4048) 2024-03-22 20:06:49 +05:30
guru_sainathandGitHub b5ed602e05 fix: disbaled the issue property check in the issue create/edit modal (#4038) 2024-03-22 18:46:38 +05:30
sriram veeraghantaandGitHub 9652d56e49 chore: removing deepsource.toml file (#4046) 2024-03-22 18:42:33 +05:30
Prateek ShouryaandGitHub 2f637fc9f1 fix: project total issue count mutation. (#4045) 2024-03-22 18:39:26 +05:30
Prateek ShouryaandGitHub 95d2b6f1c1 style: hide cycle and module dropdown placeholder from list and kanban view. (#4044) 2024-03-22 18:39:06 +05:30
5c7886d7f3 [WEB-811] chore: filter dropdown custom date select improvement (#4043)
* fix: handled custom start_date and target_date custom filter in project-issues

* chore: filter dropdown improvement

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
2024-03-22 18:38:39 +05:30
sriram veeraghanta e4211e5817 Merge branch 'preview' of github.com:makeplane/plane into develop 2024-03-22 18:38:03 +05:30
Aaryan KhandelwalandGitHub 1caceca1e7 [WEB-818] fix: sub-issue and attachment delete not working in the peek overview (#4042)
* fix: delete attachment not working in the peek overview

* fix: sub-issue delete not working

* fix: lint errors
2024-03-22 18:37:11 +05:30
Anmol Singh BhatiaandGitHub 53f3357149 chore: cycle list page alignment (#4041) 2024-03-22 18:36:34 +05:30
Anmol Singh BhatiaandGitHub cdf86391f0 fix: module filter and order by (#4040) 2024-03-22 18:36:09 +05:30
guru_sainathandGitHub 72392d5731 fix: resetting the changesMage when the createmore toggle is turned on in issue create-edit modal (#4039) 2024-03-22 18:35:40 +05:30
guru_sainathandGitHub db8cf1fb24 fix: handled quick actions in the project draft issues (#4034) 2024-03-22 18:35:06 +05:30
Lakhan BahetiandGitHub d262eb4ffb [WEB-800] fix: issue peekview, and detail page create label colour selector autoplacement (#4032)
* fix: issue peekview, and detail label colour selector autoplacement

* fix: build errors
2024-03-22 18:30:23 +05:30
guru_sainathandGitHub 60aea62739 fix: handled inital empty state close in the issue create/edit odal (#4033) 2024-03-22 18:28:44 +05:30
Anmol Singh BhatiaandGitHub baab6ce99f fix: project order by dropdown (#4037) 2024-03-22 18:26:44 +05:30
Anmol Singh BhatiaandGitHub 5aed04eb41 fix: module and cycle list page quick action (#4031) 2024-03-21 21:16:06 +05:30
guru_sainathandGitHub 165bec9aa4 fix: handled the empty issue propety, create more in edit modal, and moving drafts from issue functionality (#4030) 2024-03-21 21:06:55 +05:30
231fd52992 [WEB-447] feat: projects archive. (#4014)
* dev: project archive response

* feat: projects archive.

* dev: response changes for cycle and module

* chore: status message changed

* chore: update clear all applied display filters logic.

* style: archived project card UI update.

* chore: archive/ restore taost message update.

* fix: clear all applied display filter logic.

* chore: project empty state update to handle archived projects.

* chore: minor typo fix in cycles and modules archive.

* chore: close cycle/ module overview sidebar if it's already open when clicked on overview button.

* chore: optimize current workspace applied display filter logic.

* chore: update all `archived_at` type from `Date` to `string`.

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-03-21 20:59:34 +05:30
Lakhan BahetiandGitHub 9642b761b7 fix: issue card assignee empty state tooltip (#4029) 2024-03-21 20:59:08 +05:30
guru_sainathandGitHub 86ae79f851 fix: resolved rendering issues in list and kanban layout when we apply group-by filter (#4028) 2024-03-21 20:47:36 +05:30
Anmol Singh BhatiaandGitHub 991b8e7703 chore: custom month select modal validation added (#4027) 2024-03-21 20:47:22 +05:30
Anmol Singh BhatiaandGitHub 56d4e25431 fix: project list view dropdown placement (#4026) 2024-03-21 20:47:07 +05:30
Prateek ShouryaandGitHub 23f77328d4 fix: prevent custom menu button from opening cycle/ module details page when closed. (#4025) 2024-03-21 20:46:33 +05:30
guru_sainathandGitHub 58a45c96c0 fix: rendering default state in the issue create update modal whenever we switch between the projects in the issue modal (#4024) 2024-03-21 20:46:18 +05:30
Anmol Singh BhatiaandGitHub 15e04e55bb [WEB-692] fix: project modal cover image popover z-index fix (#4018)
* fix: project modal cover image popover z-index fix

* fix: project modal cover image popover z-index fix
2024-03-21 20:46:02 +05:30
Anmol Singh BhatiaandGitHub 8911eaf676 fix: profile cover fix (#4010) 2024-03-21 15:36:16 +05:30
sriram veeraghanta 0d2a8cca50 chore: project structuring 2024-03-21 14:58:16 +05:30
061be85a5d feat: cycles and modules archive. (#4005)
* fix: GET request changes

* fix: filtering changes

* feat: cycles and modules archive.

* chore: disable fetching of cycle/ module details when clicked on the card in archives page.

* chore: remove copy link button from archived modules/ cycles.

* fix: archived cycle and module loading fliker issue.

* chore: add validation to only archive completed cycles.

* chore: add validation to only archive completed or cancelled module.

* chore: archived issues/ cycles/ modules empty state update.

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-03-20 21:02:58 +05:30
Bavisetti NarayanandGitHub 4d1b5adfc4 dev: assignee leave changes (#4009) 2024-03-20 20:42:14 +05:30
3ff0f6187a [WEB-762] chore: cycle, module modal improvement and cycle, module (#4000)
* chore: cycle modal description improvement

* chore: updated the description ui in cycles and modules

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
2024-03-20 20:41:49 +05:30
Anmol Singh BhatiaandGitHub 37c5ce54d5 fix: peek overview sub issue operation (#4002) 2024-03-20 20:00:34 +05:30
Anmol Singh BhatiaandGitHub 054dd2bb7d fix: module empty state (#4004) 2024-03-20 20:00:13 +05:30
Bavisetti NarayanandGitHub 180f1d74e8 dev: removed double issue count (#4008) 2024-03-20 19:59:31 +05:30
Lakhan BahetiandGitHub 6ab8588afb fix: create label inline overflow (#4006) 2024-03-20 19:32:42 +05:30
NikhilandGitHub e1f04356fc dev: add -p flag for the logs folder (#4007) 2024-03-20 19:28:19 +05:30
Lakhan BahetiandGitHub 4eefc7f692 [WEB-784] chore: create workspace fields as required indication (#4003)
* chore: create workspace fields as required indication

* style: gap between asterisk & text
2024-03-20 19:22:02 +05:30
7142889c23 [WEB-413] chore: project active cycle UI revamp (#3997)
* chore: project active cycle ui revamp

* chore: resolved liniting issues

---------

Co-authored-by: gurusainath <gurusainath007@gmail.com>
2024-03-20 19:19:14 +05:30
guru_sainathandGitHub bca3e13242 fix: project inifinite loader when we go the workspace projects for the first time (#3999) 2024-03-20 18:08:42 +05:30
guru_sainathandGitHub e02fa4d9e7 fix: autofocus on the title element when we are creating the bulk issues in the issue create modal (#3998) 2024-03-20 18:08:21 +05:30
guru_sainathandGitHub 621624e29f [WEB-383] fix: rendering state and members from different projects in sub-issues (#3996)
* fix: rendering the state and memebers from different projects in sub issues and exception handling while creating an issue from different project

* chore: handled different project issue properties in a new function handler
2024-03-20 18:07:35 +05:30
Lakhan BahetiandGitHub 4ea616f1cd fix: Labels overflow in peek, detail view (#3995) 2024-03-20 18:07:11 +05:30
Lakhan BahetiandGitHub 901a7703ff fix: project, module, cycle filter store infinite loop (#3994) 2024-03-20 18:06:45 +05:30
Bavisetti NarayanandGitHub 2f883e4939 [WEB-780]feat: project cycle module archive (#3990)
* dev: project cycle module archive

* fix: update filter logic updated
2024-03-20 13:59:31 +05:30
rahulrameshaandGitHub cb4cfa1dd5 [WEB-782] fix: Date timezone changes error (#3992)
* fix date related exceptions

* replace new Date from develop branch changes as well

* changes from self review

* wrap getDate logic with try catch to handle in case of error scenarios

* fix formatted time
2024-03-20 13:44:08 +05:30
guru_sainathandGitHub 7d3a96b3d0 [WEB-763] fix: workspace remains listed after leaving the workspace in the user profile (#3993)
* chore: build error

* fix: workspace not getting removed when user leaves the workspace
2024-03-20 13:43:18 +05:30
Wiebe VerweijandGitHub 0f79c6d7d8 Fix test_email command to use new SSL setting (#3988)
This was missed in pull request #3732 and/or the command didn't exist yet then ...
2024-03-20 12:46:40 +05:30
Lakhan BahetiandGitHub 6a245e121a fix: analytics dialog close on outside click (#3987) 2024-03-20 12:42:10 +05:30
NikhilandGitHub 293854fb3a fix: user caching when the user leaves/deletes the workspace (#3989) 2024-03-20 12:38:00 +05:30
sriram veeraghanta 53ddef1cd5 fix: eslint fixes and file formatting 2024-03-19 20:08:35 +05:30
sriram veeraghanta 473dfc7a5b fix: merge conflicts resolved 2024-03-19 18:00:43 +05:30
rahulrameshaandGitHub 1a462711e1 [WEB-761] fix: Time zone date misalignment (#3986)
* fix date time misalignment

* fix failing build

* fix gantt chart view position fix

* comments for getDate method

* remove new Date() where not required

* changes from my self review
2024-03-19 17:40:20 +05:30
sriram veeraghanta 3139f8e109 fix: merge conflicts resolved 2024-03-18 19:58:39 +05:30
sriram veeraghanta aa3702cd46 fix: codeql check workflow changes 2024-03-18 19:50:58 +05:30
sriram veeraghanta aed87ef472 fix: build branch workflow dispatch trigger changes 2024-03-18 19:48:44 +05:30
roujaandGitHub 1b742f66c6 Fix email configuration issue (#3732) 2024-03-18 19:43:00 +05:30
Lakhan BahetiandGitHub 568701881e fix: calendar-layout draggable wrapper condition (#3984) 2024-03-18 19:35:17 +05:30
Lakhan BahetiandGitHub 2dbea54d2a fix: Mobile header visibility (#3983) 2024-03-18 16:54:45 +05:30
NikhilandGitHub 82ba9833f2 dev: enable api logging (#2538)
* dev: enable api logging and control worker count through env

* dev: enable logger instead of printing

* dev: remove worker counts

* dev: enable global level log settings

* dev: add rotating logger

* fix: logging configuration

* dev: api logging and moving the capture exception to utils for logging and then capturing

* fix: information leaking through print logs

* dev: linting fix

* dev: logging configuration for django

* fix: linting errors

* dev: add logs for migrator

* dev: logging cofiguration

* dev: add permision for captain user in Plane

* dev: add log paths in compose

* dev: create directory for logs

* dev: fix linting errors
2024-03-18 14:27:02 +05:30
M. PalanikannanandGitHub 0759666b75 [WEB-755] fix: Clearing nodes to default node i.e. paragraph before converting it to other type (#3974)
* fix: clearing nodes to default node i.e paragraph before converting it to other types of nodes

For more reference on what this does, please refer https://tiptap.dev/docs/editor/api/commands/clear-nodes

* chore: clearNodes after delete in case of selections being present

* fix: hiding link selector in the bubble menu if inline code block is selected
2024-03-18 12:51:35 +05:30
Lakhan BahetiandGitHub e9774e1af3 [WEB-759] style: added calendar layout responsiveness (#3969)
* style: added calendar layout responsiveness

* fix: quick-add-form

* fix: popover menu close on item select

* fix: class conditiion

* code review
2024-03-18 12:51:19 +05:30
Ramesh Kumar ChandraandGitHub 4a93fdbdb4 [WEB-700] chore: sidebar hamburger refactor (#3960) 2024-03-18 12:50:33 +05:30
Aaryan KhandelwalandGitHub 861a1c4132 [WEB-738] chore: conditionally render projects in the dropdown (#3952)
* chore: show authorized projects in the dropdown

* refactor: command palette logic

* chore: add helper function to check for project role

* fix: add preventDefault for shortcuts
2024-03-15 17:44:01 +05:30
Anmol Singh BhatiaandGitHub 5244ba72c9 [WEB-746] chore: draft issue modal improvement (#3966)
* chore: draft issue modal improvement

* chore: draft issue modal improvement

* chore: draft issue modal improvement

* chore: draft issue modal improvement
2024-03-15 17:43:42 +05:30
Anmol Singh BhatiaandGitHub 36bc7bf996 chore: app sidebar collapsed state alignment improvement (#3976) 2024-03-15 17:36:20 +05:30
Aaryan KhandelwalandGitHub 0789238282 fix: cycle layout not getting initialized (#3961) 2024-03-15 17:31:28 +05:30
Anmol Singh BhatiaandGitHub c17748eec2 chore: completed cycle empty state valdidation updated (#3959) 2024-03-15 17:30:26 +05:30
Anmol Singh BhatiaandGitHub 94f1e6d957 [WEB-698] chore: profile activity page scrollbar added (#3958)
* chore: profile activity page scrollbar added

* chore: profile activity page padding improvement
2024-03-15 17:29:46 +05:30
Aaryan KhandelwalandGitHub 13bbb9cde4 [WEB-699] chore: implement sub-issues and attachments in the peek overview (#3956)
* chore: implement sub-issues and attachments in the peek overview

* chore: add the same to full-screen view
2024-03-15 17:29:22 +05:30
Anmol Singh BhatiaandGitHub 92a077dce1 [WEB-504] chore: command k and issue relation modal empty state (#3955)
* chore: empty state asset updated

* chore: empty state asset updated

* chore: empty state config file updated

* chore: notification empty state updated

* chore: command-k, bulk delete and issue relation modal empty state updated

* chore: code refactor

* chore: code refactor
2024-03-15 17:28:45 +05:30
Lakhan BahetiandGitHub ed2e4ad6f7 fix: cycle & module peekview scroll (#3953) 2024-03-15 17:28:03 +05:30
Anmol Singh BhatiaandGitHub cbe5d9a047 chore: issue reaction response updated (#3951) 2024-03-15 17:26:38 +05:30
Ramesh Kumar ChandraandGitHub d25fcfdd88 [WEB-715] chore: closing custom dropdown on button click (#3950) 2024-03-15 17:25:57 +05:30
Aaryan KhandelwalandGitHub aaad37575b fix: cycle date check wrong projectId (#3972) 2024-03-14 20:11:10 +05:30
Aaryan KhandelwalandGitHub 6bc133e3b1 chore: swapped dates and status properties in the cycle list item (#3957) 2024-03-14 20:02:18 +05:30
Bavisetti NarayanandGitHub 42b524b16a chore: project active filter (#3971) 2024-03-14 19:22:54 +05:30
Anmol Singh BhatiaandGitHub 0bc4b6cece chore: ai modal disclamier added (#3970) 2024-03-14 19:16:07 +05:30
guru_sainathandGitHub 43c75f4457 fix: rendering Issue in kanban swimlanes view for unassigned cycle or Modules (#3965) 2024-03-14 12:43:29 +05:30
sriram veeraghanta 80761d3507 Merge branch 'preview' of github.com:makeplane/plane into develop 2024-03-14 12:42:33 +05:30
sriram veeraghanta 9c13dbd957 chore: 1click docs readme update 2024-03-13 17:26:52 +05:30
sriram veeraghanta 8d9adf4d87 chore: 1click docs readme update 2024-03-13 17:26:04 +05:30
sriram veeraghanta 4ccb505f36 chore: 1click docs changes 2024-03-13 17:24:37 +05:30
sriram veeraghanta 884856b021 chore: 1click docs update 2024-03-13 17:18:11 +05:30
sriram veeraghanta 552c66457a chore: 1click docs update 2024-03-13 17:17:40 +05:30
P BandGitHub 1363ef0b2d Updated one-click deploy's readme for readability and presentation (#3962)
Changed title, first paragraph, and bullets.
2024-03-13 17:13:11 +05:30
guru_sainathandGitHub 898cf98be3 [WEB-749] fix: rendering empty states with "showEmptyGroup" filter in issue grouping (#3954)
* fix: Fixed show empty states in groupBy and subGroupBy in kanban

* lint: lint issue resolved
2024-03-13 16:59:12 +05:30
cb632408f9 [WEB-713] style: remove tooltips in mobile responsiveness (#3948)
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-03-12 20:39:36 +05:30
b930d98665 [WEB-554] feat: modules filtering, searching and ordering (#3947)
* feat: modules filtering, searching and ordering implemented

* fix: modules ordering

* chore: total issues in list endpoint

* fix: modules ordering

* fix: build errors

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-03-12 20:24:21 +05:30
Aaryan KhandelwalandGitHub 69e110f4a8 [WEB-578] feat: projects list filtering and ordering (#3926)
* style: project card UI updated

* dev: initialize project filter store and types

* chore: implemented filtering logic

* chore: implemented ordering

* chore: my projects filter added

* chore: update created at date filter options

* refactor: order by dropdown

* style: revert project card UI

* fix: project card z-index

* fix: members filtering

* fix: build errors
2024-03-12 19:36:40 +05:30
Lakhan BahetiandGitHub c3c6ef8830 chore: removed module tooltip from peek-overview & issue detail (#3946) 2024-03-12 19:13:04 +05:30
Anmol Singh BhatiaandGitHub 8aca74c68d [WEB-720] chore: reaction tooltip added (#3945)
* chore: reaction tooltip added

* chore: reaction tooltip updated

* chore: issue reaction tooltip updated

* chore: helper function updated
2024-03-12 19:12:25 +05:30
Prateek ShouryaandGitHub c97b994311 [WEB-717] fix: delete issue modal UI fixes. (#3944)
* fix: avoid closing the peek overview when the close button within the delete model popup is clicked.

* fix: distortion in issue detail sidebar UI when any modal is open.
2024-03-12 19:11:36 +05:30
Lakhan BahetiandGitHub 443b93f897 fix: label mutation in peek-overview & issue detail (#3942) 2024-03-12 19:10:35 +05:30
Aaryan KhandelwalandGitHub 730e556bea fix: emoji picker unnecessary scroll (#3941) 2024-03-12 19:09:51 +05:30
Aaryan KhandelwalandGitHub f77f4b8221 fix: gantt sidebar links (#3940) 2024-03-12 19:07:12 +05:30
Anmol Singh BhatiaandGitHub 5c4c3f5c04 fix: project page empty state (#3939) 2024-03-12 19:05:15 +05:30
Ramesh Kumar ChandraandGitHub 73c91654eb [WEB-716] style: list view issues responsiveness (#3938) 2024-03-12 12:29:00 +05:30
Bavisetti NarayanandGitHub 578bd29f6f chore: active issue total count (#3936) 2024-03-12 12:24:58 +05:30
NikhilandGitHub 2e5e14556d feat: test email script (#3937)
* feat: script for testing emails

* chore: rename subject and body for the mail
2024-03-12 12:00:18 +05:30
sriram veeraghanta ecac45e885 Merge branch 'preview' of github.com:makeplane/plane into develop 2024-03-12 01:12:57 +05:30
sriram veeraghanta 6ec9c64f7c fix: build branch optional builds workflow changes 2024-03-12 01:06:37 +05:30
sriram veeraghanta f493a03f56 fix: adding github workflow events 2024-03-12 01:01:03 +05:30
Anmol Singh BhatiaandGitHub 48c9b78397 [WEB-545] chore: completed cycle empty state (#3931)
* chore: completed cycle issue transfer empty state added

* chore: cycle empty state variable updated

* chore: empty state config file updated
2024-03-11 21:23:09 +05:30
Anmol Singh BhatiaandGitHub 9c29ad1a28 chore: list layout scrollbar improvement (#3933) 2024-03-11 21:12:59 +05:30
Aaryan KhandelwalandGitHub e3ac075ee2 chore: error state for the issues widgets (#3934) 2024-03-11 21:12:28 +05:30
Anmol Singh BhatiaandGitHub 8c9d328c24 chore: profile setting scroll fix and scrollbar added in activity section (#3929) 2024-03-11 21:09:41 +05:30
Aaryan KhandelwalandGitHub b2146098e2 chore: added view less button to the collaborators widget (#3928) 2024-03-11 21:09:16 +05:30
NikhilandGitHub 4a06572f73 chore: remove deprecated envs (#3927) 2024-03-11 21:08:10 +05:30
M. PalanikannanandGitHub d34df5c805 fix: updated extensions in read only instance of the editor (#3925) 2024-03-11 21:05:27 +05:30
01702e9f66 [WEB-402] chore: project issues count (#3911)
* chore: added project issues count

* chore: project module and cycle issue count

* chore: resolved merge conflicts

* chore: added import statement

* chore: issue count type added

* chore: issue count added in project, cycle and module issues

* fix: lint fixes

* chore: tooltip added in issue count badge

* chore: tooltip added in issue count badge

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-03-11 21:05:00 +05:30
NikhilandGitHub b57c389c75 fix: caching (#3923) 2024-03-11 21:04:43 +05:30
Lakhan BahetiandGitHub 27acd1bec1 fix: cycle & module sidebar progress-stats scroll (#3932) 2024-03-11 21:03:30 +05:30
Anmol Singh BhatiaandGitHub 539afb0792 chore: issue quick action dropdown max height updated (#3919) 2024-03-11 21:02:28 +05:30
Anmol Singh BhatiaandGitHub 6c7ba3bc79 chore: applied filter ui improvement (#3918) 2024-03-11 21:01:59 +05:30
Anmol Singh BhatiaandGitHub c8ab650008 fix: module empty state create issue (#3916) 2024-03-11 21:01:27 +05:30
Anmol Singh BhatiaandGitHub 89d019df57 fix: parent select modal params updated (#3914) 2024-03-11 21:01:07 +05:30
535731141f [WEB-682] feat: cycles list filtering and searching (#3910)
* chore: implemented cycles list filters and ordering

* chore: active cycle tab updated

* refactor: cycles folder structure

* fix: name search inout auto-focus

* fix: cycles ordering

* refactor: move cycle filters logic to mobx store from local storage

* chore: show completed cycles in a disclosure

* chore: added completed cycles count

* refactor: cycles mapping logic

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-03-11 21:00:05 +05:30
4b30339a59 [WEB-638] feat: add tabIndex prop support to navigate using Tab key in all the editors (#3902)
* feat: added tab index support to navigate using Tab key in all the editors

* chore: changed the name of Table of Contents in Pages

* chore: file formatting

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-03-11 20:58:23 +05:30
899771a678 [WEB-434] feat: add support to insert a new empty line on clicking at bottom of the editor (#3856)
* fix: horizontal rule no more causes issues on last node

* fixed the mismatched transaction by using native tiptap stuff

* added support to add new line onclick at bottom if last node is an image

TODO: blockquote at last node

* fix: simplified adding node at end of the document logic

* feat: rewrite entire logic handling all cases

* feat: arrow down and arrow up keys add empty node at top and bottom of doc from first/last row's cells

* feat: added arrow up and down key support to images too

* remove unnecessary console logs

* chore: formatting components

* fix: reduced bottom padding to increase onclick area

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
2024-03-11 20:55:24 +05:30
sriram veeraghanta 8997ee2e3e fix: eslint fixes 2024-03-11 20:45:51 +05:30
sriram veeraghanta cb78ccad1f fix: 1click deployment fixes 2024-03-08 16:58:37 +05:30
Manish Gupta 6c6b7156bb helm variable update 2024-03-08 16:00:18 +05:30
Manish Gupta 8cc372679c Web Build fixes 2024-03-08 15:56:05 +05:30
Manish GuptaandGitHub 94327b8311 chore: feature build process optimization (#3907)
* process changed to build tar and use for deployment

* fixes
2024-03-08 15:16:32 +05:30
sriram veeraghantaandGitHub c1b1ba35c1 Merge pull request #3878 from makeplane/preview
release: v0.16-dev
2024-03-05 20:04:08 +05:30
sriram veeraghantaandGitHub 4566d6e80c Merge pull request #3697 from makeplane/preview
release: 0.15.4-dev
2024-02-19 19:30:06 +05:30
sriram veeraghantaandGitHub e8d359e625 Merge pull request #3674 from makeplane/preview
fix: build branch docker images push on release
2024-02-15 14:35:32 +05:30
sriram veeraghantaandGitHub 351eba8d61 Merge pull request #3671 from makeplane/preview
release: peek overview issue description initial load bug (#3670)
2024-02-15 03:25:30 +05:30
sriram veeraghantaandGitHub 1e27e37b51 Merge pull request #3666 from makeplane/preview
release: v0.15.2-dev
2024-02-14 19:41:55 +05:30
sriram veeraghantaandGitHub 7df2e9cf11 Merge pull request #3632 from makeplane/preview
release: v0.15.1-dev
2024-02-12 20:59:56 +05:30
sriram veeraghantaandGitHub c6e3f1b932 Merge pull request #3535 from makeplane/preview
release: 0.15-dev
2024-02-01 15:01:49 +05:30
2146 changed files with 79799 additions and 51900 deletions
-23
View File
@@ -1,23 +0,0 @@
version = 1
exclude_patterns = [
"bin/**",
"**/node_modules/",
"**/*.min.js"
]
[[analyzers]]
name = "shell"
[[analyzers]]
name = "javascript"
[analyzers.meta]
plugins = ["react"]
environment = ["nodejs"]
[[analyzers]]
name = "python"
[analyzers.meta]
runtime_version = "3.x.x"
+59
View File
@@ -0,0 +1,59 @@
/**
* Adds three new lint plugins over the existing configuration:
* This is used to lint staged files only.
* We should remove this file once the entire codebase follows these rules.
*/
module.exports = {
root: true,
extends: [
"custom",
],
parser: "@typescript-eslint/parser",
settings: {
"import/resolver": {
typescript: {},
node: {
moduleDirectory: ["node_modules", "."],
},
},
},
rules: {
"import/order": [
"error",
{
groups: ["builtin", "external", "internal", "parent", "sibling"],
pathGroups: [
{
pattern: "react",
group: "external",
position: "before",
},
{
pattern: "lucide-react",
group: "external",
position: "after",
},
{
pattern: "@headlessui/**",
group: "external",
position: "after",
},
{
pattern: "@plane/**",
group: "external",
position: "after",
},
{
pattern: "@/**",
group: "internal",
},
],
pathGroupsExcludedImportTypes: ["builtin", "internal", "react"],
alphabetize: {
order: "asc",
caseInsensitive: true,
},
},
],
},
};
+1 -1
View File
@@ -4,7 +4,7 @@ module.exports = {
extends: ["custom"],
settings: {
next: {
rootDir: ["web/", "space/"],
rootDir: ["web/", "space/", "admin/"],
},
},
};
+9 -2
View File
@@ -55,12 +55,19 @@ body:
- Safari
- Other
- type: dropdown
id: version
id: variant
attributes:
label: Version
label: Variant
options:
- Cloud
- Self-hosted
- Local
validations:
required: true
- type: input
id: version
attributes:
label: Version
placeholder: v0.17.0-dev
validations:
required: true
-84
View File
@@ -1,84 +0,0 @@
name: Auto Merge or Create PR on Push
on:
workflow_dispatch:
push:
branches:
- "sync/**"
env:
CURRENT_BRANCH: ${{ github.ref_name }}
SOURCE_BRANCH: ${{ secrets.SYNC_SOURCE_BRANCH_NAME }} # The sync branch such as "sync/ce"
TARGET_BRANCH: ${{ secrets.SYNC_TARGET_BRANCH_NAME }} # The target branch that you would like to merge changes like develop
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} # Personal access token required to modify contents and workflows
REVIEWER: ${{ secrets.SYNC_PR_REVIEWER }}
jobs:
Check_Branch:
runs-on: ubuntu-latest
outputs:
BRANCH_MATCH: ${{ steps.check-branch.outputs.MATCH }}
steps:
- name: Check if current branch matches the secret
id: check-branch
run: |
if [ "$CURRENT_BRANCH" = "$SOURCE_BRANCH" ]; then
echo "MATCH=true" >> $GITHUB_OUTPUT
else
echo "MATCH=false" >> $GITHUB_OUTPUT
fi
Auto_Merge:
if: ${{ needs.Check_Branch.outputs.BRANCH_MATCH == 'true' }}
needs: [Check_Branch]
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4.1.1
with:
fetch-depth: 0 # Fetch all history for all branches and tags
- name: Setup Git
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
- name: Setup GH CLI and Git Config
run: |
type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh -y
- name: Check for merge conflicts
id: conflicts
run: |
git fetch origin $TARGET_BRANCH
git checkout $TARGET_BRANCH
# Attempt to merge the main branch into the current branch
if $(git merge --no-commit --no-ff $SOURCE_BRANCH); then
echo "No merge conflicts detected."
echo "HAS_CONFLICTS=false" >> $GITHUB_ENV
else
echo "Merge conflicts detected."
echo "HAS_CONFLICTS=true" >> $GITHUB_ENV
git merge --abort
fi
- name: Merge Change to Target Branch
if: env.HAS_CONFLICTS == 'false'
run: |
git commit -m "Merge branch '$SOURCE_BRANCH' into $TARGET_BRANCH"
git push origin $TARGET_BRANCH
- name: Create PR to Target Branch
if: env.HAS_CONFLICTS == 'true'
run: |
# Replace 'username' with the actual GitHub username of the reviewer.
PR_URL=$(gh pr create --base $TARGET_BRANCH --head $SOURCE_BRANCH --title "sync: merge conflicts need to be resolved" --body "" --reviewer $REVIEWER)
echo "Pull Request created: $PR_URL"
+76 -18
View File
@@ -6,7 +6,6 @@ on:
branches:
- master
- preview
- develop
release:
types: [released, prereleased]
@@ -18,15 +17,16 @@ jobs:
name: Build-Push Web/Space/API/Proxy Docker Image
runs-on: ubuntu-latest
outputs:
gh_branch_name: ${{ steps.set_env_variables.outputs.TARGET_BRANCH }}
gh_branch_name: ${{ steps.set_env_variables.outputs.TARGET_BRANCH }}
gh_buildx_driver: ${{ steps.set_env_variables.outputs.BUILDX_DRIVER }}
gh_buildx_version: ${{ steps.set_env_variables.outputs.BUILDX_VERSION }}
gh_buildx_platforms: ${{ steps.set_env_variables.outputs.BUILDX_PLATFORMS }}
gh_buildx_endpoint: ${{ steps.set_env_variables.outputs.BUILDX_ENDPOINT }}
build_frontend: ${{ steps.changed_files.outputs.frontend_any_changed }}
build_space: ${{ steps.changed_files.outputs.space_any_changed }}
build_backend: ${{ steps.changed_files.outputs.backend_any_changed }}
build_proxy: ${{ steps.changed_files.outputs.proxy_any_changed }}
build_apiserver: ${{ steps.changed_files.outputs.apiserver_any_changed }}
build_admin: ${{ steps.changed_files.outputs.admin_any_changed }}
build_space: ${{ steps.changed_files.outputs.space_any_changed }}
build_web: ${{ steps.changed_files.outputs.web_any_changed }}
steps:
- id: set_env_variables
@@ -54,8 +54,12 @@ jobs:
uses: tj-actions/changed-files@v42
with:
files_yaml: |
frontend:
- web/**
apiserver:
- apiserver/**
proxy:
- nginx/**
admin:
- admin/**
- packages/**
- 'package.json'
- 'yarn.lock'
@@ -68,13 +72,16 @@ jobs:
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
backend:
- apiserver/**
proxy:
- nginx/**
web:
- web/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
branch_build_push_frontend:
if: ${{ needs.branch_build_setup.outputs.build_frontend == 'true' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
branch_build_push_web:
if: ${{ needs.branch_build_setup.outputs.build_web == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
runs-on: ubuntu-20.04
needs: [branch_build_setup]
env:
@@ -125,8 +132,60 @@ jobs:
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
branch_build_push_admin:
if: ${{ needs.branch_build_setup.outputs.build_admin== 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
runs-on: ubuntu-20.04
needs: [branch_build_setup]
env:
ADMIN_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:${{ needs.branch_build_setup.outputs.gh_branch_name }}
TARGET_BRANCH: ${{ needs.branch_build_setup.outputs.gh_branch_name }}
BUILDX_DRIVER: ${{ needs.branch_build_setup.outputs.gh_buildx_driver }}
BUILDX_VERSION: ${{ needs.branch_build_setup.outputs.gh_buildx_version }}
BUILDX_PLATFORMS: ${{ needs.branch_build_setup.outputs.gh_buildx_platforms }}
BUILDX_ENDPOINT: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
steps:
- name: Set Admin Docker Tag
run: |
if [ "${{ github.event_name }}" == "release" ]; then
TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:stable,${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:${{ github.event.release.tag_name }}
elif [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:latest
else
TAG=${{ env.ADMIN_TAG }}
fi
echo "ADMIN_TAG=${TAG}" >> $GITHUB_ENV
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: ${{ env.BUILDX_DRIVER }}
version: ${{ env.BUILDX_VERSION }}
endpoint: ${{ env.BUILDX_ENDPOINT }}
- name: Check out the repo
uses: actions/checkout@v4
- name: Build and Push Frontend to Docker Container Registry
uses: docker/build-push-action@v5.1.0
with:
context: .
file: ./admin/Dockerfile.admin
platforms: ${{ env.BUILDX_PLATFORMS }}
tags: ${{ env.ADMIN_TAG }}
push: true
env:
DOCKER_BUILDKIT: 1
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
branch_build_push_space:
if: ${{ needs.branch_build_setup.outputs.build_space == 'true' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
if: ${{ needs.branch_build_setup.outputs.build_space == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
runs-on: ubuntu-20.04
needs: [branch_build_setup]
env:
@@ -177,8 +236,8 @@ jobs:
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
branch_build_push_backend:
if: ${{ needs.branch_build_setup.outputs.build_backend == 'true' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
branch_build_push_apiserver:
if: ${{ needs.branch_build_setup.outputs.build_apiserver == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
runs-on: ubuntu-20.04
needs: [branch_build_setup]
env:
@@ -230,7 +289,7 @@ jobs:
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
branch_build_push_proxy:
if: ${{ needs.branch_build_setup.outputs.build_proxy == 'true' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
if: ${{ needs.branch_build_setup.outputs.build_proxy == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
runs-on: ubuntu-20.04
needs: [branch_build_setup]
env:
@@ -280,4 +339,3 @@ jobs:
DOCKER_BUILDKIT: 1
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
+56 -23
View File
@@ -10,42 +10,50 @@ jobs:
runs-on: ubuntu-latest
outputs:
apiserver_changed: ${{ steps.changed-files.outputs.apiserver_any_changed }}
admin_changed: ${{ steps.changed-files.outputs.admin_any_changed }}
space_changed: ${{ steps.changed-files.outputs.space_any_changed }}
web_changed: ${{ steps.changed-files.outputs.web_any_changed }}
space_changed: ${{ steps.changed-files.outputs.deploy_any_changed }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v41
uses: tj-actions/changed-files@v44
with:
files_yaml: |
apiserver:
- apiserver/**
web:
- web/**
admin:
- admin/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
deploy:
space:
- space/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
web:
- web/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
lint-apiserver:
needs: get-changed-files
runs-on: ubuntu-latest
if: needs.get-changed-files.outputs.apiserver_changed == 'true'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x' # Specify the Python version you need
python-version: "3.x" # Specify the Python version you need
- name: Install Pylint
run: python -m pip install ruff
- name: Install Apiserver Dependencies
@@ -53,52 +61,77 @@ jobs:
- name: Lint apiserver
run: ruff check --fix apiserver
lint-web:
lint-admin:
needs: get-changed-files
if: needs.get-changed-files.outputs.web_changed == 'true'
if: needs.get-changed-files.outputs.admin_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn install
- run: yarn lint --filter=web
- run: yarn lint --filter=admin
lint-space:
needs: get-changed-files
if: needs.get-changed-files.outputs.space_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn install
- run: yarn lint --filter=space
build-web:
needs: lint-web
lint-web:
needs: get-changed-files
if: needs.get-changed-files.outputs.web_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn install
- run: yarn build --filter=web
- run: yarn lint --filter=web
build-admin:
needs: lint-admin
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn install
- run: yarn build --filter=admin
build-space:
needs: lint-space
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn install
- run: yarn build --filter=space
build-web:
needs: lint-web
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18.x
- run: yarn install
- run: yarn build --filter=web
+32 -33
View File
@@ -1,13 +1,13 @@
name: "CodeQL"
on:
workflow_dispatch:
push:
branches: [ 'develop', 'preview', 'master' ]
branches: ["preview", "master"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ 'develop', 'preview', 'master' ]
branches: ["develop", "preview", "master"]
schedule:
- cron: '53 19 * * 5'
- cron: "53 19 * * 5"
jobs:
analyze:
@@ -21,45 +21,44 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'python', 'javascript' ]
language: ["python", "javascript"]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
+44 -30
View File
@@ -1,28 +1,53 @@
name: Create Sync Action
name: Create PR on Sync
on:
workflow_dispatch:
push:
branches:
- preview
- "sync/**"
env:
SOURCE_BRANCH_NAME: ${{ github.ref_name }}
CURRENT_BRANCH: ${{ github.ref_name }}
SOURCE_BRANCH: ${{ vars.SYNC_SOURCE_BRANCH_NAME }} # The sync branch such as "sync/ce"
TARGET_BRANCH: ${{ vars.SYNC_TARGET_BRANCH_NAME }} # The target branch that you would like to merge changes like develop
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} # Personal access token required to modify contents and workflows
REVIEWER: ${{ vars.SYNC_PR_REVIEWER }}
ACCOUNT_USER_NAME: ${{ vars.ACCOUNT_USER_NAME }}
ACCOUNT_USER_EMAIL: ${{ vars.ACCOUNT_USER_EMAIL }}
jobs:
sync_changes:
Check_Branch:
runs-on: ubuntu-latest
outputs:
BRANCH_MATCH: ${{ steps.check-branch.outputs.MATCH }}
steps:
- name: Check if current branch matches the secret
id: check-branch
run: |
if [ "$CURRENT_BRANCH" = "$SOURCE_BRANCH" ]; then
echo "MATCH=true" >> $GITHUB_OUTPUT
else
echo "MATCH=false" >> $GITHUB_OUTPUT
fi
Auto_Merge:
if: ${{ needs.Check_Branch.outputs.BRANCH_MATCH == 'true' }}
needs: [Check_Branch]
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
contents: write
steps:
- name: Checkout Code
- name: Checkout code
uses: actions/checkout@v4.1.1
with:
persist-credentials: false
fetch-depth: 0
fetch-depth: 0 # Fetch all history for all branches and tags
- name: Setup GH CLI
- name: Setup Git
run: |
git config user.name "$ACCOUNT_USER_NAME"
git config user.email "$ACCOUNT_USER_EMAIL"
- name: Setup GH CLI and Git Config
run: |
type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
@@ -31,25 +56,14 @@ jobs:
sudo apt update
sudo apt install gh -y
- name: Push Changes to Target Repo A
env:
GH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
- name: Create PR to Target Branch
run: |
TARGET_REPO="${{ secrets.TARGET_REPO_A }}"
TARGET_BRANCH="${{ secrets.TARGET_REPO_A_BRANCH_NAME }}"
SOURCE_BRANCH="${{ env.SOURCE_BRANCH_NAME }}"
git checkout $SOURCE_BRANCH
git remote add target-origin-a "https://$GH_TOKEN@github.com/$TARGET_REPO.git"
git push target-origin-a $SOURCE_BRANCH:$TARGET_BRANCH
- name: Push Changes to Target Repo B
env:
GH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
TARGET_REPO="${{ secrets.TARGET_REPO_B }}"
TARGET_BRANCH="${{ secrets.TARGET_REPO_B_BRANCH_NAME }}"
SOURCE_BRANCH="${{ env.SOURCE_BRANCH_NAME }}"
git remote add target-origin-b "https://$GH_TOKEN@github.com/$TARGET_REPO.git"
git push target-origin-b $SOURCE_BRANCH:$TARGET_BRANCH
# get all pull requests and check if there is already a PR
PR_EXISTS=$(gh pr list --base $TARGET_BRANCH --head $SOURCE_BRANCH --state open --json number | jq '.[] | .number')
if [ -n "$PR_EXISTS" ]; then
echo "Pull Request already exists: $PR_EXISTS"
else
echo "Creating new pull request"
PR_URL=$(gh pr create --base $TARGET_BRANCH --head $SOURCE_BRANCH --title "sync: community changes" --body "")
echo "Pull Request created: $PR_URL"
fi
+224 -31
View File
@@ -4,70 +4,263 @@ on:
workflow_dispatch:
inputs:
web-build:
required: true
required: false
description: "Build Web"
type: boolean
default: true
space-build:
required: true
required: false
description: "Build Space"
type: boolean
default: false
admin-build:
required: false
description: "Build Admin"
type: boolean
default: false
env:
BUILD_WEB: ${{ github.event.inputs.web-build }}
BUILD_SPACE: ${{ github.event.inputs.space-build }}
BUILD_ADMIN: ${{ github.event.inputs.admin-build }}
jobs:
setup-feature-build:
name: Feature Build Setup
runs-on: ubuntu-latest
steps:
- name: Checkout
run: |
echo "BUILD_WEB=$BUILD_WEB"
echo "BUILD_SPACE=$BUILD_SPACE"
echo "BUILD_ADMIN=$BUILD_ADMIN"
outputs:
web-build: ${{ env.BUILD_WEB}}
space-build: ${{env.BUILD_SPACE}}
admin-build: ${{env.BUILD_ADMIN}}
feature-build-web:
if: ${{ needs.setup-feature-build.outputs.web-build == 'true' }}
needs: setup-feature-build
name: Feature Build Web
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ vars.FEATURE_PREVIEW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FEATURE_PREVIEW_AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET: ${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}
NEXT_PUBLIC_API_BASE_URL: ${{ vars.FEATURE_PREVIEW_NEXT_PUBLIC_API_BASE_URL }}
steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install AWS cli
run: |
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 install awscli
- name: Checkout
uses: actions/checkout@v4
with:
path: plane
- name: Install Dependencies
run: |
cd $GITHUB_WORKSPACE/plane
yarn install
- name: Build Web
id: build-web
run: |
cd $GITHUB_WORKSPACE/plane
yarn build --filter=web
cd $GITHUB_WORKSPACE
TAR_NAME="web.tar.gz"
tar -czf $TAR_NAME ./plane
FILE_EXPIRY=$(date -u -d "+2 days" +"%Y-%m-%dT%H:%M:%SZ")
aws s3 cp $TAR_NAME s3://${{ env.AWS_BUCKET }}/${{github.sha}}/$TAR_NAME --expires $FILE_EXPIRY
feature-build-space:
if: ${{ needs.setup-feature-build.outputs.space-build == 'true' }}
needs: setup-feature-build
name: Feature Build Space
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ vars.FEATURE_PREVIEW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FEATURE_PREVIEW_AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET: ${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}
NEXT_PUBLIC_SPACE_BASE_PATH: "/spaces"
NEXT_PUBLIC_API_BASE_URL: ${{ vars.FEATURE_PREVIEW_NEXT_PUBLIC_API_BASE_URL }}
outputs:
do-build: ${{ needs.setup-feature-build.outputs.space-build }}
s3-url: ${{ steps.build-space.outputs.S3_PRESIGNED_URL }}
steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install AWS cli
run: |
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 install awscli
- name: Checkout
uses: actions/checkout@v4
with:
path: plane
- name: Install Dependencies
run: |
cd $GITHUB_WORKSPACE/plane
yarn install
- name: Build Space
id: build-space
run: |
cd $GITHUB_WORKSPACE/plane
yarn build --filter=space
cd $GITHUB_WORKSPACE
TAR_NAME="space.tar.gz"
tar -czf $TAR_NAME ./plane
FILE_EXPIRY=$(date -u -d "+2 days" +"%Y-%m-%dT%H:%M:%SZ")
aws s3 cp $TAR_NAME s3://${{ env.AWS_BUCKET }}/${{github.sha}}/$TAR_NAME --expires $FILE_EXPIRY
feature-build-admin:
if: ${{ needs.setup-feature-build.outputs.admin-build == 'true' }}
needs: setup-feature-build
name: Feature Build Admin
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ vars.FEATURE_PREVIEW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FEATURE_PREVIEW_AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET: ${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}
NEXT_PUBLIC_ADMIN_BASE_PATH: "/god-mode"
NEXT_PUBLIC_API_BASE_URL: ${{ vars.FEATURE_PREVIEW_NEXT_PUBLIC_API_BASE_URL }}
outputs:
do-build: ${{ needs.setup-feature-build.outputs.admin-build }}
s3-url: ${{ steps.build-admin.outputs.S3_PRESIGNED_URL }}
steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install AWS cli
run: |
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 install awscli
- name: Checkout
uses: actions/checkout@v4
with:
path: plane
- name: Install Dependencies
run: |
cd $GITHUB_WORKSPACE/plane
yarn install
- name: Build Admin
id: build-admin
run: |
cd $GITHUB_WORKSPACE/plane
yarn build --filter=admin
cd $GITHUB_WORKSPACE
TAR_NAME="admin.tar.gz"
tar -czf $TAR_NAME ./plane
FILE_EXPIRY=$(date -u -d "+2 days" +"%Y-%m-%dT%H:%M:%SZ")
aws s3 cp $TAR_NAME s3://${{ env.AWS_BUCKET }}/${{github.sha}}/$TAR_NAME --expires $FILE_EXPIRY
feature-deploy:
if: ${{ always() && (needs.setup-feature-build.outputs.web-build == 'true' || needs.setup-feature-build.outputs.space-build == 'true' || needs.setup-feature-build.outputs.admin-build == 'true') }}
needs:
[
setup-feature-build,
feature-build-web,
feature-build-space,
feature-build-admin,
]
name: Feature Deploy
runs-on: ubuntu-latest
env:
KUBE_CONFIG_FILE: ${{ secrets.KUBE_CONFIG }}
BUILD_WEB: ${{ (github.event.inputs.web-build == '' && true) || github.event.inputs.web-build }}
BUILD_SPACE: ${{ (github.event.inputs.space-build == '' && false) || github.event.inputs.space-build }}
AWS_ACCESS_KEY_ID: ${{ vars.FEATURE_PREVIEW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FEATURE_PREVIEW_AWS_SECRET_ACCESS_KEY }}
AWS_BUCKET: ${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}
KUBE_CONFIG_FILE: ${{ secrets.FEATURE_PREVIEW_KUBE_CONFIG }}
steps:
- name: Install AWS cli
run: |
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 install awscli
- name: Tailscale
uses: tailscale/github-action@v2
with:
oauth-client-id: ${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TAILSCALE_OAUTH_SECRET }}
tags: tag:ci
- name: Kubectl Setup
run: |
curl -LO "https://dl.k8s.io/release/${{secrets.KUBE_VERSION}}/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/${{ vars.FEATURE_PREVIEW_KUBE_VERSION }}/bin/linux/amd64/kubectl"
chmod +x kubectl
mkdir -p ~/.kube
echo "$KUBE_CONFIG_FILE" > ~/.kube/config
chmod 600 ~/.kube/config
- name: HELM Setup
run: |
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
- name: App Deploy
run: |
helm --kube-insecure-skip-tls-verify repo add feature-preview ${{ secrets.FEATURE_PREVIEW_HELM_CHART_URL }}
GIT_BRANCH=${{ github.ref_name }}
APP_NAMESPACE=${{ secrets.FEATURE_PREVIEW_NAMESPACE }}
WEB_S3_URL=""
if [ ${{ env.BUILD_WEB }} == true ]; then
WEB_S3_URL=$(aws s3 presign s3://${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}/${{github.sha}}/web.tar.gz --expires-in 3600)
fi
METADATA=$(helm install feature-preview/${{ secrets.FEATURE_PREVIEW_HELM_CHART_NAME }} \
--kube-insecure-skip-tls-verify \
--generate-name \
--namespace $APP_NAMESPACE \
--set shared_config.git_repo=${{github.server_url}}/${{ github.repository }}.git \
--set shared_config.git_branch="$GIT_BRANCH" \
--set web.enabled=${{ env.BUILD_WEB }} \
--set space.enabled=${{ env.BUILD_SPACE }} \
--output json \
--timeout 1000s)
SPACE_S3_URL=""
if [ ${{ env.BUILD_SPACE }} == true ]; then
SPACE_S3_URL=$(aws s3 presign s3://${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}/${{github.sha}}/space.tar.gz --expires-in 3600)
fi
APP_NAME=$(echo $METADATA | jq -r '.name')
ADMIN_S3_URL=""
if [ ${{ env.BUILD_ADMIN }} == true ]; then
ADMIN_S3_URL=$(aws s3 presign s3://${{ vars.FEATURE_PREVIEW_AWS_BUCKET }}/${{github.sha}}/admin.tar.gz --expires-in 3600)
fi
INGRESS_HOSTNAME=$(kubectl get ingress -n feature-builds --insecure-skip-tls-verify \
-o jsonpath='{.items[?(@.metadata.annotations.meta\.helm\.sh\/release-name=="'$APP_NAME'")]}' | \
jq -r '.spec.rules[0].host')
if [ ${{ env.BUILD_WEB }} == true ] || [ ${{ env.BUILD_SPACE }} == true ] || [ ${{ env.BUILD_ADMIN }} == true ]; then
echo "****************************************"
echo "APP NAME ::: $APP_NAME"
echo "INGRESS HOSTNAME ::: $INGRESS_HOSTNAME"
echo "****************************************"
helm --kube-insecure-skip-tls-verify repo add feature-preview ${{ vars.FEATURE_PREVIEW_HELM_CHART_URL }}
APP_NAMESPACE="${{ vars.FEATURE_PREVIEW_NAMESPACE }}"
DEPLOY_SCRIPT_URL="${{ vars.FEATURE_PREVIEW_DEPLOY_SCRIPT_URL }}"
METADATA=$(helm --kube-insecure-skip-tls-verify install feature-preview/${{ vars.FEATURE_PREVIEW_HELM_CHART_NAME }} \
--generate-name \
--namespace $APP_NAMESPACE \
--set ingress.primaryDomain=${{vars.FEATURE_PREVIEW_PRIMARY_DOMAIN || 'feature.plane.tools' }} \
--set web.image=${{vars.FEATURE_PREVIEW_DOCKER_BASE}} \
--set web.enabled=${{ env.BUILD_WEB || false }} \
--set web.artifact_url=$WEB_S3_URL \
--set space.image=${{vars.FEATURE_PREVIEW_DOCKER_BASE}} \
--set space.enabled=${{ env.BUILD_SPACE || false }} \
--set space.artifact_url=$SPACE_S3_URL \
--set admin.image=${{vars.FEATURE_PREVIEW_DOCKER_BASE}} \
--set admin.enabled=${{ env.BUILD_ADMIN || false }} \
--set admin.artifact_url=$ADMIN_S3_URL \
--set shared_config.deploy_script_url=$DEPLOY_SCRIPT_URL \
--set shared_config.api_base_url=${{vars.FEATURE_PREVIEW_NEXT_PUBLIC_API_BASE_URL}} \
--output json \
--timeout 1000s)
APP_NAME=$(echo $METADATA | jq -r '.name')
INGRESS_HOSTNAME=$(kubectl get ingress -n feature-builds --insecure-skip-tls-verify \
-o jsonpath='{.items[?(@.metadata.annotations.meta\.helm\.sh\/release-name=="'$APP_NAME'")]}' | \
jq -r '.spec.rules[0].host')
echo "****************************************"
echo "APP NAME ::: $APP_NAME"
echo "INGRESS HOSTNAME ::: $INGRESS_HOSTNAME"
echo "****************************************"
fi
+44
View File
@@ -0,0 +1,44 @@
name: Sync Repositories
on:
workflow_dispatch:
push:
branches:
- preview
env:
SOURCE_BRANCH_NAME: ${{ github.ref_name }}
jobs:
sync_changes:
runs-on: ubuntu-20.04
permissions:
pull-requests: write
contents: read
steps:
- name: Checkout Code
uses: actions/checkout@v4.1.1
with:
persist-credentials: false
fetch-depth: 0
- name: Setup GH CLI
run: |
type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh -y
- name: Push Changes to Target Repo
env:
GH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
TARGET_REPO="${{ vars.SYNC_TARGET_REPO }}"
TARGET_BRANCH="${{ vars.SYNC_TARGET_BRANCH_NAME }}"
SOURCE_BRANCH="${{ env.SOURCE_BRANCH_NAME }}"
git checkout $SOURCE_BRANCH
git remote add target-origin-a "https://$GH_TOKEN@github.com/$TARGET_REPO.git"
git push target-origin-a $SOURCE_BRANCH:$TARGET_BRANCH
+5
View File
@@ -51,6 +51,7 @@ staticfiles
mediafiles
.env
.DS_Store
logs/
node_modules/
assets/dist/
@@ -80,3 +81,7 @@ tmp/
## packages
dist
.temp/
deploy/selfhost/plane-app/
## Storybook
*storybook.log
output.css
View File
+3
View File
@@ -0,0 +1,3 @@
{
"*.{ts,tsx,js,jsx}": ["eslint -c ./.eslintrc-staged.js", "prettier --check"]
}
+6 -11
View File
@@ -27,7 +27,7 @@ RUN yarn install
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json
COPY replace-env-vars.sh /usr/local/bin/
USER root
RUN chmod +x /usr/local/bin/replace-env-vars.sh
RUN yarn turbo run build
@@ -82,28 +82,24 @@ COPY apiserver/templates templates/
RUN apk --no-cache add "bash~=5.2"
COPY apiserver/bin ./bin/
RUN chmod +x ./bin/takeoff ./bin/worker
RUN chmod +x ./bin/*
RUN chmod -R 777 /code
# Expose container port and run entry point script
WORKDIR /app
# Don't run production as root
RUN addgroup --system --gid 1001 plane
RUN adduser --system --uid 1001 captain
COPY --from=installer /app/apps/app/next.config.js .
COPY --from=installer /app/apps/app/package.json .
COPY --from=installer /app/apps/space/next.config.js .
COPY --from=installer /app/apps/space/package.json .
COPY --from=installer --chown=captain:plane /app/apps/app/.next/standalone ./
COPY --from=installer /app/apps/app/.next/standalone ./
COPY --from=installer --chown=captain:plane /app/apps/app/.next/static ./apps/app/.next/static
COPY --from=installer /app/apps/app/.next/static ./apps/app/.next/static
COPY --from=installer --chown=captain:plane /app/apps/space/.next/standalone ./
COPY --from=installer --chown=captain:plane /app/apps/space/.next ./apps/space/.next
COPY --from=installer /app/apps/space/.next/standalone ./
COPY --from=installer /app/apps/space/.next ./apps/space/.next
ENV NEXT_TELEMETRY_DISABLED 1
@@ -118,7 +114,6 @@ ARG NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL \
BUILT_NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
USER root
COPY replace-env-vars.sh /usr/local/bin/
COPY start.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/replace-env-vars.sh
+16 -16
View File
@@ -7,7 +7,7 @@
</p>
<h3 align="center"><b>Plane</b></h3>
<p align="center"><b>Open-source project management that unlocks customer value.</b></p>
<p align="center"><b>Open-source project management that unlocks customer value</b></p>
<p align="center">
<a href="https://discord.com/invite/A92xrEGCge">
@@ -17,10 +17,10 @@
</p>
<p align="center">
<a href="http://www.plane.so"><b>Website</b></a> •
<a href="https://github.com/makeplane/plane/releases"><b>Releases</b></a> •
<a href="https://twitter.com/planepowers"><b>Twitter</b></a> •
<a href="https://docs.plane.so/"><b>Documentation</b></a>
<a href="https://dub.sh/plane-website-readme"><b>Website</b></a> •
<a href="https://git.new/releases"><b>Releases</b></a> •
<a href="https://dub.sh/planepowershq"><b>Twitter</b></a> •
<a href="https://dub.sh/planedocs"><b>Documentation</b></a>
</p>
<p>
@@ -40,28 +40,28 @@
</a>
</p>
Meet [Plane](https://plane.so). An open-source software development tool to manage issues, sprints, and product roadmaps with peace of mind. 🧘‍♀️
Meet [Plane](https://dub.sh/plane-website-readme), an open-source project management tool to track issues, run ~sprints~ cycles, and manage product roadmaps without the chaos of managing the tool itself. 🧘‍♀️
> Plane is still in its early days, not everything will be perfect yet, and hiccups may happen. Please let us know of any suggestions, ideas, or bugs that you encounter on our [Discord](https://discord.com/invite/A92xrEGCge) or GitHub issues, and we will use your feedback to improve on our upcoming releases.
> Plane is evolving every day. Your suggestions, ideas, and reported bugs help us immensely. Do not hesitate to join in the conversation on [Discord](https://discord.com/invite/A92xrEGCge) or raise a GitHub issue. We read everything and respond to most.
## ⚡ Installation
The easiest way to get started with Plane is by creating a [Plane Cloud](https://app.plane.so) account where we offer a hosted solution for users.
The easiest way to get started with Plane is by creating a [Plane Cloud](https://app.plane.so) account.
If you want more control over your data prefer to self-host Plane, please refer to our [deployment documentation](https://docs.plane.so/docker-compose).
If you would like to self-host Plane, please see our [deployment guide](https://docs.plane.so/docker-compose).
| Installation Methods | Documentation Link |
| Installation methods | Docs link |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Docker | [![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white)](https://docs.plane.so/docker-compose) |
| Docker | [![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white)](https://docs.plane.so/self-hosting/methods/docker-compose) |
| Kubernetes | [![Kubernetes](https://img.shields.io/badge/kubernetes-%23326ce5.svg?style=for-the-badge&logo=kubernetes&logoColor=white)](https://docs.plane.so/kubernetes) |
`Instance admin` can configure instance settings using our [God-mode](https://docs.plane.so/instance-admin) feature.
`Instance admins` can configure instance settings with [God-mode](https://docs.plane.so/instance-admin).
## 🚀 Features
- **Issues**: Quickly create issues and add details using a powerful, rich text editor that supports file uploads. Add sub-properties and references to problems for better organization and tracking.
- **Issues**: Quickly create issues and add details using a powerful rich text editor that supports file uploads. Add sub-properties and references to problems for better organization and tracking.
- **Cycles**
- **Cycles**:
Keep up your team's momentum with Cycles. Gain insights into your project's progress with burn-down charts and other valuable features.
- **Modules**: Break down your large projects into smaller, more manageable modules. Assign modules between teams to track and plan your project's progress easily.
@@ -74,11 +74,11 @@ If you want more control over your data prefer to self-host Plane, please refer
- **Drive** (_coming soon_): The drive helps you share documents, images, videos, or any other files that make sense to you or your team and align on the problem/solution.
## 🛠️ Contributors Quick Start
## 🛠️ Quick start for contributors
> Development system must have docker engine installed and running.
Setting up local environment is extremely easy and straight forward. Follow the below step and you will be ready to contribute
Setting up local environment is extremely easy and straight forward. Follow the below step and you will be ready to contribute -
1. Clone the code locally using:
```
+44
View File
@@ -0,0 +1,44 @@
# Security Policy
This document outlines security procedures and vulnerabilities reporting for the Plane project.
At Plane, we safeguarding the security of our systems with top priority. Despite our efforts, vulnerabilities may still exist. We greatly appreciate your assistance in identifying and reporting any such vulnerabilities to help us maintain the integrity of our systems and protect our clients.
To report a security vulnerability, please email us directly at security@plane.so with a detailed description of the vulnerability and steps to reproduce it. Please refrain from disclosing the vulnerability publicly until we have had an opportunity to review and address it.
## Out of Scope Vulnerabilities
We appreciate your help in identifying vulnerabilities. However, please note that the following types of vulnerabilities are considered out of scope:
- Attacks requiring MITM or physical access to a user's device.
- Content spoofing and text injection issues without demonstrating an attack vector or ability to modify HTML/CSS.
- Email spoofing.
- Missing DNSSEC, CAA, CSP headers.
- Lack of Secure or HTTP only flag on non-sensitive cookies.
## Reporting Process
If you discover a vulnerability, please adhere to the following reporting process:
1. Email your findings to security@plane.so.
2. Refrain from running automated scanners on our infrastructure or dashboard without prior consent. Contact us to set up a sandbox environment if necessary.
3. Do not exploit the vulnerability for malicious purposes, such as downloading excessive data or altering user data.
4. Maintain confidentiality and refrain from disclosing the vulnerability until it has been resolved.
5. Avoid using physical security attacks, social engineering, distributed denial of service, spam, or third-party applications.
When reporting a vulnerability, please provide sufficient information to allow us to reproduce and address the issue promptly. Include the IP address or URL of the affected system, along with a detailed description of the vulnerability.
## Our Commitment
We are committed to promptly addressing reported vulnerabilities and maintaining open communication throughout the resolution process. Here's what you can expect from us:
- **Response Time:** We will acknowledge receipt of your report within three business days and provide an expected resolution date.
- **Legal Protection:** We will not pursue legal action against you for reporting vulnerabilities, provided you adhere to the reporting guidelines.
- **Confidentiality:** Your report will be treated with strict confidentiality. We will not disclose your personal information to third parties without your consent.
- **Progress Updates:** We will keep you informed of our progress in resolving the reported vulnerability.
- **Recognition:** With your permission, we will publicly acknowledge you as the discoverer of the vulnerability.
- **Timely Resolution:** We strive to resolve all reported vulnerabilities promptly and will actively participate in the publication process once the issue is resolved.
We appreciate your cooperation in helping us maintain the security of our systems and protecting our clients. Thank you for your contributions to our security efforts.
reference: https://supabase.com/.well-known/security.txt
+3
View File
@@ -0,0 +1,3 @@
NEXT_PUBLIC_API_BASE_URL=""
NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode"
NEXT_PUBLIC_WEB_BASE_URL=""
+52
View File
@@ -0,0 +1,52 @@
module.exports = {
root: true,
extends: ["custom"],
parser: "@typescript-eslint/parser",
settings: {
"import/resolver": {
typescript: {},
node: {
moduleDirectory: ["node_modules", "."],
},
},
},
rules: {
"import/order": [
"error",
{
groups: ["builtin", "external", "internal", "parent", "sibling",],
pathGroups: [
{
pattern: "react",
group: "external",
position: "before",
},
{
pattern: "lucide-react",
group: "external",
position: "after",
},
{
pattern: "@headlessui/**",
group: "external",
position: "after",
},
{
pattern: "@plane/**",
group: "external",
position: "after",
},
{
pattern: "@/**",
group: "internal",
}
],
pathGroupsExcludedImportTypes: ["builtin", "internal", "react"],
alphabetize: {
order: "asc",
caseInsensitive: true,
},
},
],
},
}
+6
View File
@@ -0,0 +1,6 @@
.next
.vercel
.tubro
out/
dis/
build/
+5
View File
@@ -0,0 +1,5 @@
{
"printWidth": 120,
"tabWidth": 2,
"trailingComma": "es5"
}
+86
View File
@@ -0,0 +1,86 @@
# *****************************************************************************
# STAGE 1: Build the project
# *****************************************************************************
FROM node:18-alpine AS builder
RUN apk add --no-cache libc6-compat
WORKDIR /app
RUN yarn global add turbo
COPY . .
RUN turbo prune --scope=admin --docker
# *****************************************************************************
# STAGE 2: Install dependencies & build the project
# *****************************************************************************
FROM node:18-alpine AS installer
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/yarn.lock ./yarn.lock
RUN yarn install --network-timeout 500000
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json
ARG NEXT_PUBLIC_API_BASE_URL=""
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
ARG NEXT_PUBLIC_ADMIN_BASE_URL=""
ENV NEXT_PUBLIC_ADMIN_BASE_URL=$NEXT_PUBLIC_ADMIN_BASE_URL
ARG NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode"
ENV NEXT_PUBLIC_ADMIN_BASE_PATH=$NEXT_PUBLIC_ADMIN_BASE_PATH
ARG NEXT_PUBLIC_SPACE_BASE_URL=""
ENV NEXT_PUBLIC_SPACE_BASE_URL=$NEXT_PUBLIC_SPACE_BASE_URL
ARG NEXT_PUBLIC_SPACE_BASE_PATH="/spaces"
ENV NEXT_PUBLIC_SPACE_BASE_PATH=$NEXT_PUBLIC_SPACE_BASE_PATH
ARG NEXT_PUBLIC_WEB_BASE_URL=""
ENV NEXT_PUBLIC_WEB_BASE_URL=$NEXT_PUBLIC_WEB_BASE_URL
ENV NEXT_TELEMETRY_DISABLED 1
ENV TURBO_TELEMETRY_DISABLED 1
RUN yarn turbo run build --filter=admin
# *****************************************************************************
# STAGE 3: Copy the project and start it
# *****************************************************************************
FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=installer /app/admin/next.config.js .
COPY --from=installer /app/admin/package.json .
COPY --from=installer /app/admin/.next/standalone ./
COPY --from=installer /app/admin/.next/static ./admin/.next/static
COPY --from=installer /app/admin/public ./admin/public
ARG NEXT_PUBLIC_API_BASE_URL=""
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
ARG NEXT_PUBLIC_ADMIN_BASE_URL=""
ENV NEXT_PUBLIC_ADMIN_BASE_URL=$NEXT_PUBLIC_ADMIN_BASE_URL
ARG NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode"
ENV NEXT_PUBLIC_ADMIN_BASE_PATH=$NEXT_PUBLIC_ADMIN_BASE_PATH
ARG NEXT_PUBLIC_SPACE_BASE_URL=""
ENV NEXT_PUBLIC_SPACE_BASE_URL=$NEXT_PUBLIC_SPACE_BASE_URL
ARG NEXT_PUBLIC_SPACE_BASE_PATH="/spaces"
ENV NEXT_PUBLIC_SPACE_BASE_PATH=$NEXT_PUBLIC_SPACE_BASE_PATH
ARG NEXT_PUBLIC_WEB_BASE_URL=""
ENV NEXT_PUBLIC_WEB_BASE_URL=$NEXT_PUBLIC_WEB_BASE_URL
ENV NEXT_TELEMETRY_DISABLED 1
ENV TURBO_TELEMETRY_DISABLED 1
EXPOSE 3000
+17
View File
@@ -0,0 +1,17 @@
FROM node:18-alpine
RUN apk add --no-cache libc6-compat
# Set working directory
WORKDIR /app
COPY . .
RUN yarn global add turbo
RUN yarn install
ENV NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode"
EXPOSE 3000
VOLUME [ "/app/node_modules", "/app/admin/node_modules" ]
CMD ["yarn", "dev", "--filter=admin"]
+128
View File
@@ -0,0 +1,128 @@
import { FC } from "react";
import { useForm } from "react-hook-form";
import { Lightbulb } from "lucide-react";
import { IFormattedInstanceConfiguration, TInstanceAIConfigurationKeys } from "@plane/types";
import { Button, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ControllerInput, TControllerInputFormField } from "@/components/common";
// hooks
import { useInstance } from "@/hooks/store";
type IInstanceAIForm = {
config: IFormattedInstanceConfiguration;
};
type AIFormValues = Record<TInstanceAIConfigurationKeys, string>;
export const InstanceAIForm: FC<IInstanceAIForm> = (props) => {
const { config } = props;
// store
const { updateInstanceConfigurations } = useInstance();
// form data
const {
handleSubmit,
control,
formState: { errors, isSubmitting },
} = useForm<AIFormValues>({
defaultValues: {
OPENAI_API_KEY: config["OPENAI_API_KEY"],
GPT_ENGINE: config["GPT_ENGINE"],
},
});
const aiFormFields: TControllerInputFormField[] = [
{
key: "GPT_ENGINE",
type: "text",
label: "GPT_ENGINE",
description: (
<>
Choose an OpenAI engine.{" "}
<a
href="https://platform.openai.com/docs/models/overview"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
Learn more
</a>
</>
),
placeholder: "gpt-3.5-turbo",
error: Boolean(errors.GPT_ENGINE),
required: false,
},
{
key: "OPENAI_API_KEY",
type: "password",
label: "API key",
description: (
<>
You will find your API key{" "}
<a
href="https://platform.openai.com/api-keys"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
here.
</a>
</>
),
placeholder: "sk-asddassdfasdefqsdfasd23das3dasdcasd",
error: Boolean(errors.OPENAI_API_KEY),
required: false,
},
];
const onSubmit = async (formData: AIFormValues) => {
const payload: Partial<AIFormValues> = { ...formData };
await updateInstanceConfigurations(payload)
.then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "AI Settings updated successfully",
})
)
.catch((err) => console.error(err));
};
return (
<div className="space-y-8">
<div className="space-y-3">
<div>
<div className="pb-1 text-xl font-medium text-custom-text-100">OpenAI</div>
<div className="text-sm font-normal text-custom-text-300">If you use ChatGPT, this is for you.</div>
</div>
<div className="grid-col grid w-full grid-cols-1 items-center justify-between gap-x-12 gap-y-8 lg:grid-cols-3">
{aiFormFields.map((field) => (
<ControllerInput
key={field.key}
control={control}
type={field.type}
name={field.key}
label={field.label}
description={field.description}
placeholder={field.placeholder}
error={field.error}
required={field.required}
/>
))}
</div>
</div>
<div className="space-y-4">
<Button variant="primary" onClick={handleSubmit(onSubmit)} loading={isSubmitting}>
{isSubmitting ? "Saving..." : "Save changes"}
</Button>
<div className="relative inline-flex items-center gap-2 rounded border border-custom-primary-100/20 bg-custom-primary-100/10 px-4 py-2 text-xs text-custom-primary-200">
<Lightbulb height="14" width="14" />
<div>If you have a preferred AI models vendor, please get in touch with us.</div>
</div>
</div>
</div>
);
};
+11
View File
@@ -0,0 +1,11 @@
import { ReactNode } from "react";
import { Metadata } from "next";
import { AdminLayout } from "@/layouts/admin-layout";
export const metadata: Metadata = {
title: "AI Settings - God Mode",
};
export default function AILayout({ children }: { children: ReactNode }) {
return <AdminLayout>{children}</AdminLayout>;
}
+48
View File
@@ -0,0 +1,48 @@
"use client";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import { Loader } from "@plane/ui";
// components
import { PageHeader } from "@/components/core";
// hooks
import { useInstance } from "@/hooks/store";
// components
import { InstanceAIForm } from "./form";
const InstanceAIPage = observer(() => {
// store
const { fetchInstanceConfigurations, formattedConfig } = useInstance();
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
return (
<>
<PageHeader title="Artificial Intelligence - God Mode" />
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<div className="text-xl font-medium text-custom-text-100">AI features for all your workspaces</div>
<div className="text-sm font-normal text-custom-text-300">
Configure your AI API credentials so Plane AI features are turned on for all your workspaces.
</div>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{formattedConfig ? (
<InstanceAIForm config={formattedConfig} />
) : (
<Loader className="space-y-8">
<Loader.Item height="50px" width="40%" />
<div className="w-2/3 grid grid-cols-2 gap-x-8 gap-y-4">
<Loader.Item height="50px" />
<Loader.Item height="50px" />
</div>
<Loader.Item height="50px" width="20%" />
</Loader>
)}
</div>
</div>
</>
);
});
export default InstanceAIPage;
@@ -0,0 +1,51 @@
"use client";
import { FC } from "react";
// helpers
import { cn } from "helpers/common.helper";
type Props = {
name: string;
description: string;
icon: JSX.Element;
config: JSX.Element;
disabled?: boolean;
withBorder?: boolean;
};
export const AuthenticationMethodCard: FC<Props> = (props) => {
const { name, description, icon, config, disabled = false, withBorder = true } = props;
return (
<div
className={cn("w-full flex items-center gap-14 rounded", {
"px-4 py-3 border border-custom-border-200": withBorder,
})}
>
<div className="flex grow items-center gap-4">
<div className="shrink-0">
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-custom-background-80">{icon}</div>
</div>
<div className="grow">
<div
className={cn("font-medium leading-5 text-custom-text-100", {
"text-sm": withBorder,
"text-xl": !withBorder,
})}
>
{name}
</div>
<div
className={cn("font-normal leading-5 text-custom-text-300", {
"text-xs": withBorder,
"text-sm": !withBorder,
})}
>
{description}
</div>
</div>
</div>
<div className={`shrink-0 ${disabled && "opacity-70"}`}>{config}</div>
</div>
);
};
@@ -0,0 +1,36 @@
"use client";
import React from "react";
import { observer } from "mobx-react-lite";
// hooks
import { TInstanceAuthenticationMethodKeys } from "@plane/types";
import { ToggleSwitch } from "@plane/ui";
import { useInstance } from "@/hooks/store";
// ui
// types
type Props = {
disabled: boolean;
updateConfig: (key: TInstanceAuthenticationMethodKeys, value: string) => void;
};
export const EmailCodesConfiguration: React.FC<Props> = observer((props) => {
const { disabled, updateConfig } = props;
// store
const { formattedConfig } = useInstance();
// derived values
const enableMagicLogin = formattedConfig?.ENABLE_MAGIC_LINK_LOGIN ?? "";
return (
<ToggleSwitch
value={Boolean(parseInt(enableMagicLogin))}
onChange={() => {
Boolean(parseInt(enableMagicLogin)) === true
? updateConfig("ENABLE_MAGIC_LINK_LOGIN", "0")
: updateConfig("ENABLE_MAGIC_LINK_LOGIN", "1");
}}
size="sm"
disabled={disabled}
/>
);
});
@@ -0,0 +1,59 @@
"use client";
import React from "react";
import { observer } from "mobx-react-lite";
import Link from "next/link";
// icons
import { Settings2 } from "lucide-react";
// types
import { TInstanceAuthenticationMethodKeys } from "@plane/types";
// ui
import { ToggleSwitch, getButtonStyling } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useInstance } from "@/hooks/store";
type Props = {
disabled: boolean;
updateConfig: (key: TInstanceAuthenticationMethodKeys, value: string) => void;
};
export const GithubConfiguration: React.FC<Props> = observer((props) => {
const { disabled, updateConfig } = props;
// store
const { formattedConfig } = useInstance();
// derived values
const enableGithubConfig = formattedConfig?.IS_GITHUB_ENABLED ?? "";
const isGithubConfigured = !!formattedConfig?.GITHUB_CLIENT_ID && !!formattedConfig?.GITHUB_CLIENT_SECRET;
return (
<>
{isGithubConfigured ? (
<div className="flex items-center gap-4">
<Link href="/authentication/github" className={cn(getButtonStyling("link-primary", "md"), "font-medium")}>
Edit
</Link>
<ToggleSwitch
value={Boolean(parseInt(enableGithubConfig))}
onChange={() => {
Boolean(parseInt(enableGithubConfig)) === true
? updateConfig("IS_GITHUB_ENABLED", "0")
: updateConfig("IS_GITHUB_ENABLED", "1");
}}
size="sm"
disabled={disabled}
/>
</div>
) : (
<Link
href="/authentication/github"
className={cn(getButtonStyling("neutral-primary", "sm"), "text-custom-text-300")}
>
<Settings2 className="h-4 w-4 p-0.5 text-custom-text-300/80" />
Configure
</Link>
)}
</>
);
});
@@ -0,0 +1,59 @@
"use client";
import React from "react";
import { observer } from "mobx-react-lite";
import Link from "next/link";
// icons
import { Settings2 } from "lucide-react";
// types
import { TInstanceAuthenticationMethodKeys } from "@plane/types";
// ui
import { ToggleSwitch, getButtonStyling } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useInstance } from "@/hooks/store";
type Props = {
disabled: boolean;
updateConfig: (key: TInstanceAuthenticationMethodKeys, value: string) => void;
};
export const GoogleConfiguration: React.FC<Props> = observer((props) => {
const { disabled, updateConfig } = props;
// store
const { formattedConfig } = useInstance();
// derived values
const enableGoogleConfig = formattedConfig?.IS_GOOGLE_ENABLED ?? "";
const isGoogleConfigured = !!formattedConfig?.GOOGLE_CLIENT_ID && !!formattedConfig?.GOOGLE_CLIENT_SECRET;
return (
<>
{isGoogleConfigured ? (
<div className="flex items-center gap-4">
<Link href="/authentication/google" className={cn(getButtonStyling("link-primary", "md"), "font-medium")}>
Edit
</Link>
<ToggleSwitch
value={Boolean(parseInt(enableGoogleConfig))}
onChange={() => {
Boolean(parseInt(enableGoogleConfig)) === true
? updateConfig("IS_GOOGLE_ENABLED", "0")
: updateConfig("IS_GOOGLE_ENABLED", "1");
}}
size="sm"
disabled={disabled}
/>
</div>
) : (
<Link
href="/authentication/google"
className={cn(getButtonStyling("neutral-primary", "sm"), "text-custom-text-300")}
>
<Settings2 className="h-4 w-4 p-0.5 text-custom-text-300/80" />
Configure
</Link>
)}
</>
);
});
@@ -0,0 +1,5 @@
export * from "./email-config-switch";
export * from "./password-config-switch";
export * from "./authentication-method-card";
export * from "./github-config";
export * from "./google-config";
@@ -0,0 +1,36 @@
"use client";
import React from "react";
import { observer } from "mobx-react-lite";
// hooks
import { TInstanceAuthenticationMethodKeys } from "@plane/types";
import { ToggleSwitch } from "@plane/ui";
import { useInstance } from "@/hooks/store";
// ui
// types
type Props = {
disabled: boolean;
updateConfig: (key: TInstanceAuthenticationMethodKeys, value: string) => void;
};
export const PasswordLoginConfiguration: React.FC<Props> = observer((props) => {
const { disabled, updateConfig } = props;
// store
const { formattedConfig } = useInstance();
// derived values
const enableEmailPassword = formattedConfig?.ENABLE_EMAIL_PASSWORD ?? "";
return (
<ToggleSwitch
value={Boolean(parseInt(enableEmailPassword))}
onChange={() => {
Boolean(parseInt(enableEmailPassword)) === true
? updateConfig("ENABLE_EMAIL_PASSWORD", "0")
: updateConfig("ENABLE_EMAIL_PASSWORD", "1");
}}
size="sm"
disabled={disabled}
/>
);
});
+213
View File
@@ -0,0 +1,213 @@
import { FC, useState } from "react";
import isEmpty from "lodash/isEmpty";
import Link from "next/link";
import { useForm } from "react-hook-form";
// types
import { IFormattedInstanceConfiguration, TInstanceGithubAuthenticationConfigurationKeys } from "@plane/types";
// ui
import { Button, TOAST_TYPE, getButtonStyling, setToast } from "@plane/ui";
// components
import {
ConfirmDiscardModal,
ControllerInput,
CopyField,
TControllerInputFormField,
TCopyField,
} from "@/components/common";
// helpers
import { API_BASE_URL, cn } from "@/helpers/common.helper";
// hooks
import { useInstance } from "@/hooks/store";
type Props = {
config: IFormattedInstanceConfiguration;
};
type GithubConfigFormValues = Record<TInstanceGithubAuthenticationConfigurationKeys, string>;
export const InstanceGithubConfigForm: FC<Props> = (props) => {
const { config } = props;
// states
const [isDiscardChangesModalOpen, setIsDiscardChangesModalOpen] = useState(false);
// store hooks
const { updateInstanceConfigurations } = useInstance();
// form data
const {
handleSubmit,
control,
reset,
formState: { errors, isDirty, isSubmitting },
} = useForm<GithubConfigFormValues>({
defaultValues: {
GITHUB_CLIENT_ID: config["GITHUB_CLIENT_ID"],
GITHUB_CLIENT_SECRET: config["GITHUB_CLIENT_SECRET"],
},
});
const originURL = !isEmpty(API_BASE_URL) ? API_BASE_URL : typeof window !== "undefined" ? window.location.origin : "";
const GITHUB_FORM_FIELDS: TControllerInputFormField[] = [
{
key: "GITHUB_CLIENT_ID",
type: "text",
label: "Client ID",
description: (
<>
You will get this from your{" "}
<a
tabIndex={-1}
href="https://github.com/settings/applications/new"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
GitHub OAuth application settings.
</a>
</>
),
placeholder: "70a44354520df8bd9bcd",
error: Boolean(errors.GITHUB_CLIENT_ID),
required: true,
},
{
key: "GITHUB_CLIENT_SECRET",
type: "password",
label: "Client secret",
description: (
<>
Your client secret is also found in your{" "}
<a
tabIndex={-1}
href="https://github.com/settings/applications/new"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
GitHub OAuth application settings.
</a>
</>
),
placeholder: "9b0050f94ec1b744e32ce79ea4ffacd40d4119cb",
error: Boolean(errors.GITHUB_CLIENT_SECRET),
required: true,
},
];
const GITHUB_SERVICE_FIELD: TCopyField[] = [
{
key: "Origin_URL",
label: "Origin URL",
url: originURL,
description: (
<>
We will auto-generate this. Paste this into the Authorized origin URL field{" "}
<a
tabIndex={-1}
href="https://github.com/settings/applications/new"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
here.
</a>
</>
),
},
{
key: "Callback_URI",
label: "Callback URI",
url: `${originURL}/auth/github/callback/`,
description: (
<>
We will auto-generate this. Paste this into your Authorized Callback URI field{" "}
<a
tabIndex={-1}
href="https://github.com/settings/applications/new"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
here.
</a>
</>
),
},
];
const onSubmit = async (formData: GithubConfigFormValues) => {
const payload: Partial<GithubConfigFormValues> = { ...formData };
await updateInstanceConfigurations(payload)
.then((response = []) => {
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "Github Configuration Settings updated successfully",
});
reset({
GITHUB_CLIENT_ID: response.find((item) => item.key === "GITHUB_CLIENT_ID")?.value,
GITHUB_CLIENT_SECRET: response.find((item) => item.key === "GITHUB_CLIENT_SECRET")?.value,
});
})
.catch((err) => console.error(err));
};
const handleGoBack = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
if (isDirty) {
e.preventDefault();
setIsDiscardChangesModalOpen(true);
}
};
return (
<>
<ConfirmDiscardModal
isOpen={isDiscardChangesModalOpen}
onDiscardHref="/authentication"
handleClose={() => setIsDiscardChangesModalOpen(false)}
/>
<div className="flex flex-col gap-8">
<div className="grid grid-cols-2 gap-x-12 gap-y-8 w-full">
<div className="flex flex-col gap-y-4 col-span-2 md:col-span-1">
<div className="pt-2 text-xl font-medium">Configuration</div>
{GITHUB_FORM_FIELDS.map((field) => (
<ControllerInput
key={field.key}
control={control}
type={field.type}
name={field.key}
label={field.label}
description={field.description}
placeholder={field.placeholder}
error={field.error}
required={field.required}
/>
))}
<div className="flex flex-col gap-1 pt-4">
<div className="flex items-center gap-4">
<Button variant="primary" onClick={handleSubmit(onSubmit)} loading={isSubmitting} disabled={!isDirty}>
{isSubmitting ? "Saving..." : "Save changes"}
</Button>
<Link
href="/authentication"
className={cn(getButtonStyling("link-neutral", "md"), "font-medium")}
onClick={handleGoBack}
>
Go back
</Link>
</div>
</div>
</div>
<div className="col-span-2 md:col-span-1">
<div className="flex flex-col gap-y-4 px-6 py-4 my-2 bg-custom-background-80/60 rounded-lg">
<div className="pt-2 text-xl font-medium">Service provider details</div>
{GITHUB_SERVICE_FIELD.map((field) => (
<CopyField key={field.key} label={field.label} url={field.url} description={field.description} />
))}
</div>
</div>
</div>
</div>
</>
);
};
+114
View File
@@ -0,0 +1,114 @@
"use client";
import { useState } from "react";
import { observer } from "mobx-react-lite";
import Image from "next/image";
import { useTheme } from "next-themes";
import useSWR from "swr";
import { Loader, ToggleSwitch, setPromiseToast } from "@plane/ui";
// components
import { PageHeader } from "@/components/core";
// helpers
import { resolveGeneralTheme } from "@/helpers/common.helper";
// hooks
import { useInstance } from "@/hooks/store";
// icons
import githubLightModeImage from "@/public/logos/github-black.png";
import githubDarkModeImage from "@/public/logos/github-white.png";
// local components
import { AuthenticationMethodCard } from "../components";
import { InstanceGithubConfigForm } from "./form";
const InstanceGithubAuthenticationPage = observer(() => {
// store
const { fetchInstanceConfigurations, formattedConfig, updateInstanceConfigurations } = useInstance();
// state
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
// theme
const { resolvedTheme } = useTheme();
// config
const enableGithubConfig = formattedConfig?.IS_GITHUB_ENABLED ?? "";
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
const updateConfig = async (key: "IS_GITHUB_ENABLED", value: string) => {
setIsSubmitting(true);
const payload = {
[key]: value,
};
const updateConfigPromise = updateInstanceConfigurations(payload);
setPromiseToast(updateConfigPromise, {
loading: "Saving Configuration...",
success: {
title: "Configuration saved",
message: () => `Github authentication is now ${value ? "active" : "disabled"}.`,
},
error: {
title: "Error",
message: () => "Failed to save configuration",
},
});
await updateConfigPromise
.then(() => {
setIsSubmitting(false);
})
.catch((err) => {
console.error(err);
setIsSubmitting(false);
});
};
return (
<>
<PageHeader title="Authentication - God Mode" />
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<AuthenticationMethodCard
name="Github"
description="Allow members to login or sign up to plane with their Github accounts."
icon={
<Image
src={resolveGeneralTheme(resolvedTheme) === "dark" ? githubDarkModeImage : githubLightModeImage}
height={24}
width={24}
alt="GitHub Logo"
/>
}
config={
<ToggleSwitch
value={Boolean(parseInt(enableGithubConfig))}
onChange={() => {
Boolean(parseInt(enableGithubConfig)) === true
? updateConfig("IS_GITHUB_ENABLED", "0")
: updateConfig("IS_GITHUB_ENABLED", "1");
}}
size="sm"
disabled={isSubmitting || !formattedConfig}
/>
}
disabled={isSubmitting || !formattedConfig}
withBorder={false}
/>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{formattedConfig ? (
<InstanceGithubConfigForm config={formattedConfig} />
) : (
<Loader className="space-y-8">
<Loader.Item height="50px" width="25%" />
<Loader.Item height="50px" />
<Loader.Item height="50px" />
<Loader.Item height="50px" />
<Loader.Item height="50px" width="50%" />
</Loader>
)}
</div>
</div>
</>
);
});
export default InstanceGithubAuthenticationPage;
+211
View File
@@ -0,0 +1,211 @@
import { FC, useState } from "react";
import isEmpty from "lodash/isEmpty";
import Link from "next/link";
import { useForm } from "react-hook-form";
// types
import { IFormattedInstanceConfiguration, TInstanceGoogleAuthenticationConfigurationKeys } from "@plane/types";
// ui
import { Button, TOAST_TYPE, getButtonStyling, setToast } from "@plane/ui";
// components
import {
ConfirmDiscardModal,
ControllerInput,
CopyField,
TControllerInputFormField,
TCopyField,
} from "@/components/common";
// helpers
import { API_BASE_URL, cn } from "@/helpers/common.helper";
// hooks
import { useInstance } from "@/hooks/store";
type Props = {
config: IFormattedInstanceConfiguration;
};
type GoogleConfigFormValues = Record<TInstanceGoogleAuthenticationConfigurationKeys, string>;
export const InstanceGoogleConfigForm: FC<Props> = (props) => {
const { config } = props;
// states
const [isDiscardChangesModalOpen, setIsDiscardChangesModalOpen] = useState(false);
// store hooks
const { updateInstanceConfigurations } = useInstance();
// form data
const {
handleSubmit,
control,
reset,
formState: { errors, isDirty, isSubmitting },
} = useForm<GoogleConfigFormValues>({
defaultValues: {
GOOGLE_CLIENT_ID: config["GOOGLE_CLIENT_ID"],
GOOGLE_CLIENT_SECRET: config["GOOGLE_CLIENT_SECRET"],
},
});
const originURL = !isEmpty(API_BASE_URL) ? API_BASE_URL : typeof window !== "undefined" ? window.location.origin : "";
const GOOGLE_FORM_FIELDS: TControllerInputFormField[] = [
{
key: "GOOGLE_CLIENT_ID",
type: "text",
label: "Client ID",
description: (
<>
Your client ID lives in your Google API Console.{" "}
<a
tabIndex={-1}
href="https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#creatingcred"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
Learn more
</a>
</>
),
placeholder: "840195096245-0p2tstej9j5nc4l8o1ah2dqondscqc1g.apps.googleusercontent.com",
error: Boolean(errors.GOOGLE_CLIENT_ID),
required: true,
},
{
key: "GOOGLE_CLIENT_SECRET",
type: "password",
label: "Client secret",
description: (
<>
Your client secret should also be in your Google API Console.{" "}
<a
tabIndex={-1}
href="https://developers.google.com/identity/oauth2/web/guides/get-google-api-clientid"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
Learn more
</a>
</>
),
placeholder: "GOCShX-ADp4cI0kPqav1gGCBg5bE02E",
error: Boolean(errors.GOOGLE_CLIENT_SECRET),
required: true,
},
];
const GOOGLE_SERVICE_DETAILS: TCopyField[] = [
{
key: "Origin_URL",
label: "Origin URL",
url: originURL,
description: (
<p>
We will auto-generate this. Paste this into your Authorized JavaScript origins field. For this OAuth client{" "}
<a
href="https://console.cloud.google.com/apis/credentials/oauthclient"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
here.
</a>
</p>
),
},
{
key: "Callback_URI",
label: "Callback URI",
url: `${originURL}/auth/google/callback/`,
description: (
<p>
We will auto-generate this. Paste this into your Authorized Redirect URI field. For this OAuth client{" "}
<a
href="https://console.cloud.google.com/apis/credentials/oauthclient"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
here.
</a>
</p>
),
},
];
const onSubmit = async (formData: GoogleConfigFormValues) => {
const payload: Partial<GoogleConfigFormValues> = { ...formData };
await updateInstanceConfigurations(payload)
.then((response = []) => {
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "Google Configuration Settings updated successfully",
});
reset({
GOOGLE_CLIENT_ID: response.find((item) => item.key === "GOOGLE_CLIENT_ID")?.value,
GOOGLE_CLIENT_SECRET: response.find((item) => item.key === "GOOGLE_CLIENT_SECRET")?.value,
});
})
.catch((err) => console.error(err));
};
const handleGoBack = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
if (isDirty) {
e.preventDefault();
setIsDiscardChangesModalOpen(true);
}
};
return (
<>
<ConfirmDiscardModal
isOpen={isDiscardChangesModalOpen}
onDiscardHref="/authentication"
handleClose={() => setIsDiscardChangesModalOpen(false)}
/>
<div className="flex flex-col gap-8">
<div className="grid grid-cols-2 gap-x-12 gap-y-8 w-full">
<div className="flex flex-col gap-y-4 col-span-2 md:col-span-1">
<div className="pt-2 text-xl font-medium">Configuration</div>
{GOOGLE_FORM_FIELDS.map((field) => (
<ControllerInput
key={field.key}
control={control}
type={field.type}
name={field.key}
label={field.label}
description={field.description}
placeholder={field.placeholder}
error={field.error}
required={field.required}
/>
))}
<div className="flex flex-col gap-1 pt-4">
<div className="flex items-center gap-4">
<Button variant="primary" onClick={handleSubmit(onSubmit)} loading={isSubmitting} disabled={!isDirty}>
{isSubmitting ? "Saving..." : "Save changes"}
</Button>
<Link
href="/authentication"
className={cn(getButtonStyling("link-neutral", "md"), "font-medium")}
onClick={handleGoBack}
>
Go back
</Link>
</div>
</div>
</div>
<div className="col-span-2 md:col-span-1">
<div className="flex flex-col gap-y-4 px-6 py-4 my-2 bg-custom-background-80/60 rounded-lg">
<div className="pt-2 text-xl font-medium">Service provider details</div>
{GOOGLE_SERVICE_DETAILS.map((field) => (
<CopyField key={field.key} label={field.label} url={field.url} description={field.description} />
))}
</div>
</div>
</div>
</div>
</>
);
};
+102
View File
@@ -0,0 +1,102 @@
"use client";
import { useState } from "react";
import { observer } from "mobx-react-lite";
import Image from "next/image";
import useSWR from "swr";
import { Loader, ToggleSwitch, setPromiseToast } from "@plane/ui";
// components
import { PageHeader } from "@/components/core";
// hooks
import { useInstance } from "@/hooks/store";
// icons
import GoogleLogo from "@/public/logos/google-logo.svg";
// local components
import { AuthenticationMethodCard } from "../components";
import { InstanceGoogleConfigForm } from "./form";
const InstanceGoogleAuthenticationPage = observer(() => {
// store
const { fetchInstanceConfigurations, formattedConfig, updateInstanceConfigurations } = useInstance();
// state
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
// config
const enableGoogleConfig = formattedConfig?.IS_GOOGLE_ENABLED ?? "";
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
const updateConfig = async (key: "IS_GOOGLE_ENABLED", value: string) => {
setIsSubmitting(true);
const payload = {
[key]: value,
};
const updateConfigPromise = updateInstanceConfigurations(payload);
setPromiseToast(updateConfigPromise, {
loading: "Saving Configuration...",
success: {
title: "Configuration saved",
message: () => `Google authentication is now ${value ? "active" : "disabled"}.`,
},
error: {
title: "Error",
message: () => "Failed to save configuration",
},
});
await updateConfigPromise
.then(() => {
setIsSubmitting(false);
})
.catch((err) => {
console.error(err);
setIsSubmitting(false);
});
};
return (
<>
<PageHeader title="Authentication - God Mode" />
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<AuthenticationMethodCard
name="Google"
description="Allow members to login or sign up to plane with their Google
accounts."
icon={<Image src={GoogleLogo} height={24} width={24} alt="Google Logo" />}
config={
<ToggleSwitch
value={Boolean(parseInt(enableGoogleConfig))}
onChange={() => {
Boolean(parseInt(enableGoogleConfig)) === true
? updateConfig("IS_GOOGLE_ENABLED", "0")
: updateConfig("IS_GOOGLE_ENABLED", "1");
}}
size="sm"
disabled={isSubmitting || !formattedConfig}
/>
}
disabled={isSubmitting || !formattedConfig}
withBorder={false}
/>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{formattedConfig ? (
<InstanceGoogleConfigForm config={formattedConfig} />
) : (
<Loader className="space-y-8">
<Loader.Item height="50px" width="25%" />
<Loader.Item height="50px" />
<Loader.Item height="50px" />
<Loader.Item height="50px" />
<Loader.Item height="50px" width="50%" />
</Loader>
)}
</div>
</div>
</>
);
});
export default InstanceGoogleAuthenticationPage;
+11
View File
@@ -0,0 +1,11 @@
import { ReactNode } from "react";
import { Metadata } from "next";
import { AdminLayout } from "@/layouts/admin-layout";
export const metadata: Metadata = {
title: "Authentication Settings - God Mode",
};
export default function AuthenticationLayout({ children }: { children: ReactNode }) {
return <AdminLayout>{children}</AdminLayout>;
}
+159
View File
@@ -0,0 +1,159 @@
"use client";
import { useState } from "react";
import { observer } from "mobx-react-lite";
import Image from "next/image";
import { useTheme } from "next-themes";
import useSWR from "swr";
import { Mails, KeyRound } from "lucide-react";
import { TInstanceConfigurationKeys } from "@plane/types";
import { Loader, setPromiseToast } from "@plane/ui";
// components
import { PageHeader } from "@/components/core";
// hooks
// helpers
import { resolveGeneralTheme } from "@/helpers/common.helper";
import { useInstance } from "@/hooks/store";
// images
import githubLightModeImage from "@/public/logos/github-black.png";
import githubDarkModeImage from "@/public/logos/github-white.png";
import GoogleLogo from "@/public/logos/google-logo.svg";
// local components
import {
AuthenticationMethodCard,
EmailCodesConfiguration,
PasswordLoginConfiguration,
GithubConfiguration,
GoogleConfiguration,
} from "./components";
type TInstanceAuthenticationMethodCard = {
key: string;
name: string;
description: string;
icon: JSX.Element;
config: JSX.Element;
};
const InstanceAuthenticationPage = observer(() => {
// store
const { fetchInstanceConfigurations, formattedConfig, updateInstanceConfigurations } = useInstance();
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
// state
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
// theme
const { resolvedTheme } = useTheme();
const updateConfig = async (key: TInstanceConfigurationKeys, value: string) => {
setIsSubmitting(true);
const payload = {
[key]: value,
};
const updateConfigPromise = updateInstanceConfigurations(payload);
setPromiseToast(updateConfigPromise, {
loading: "Saving Configuration...",
success: {
title: "Success",
message: () => "Configuration saved successfully",
},
error: {
title: "Error",
message: () => "Failed to save configuration",
},
});
await updateConfigPromise
.then(() => {
setIsSubmitting(false);
})
.catch((err) => {
console.error(err);
setIsSubmitting(false);
});
};
// Authentication methods
const authenticationMethodsCard: TInstanceAuthenticationMethodCard[] = [
{
key: "email-codes",
name: "Email codes",
description: "Login or sign up using codes sent via emails. You need to have email setup here and enabled.",
icon: <Mails className="h-6 w-6 p-0.5 text-custom-text-300/80" />,
config: <EmailCodesConfiguration disabled={isSubmitting} updateConfig={updateConfig} />,
},
{
key: "password-login",
name: "Password based login",
description: "Allow members to create accounts with passwords for emails to sign in.",
icon: <KeyRound className="h-6 w-6 p-0.5 text-custom-text-300/80" />,
config: <PasswordLoginConfiguration disabled={isSubmitting} updateConfig={updateConfig} />,
},
{
key: "google",
name: "Google",
description: "Allow members to login or sign up to plane with their Google accounts.",
icon: <Image src={GoogleLogo} height={20} width={20} alt="Google Logo" />,
config: <GoogleConfiguration disabled={isSubmitting} updateConfig={updateConfig} />,
},
{
key: "github",
name: "Github",
description: "Allow members to login or sign up to plane with their Github accounts.",
icon: (
<Image
src={resolveGeneralTheme(resolvedTheme) === "dark" ? githubDarkModeImage : githubLightModeImage}
height={20}
width={20}
alt="GitHub Logo"
/>
),
config: <GithubConfiguration disabled={isSubmitting} updateConfig={updateConfig} />,
},
];
return (
<>
<PageHeader title="Authentication - God Mode" />
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<div className="text-xl font-medium text-custom-text-100">Manage authentication for your instance</div>
<div className="text-sm font-normal text-custom-text-300">
Configure authentication modes for your team and restrict sign ups to be invite only.
</div>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{formattedConfig ? (
<div className="space-y-3">
<div className="text-lg font-medium">Authentication modes</div>
{authenticationMethodsCard.map((method) => (
<AuthenticationMethodCard
key={method.key}
name={method.name}
description={method.description}
icon={method.icon}
config={method.config}
disabled={isSubmitting}
/>
))}
</div>
) : (
<Loader className="space-y-10">
<Loader.Item height="50px" width="75%" />
<Loader.Item height="50px" width="75%" />
<Loader.Item height="50px" width="40%" />
<Loader.Item height="50px" width="40%" />
<Loader.Item height="50px" width="20%" />
</Loader>
)}
</div>
</div>
</>
);
});
export default InstanceAuthenticationPage;
+222
View File
@@ -0,0 +1,222 @@
import React, { FC, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
// types
import { IFormattedInstanceConfiguration, TInstanceEmailConfigurationKeys } from "@plane/types";
// ui
import { Button, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ControllerInput, TControllerInputFormField } from "@/components/common";
// hooks
import { useInstance } from "@/hooks/store";
// local components
import { SendTestEmailModal } from "./test-email-modal";
type IInstanceEmailForm = {
config: IFormattedInstanceConfiguration;
};
type EmailFormValues = Record<TInstanceEmailConfigurationKeys, string>;
type TEmailSecurityKeys = "EMAIL_USE_TLS" | "EMAIL_USE_SSL" | "NONE";
const EMAIL_SECURITY_OPTIONS: { [key in TEmailSecurityKeys]: string } = {
EMAIL_USE_TLS: "TLS",
EMAIL_USE_SSL: "SSL",
NONE: "No email security",
};
export const InstanceEmailForm: FC<IInstanceEmailForm> = (props) => {
const { config } = props;
// states
const [isSendTestEmailModalOpen, setIsSendTestEmailModalOpen] = useState(false);
// store hooks
const { updateInstanceConfigurations } = useInstance();
// form data
const {
handleSubmit,
watch,
setValue,
control,
formState: { errors, isValid, isDirty, isSubmitting },
} = useForm<EmailFormValues>({
defaultValues: {
EMAIL_HOST: config["EMAIL_HOST"],
EMAIL_PORT: config["EMAIL_PORT"],
EMAIL_HOST_USER: config["EMAIL_HOST_USER"],
EMAIL_HOST_PASSWORD: config["EMAIL_HOST_PASSWORD"],
EMAIL_USE_TLS: config["EMAIL_USE_TLS"],
EMAIL_USE_SSL: config["EMAIL_USE_SSL"],
EMAIL_FROM: config["EMAIL_FROM"],
},
});
const emailFormFields: TControllerInputFormField[] = [
{
key: "EMAIL_HOST",
type: "text",
label: "Host",
placeholder: "email.google.com",
error: Boolean(errors.EMAIL_HOST),
required: true,
},
{
key: "EMAIL_PORT",
type: "text",
label: "Port",
placeholder: "8080",
error: Boolean(errors.EMAIL_PORT),
required: true,
},
{
key: "EMAIL_FROM",
type: "text",
label: "Sender email address",
description:
"This is the email address your users will see when getting emails from this instance. You will need to verify this address.",
placeholder: "no-reply@projectplane.so",
error: Boolean(errors.EMAIL_FROM),
required: true,
},
];
const OptionalEmailFormFields: TControllerInputFormField[] = [
{
key: "EMAIL_HOST_USER",
type: "text",
label: "Username",
placeholder: "getitdone@projectplane.so",
error: Boolean(errors.EMAIL_HOST_USER),
required: false,
},
{
key: "EMAIL_HOST_PASSWORD",
type: "password",
label: "Password",
placeholder: "Password",
error: Boolean(errors.EMAIL_HOST_PASSWORD),
required: false,
},
];
const onSubmit = async (formData: EmailFormValues) => {
const payload: Partial<EmailFormValues> = { ...formData };
await updateInstanceConfigurations(payload)
.then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "Email Settings updated successfully",
})
)
.catch((err) => console.error(err));
};
const useTLSValue = watch("EMAIL_USE_TLS");
const useSSLValue = watch("EMAIL_USE_SSL");
const emailSecurityKey: TEmailSecurityKeys = useMemo(() => {
if (useTLSValue === "1") return "EMAIL_USE_TLS";
if (useSSLValue === "1") return "EMAIL_USE_SSL";
return "NONE";
}, [useTLSValue, useSSLValue]);
const handleEmailSecurityChange = (key: TEmailSecurityKeys) => {
if (key === "EMAIL_USE_SSL") {
setValue("EMAIL_USE_TLS", "0");
setValue("EMAIL_USE_SSL", "1");
}
if (key === "EMAIL_USE_TLS") {
setValue("EMAIL_USE_TLS", "1");
setValue("EMAIL_USE_SSL", "0");
}
if (key === "NONE") {
setValue("EMAIL_USE_TLS", "0");
setValue("EMAIL_USE_SSL", "0");
}
};
return (
<div className="space-y-8">
<div>
<SendTestEmailModal isOpen={isSendTestEmailModalOpen} handleClose={() => setIsSendTestEmailModalOpen(false)} />
<div className="grid-col grid w-full max-w-4xl grid-cols-1 items-start justify-between gap-10 lg:grid-cols-2">
{emailFormFields.map((field) => (
<ControllerInput
key={field.key}
control={control}
type={field.type}
name={field.key}
label={field.label}
description={field.description}
placeholder={field.placeholder}
error={field.error}
required={field.required}
/>
))}
<div className="flex flex-col gap-1">
<h4 className="text-sm text-custom-text-300">Email security</h4>
<CustomSelect
value={emailSecurityKey}
label={EMAIL_SECURITY_OPTIONS[emailSecurityKey]}
onChange={handleEmailSecurityChange}
buttonClassName="rounded-md border-custom-border-200"
optionsClassName="w-full"
input
>
{Object.entries(EMAIL_SECURITY_OPTIONS).map(([key, value]) => (
<CustomSelect.Option key={key} value={key} className="w-full">
{value}
</CustomSelect.Option>
))}
</CustomSelect>
</div>
</div>
<div className="flex flex-col gap-6 my-6 pt-4 border-t border-custom-border-100">
<div className="flex w-full max-w-md flex-col gap-y-10 px-1">
<div className="mr-8 flex items-center gap-10 pt-4">
<div className="grow">
<div className="text-sm font-medium text-custom-text-100">Authentication (optional)</div>
<div className="text-xs font-normal text-custom-text-300">
We recommend setting up a username password for your SMTP server
</div>
</div>
</div>
</div>
<div className="grid-col grid w-full max-w-4xl grid-cols-1 items-center justify-between gap-10 lg:grid-cols-2">
{OptionalEmailFormFields.map((field) => (
<ControllerInput
key={field.key}
control={control}
type={field.type}
name={field.key}
label={field.label}
description={field.description}
placeholder={field.placeholder}
error={field.error}
required={field.required}
/>
))}
</div>
</div>
</div>
<div className="flex max-w-4xl items-center py-1 gap-4">
<Button
variant="primary"
onClick={handleSubmit(onSubmit)}
loading={isSubmitting}
disabled={!isValid || !isDirty}
>
{isSubmitting ? "Saving..." : "Save changes"}
</Button>
<Button
variant="outline-primary"
onClick={() => setIsSendTestEmailModalOpen(true)}
loading={isSubmitting}
disabled={!isValid}
>
Send test email
</Button>
</div>
</div>
);
};
+15
View File
@@ -0,0 +1,15 @@
import { ReactNode } from "react";
import { Metadata } from "next";
import { AdminLayout } from "@/layouts/admin-layout";
interface EmailLayoutProps {
children: ReactNode;
}
export const metadata: Metadata = {
title: "Email Settings - God Mode",
};
const EmailLayout = ({ children }: EmailLayoutProps) => <AdminLayout>{children}</AdminLayout>;
export default EmailLayout;
+51
View File
@@ -0,0 +1,51 @@
"use client";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import { Loader } from "@plane/ui";
// components
import { PageHeader } from "@/components/core";
// hooks
import { useInstance } from "@/hooks/store";
// components
import { InstanceEmailForm } from "./email-config-form";
const InstanceEmailPage = observer(() => {
// store
const { fetchInstanceConfigurations, formattedConfig } = useInstance();
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
return (
<>
<PageHeader title="Email - God Mode" />
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<div className="text-xl font-medium text-custom-text-100">Secure emails from your own instance</div>
<div className="text-sm font-normal text-custom-text-300">
Plane can send useful emails to you and your users from your own instance without talking to the Internet.
<div className="text-sm font-normal text-custom-text-300">
Set it up below and please test your settings before you save them.&nbsp;
<span className="text-red-400">Misconfigs can lead to email bounces and errors.</span>
</div>
</div>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{formattedConfig ? (
<InstanceEmailForm config={formattedConfig} />
) : (
<Loader className="space-y-10">
<Loader.Item height="50px" width="75%" />
<Loader.Item height="50px" width="75%" />
<Loader.Item height="50px" width="40%" />
<Loader.Item height="50px" width="40%" />
<Loader.Item height="50px" width="20%" />
</Loader>
)}
</div>
</div>
</>
);
});
export default InstanceEmailPage;
+135
View File
@@ -0,0 +1,135 @@
import React, { FC, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
// ui
import { Button, Input } from "@plane/ui";
// services
import { InstanceService } from "@/services/instance.service";
type Props = {
isOpen: boolean;
handleClose: () => void;
};
enum ESendEmailSteps {
SEND_EMAIL = "SEND_EMAIL",
SUCCESS = "SUCCESS",
FAILED = "FAILED",
}
const instanceService = new InstanceService();
export const SendTestEmailModal: FC<Props> = (props) => {
const { isOpen, handleClose } = props;
// state
const [receiverEmail, setReceiverEmail] = useState("");
const [sendEmailStep, setSendEmailStep] = useState<ESendEmailSteps>(ESendEmailSteps.SEND_EMAIL);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState("");
// reset state
const resetState = () => {
setReceiverEmail("");
setSendEmailStep(ESendEmailSteps.SEND_EMAIL);
setIsLoading(false);
setError("");
};
useEffect(() => {
if (!isOpen) {
resetState();
}
}, [isOpen]);
const handleSubmit = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
setIsLoading(true);
await instanceService
.sendTestEmail(receiverEmail)
.then(() => {
setSendEmailStep(ESendEmailSteps.SUCCESS);
})
.catch((error) => {
setError(error?.message || "Failed to send email");
setSendEmailStep(ESendEmailSteps.FAILED);
})
.finally(() => {
setIsLoading(false);
});
};
return (
<Transition.Root show={isOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-20" onClose={handleClose}>
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-custom-backdrop transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-20 overflow-y-auto">
<div className="my-10 flex justify-center p-4 text-center sm:p-0 md:my-20">
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative transform rounded-lg bg-custom-background-100 p-5 px-4 text-left shadow-custom-shadow-md transition-all w-full sm:max-w-xl">
<h3 className="text-lg font-medium leading-6 text-custom-text-100">
{sendEmailStep === ESendEmailSteps.SEND_EMAIL
? "Send test email"
: sendEmailStep === ESendEmailSteps.SUCCESS
? "Email send"
: "Failed"}{" "}
</h3>
<div className="pt-6 pb-2">
{sendEmailStep === ESendEmailSteps.SEND_EMAIL && (
<Input
id="receiver_email"
type="email"
value={receiverEmail}
onChange={(e) => setReceiverEmail(e.target.value)}
placeholder="Receiver email"
className="w-full resize-none text-lg"
tabIndex={1}
/>
)}
{sendEmailStep === ESendEmailSteps.SUCCESS && (
<div className="flex flex-col gap-y-4 text-sm">
<p>
We have sent the test email to {receiverEmail}. Please check your spam folder if you cannot find
it.
</p>
<p>If you still cannot find it, recheck your SMTP configuration and trigger a new test email.</p>
</div>
)}
{sendEmailStep === ESendEmailSteps.FAILED && <div className="text-sm">{error}</div>}
<div className="flex items-center gap-2 justify-end mt-5">
<Button variant="neutral-primary" size="sm" onClick={handleClose} tabIndex={2}>
{sendEmailStep === ESendEmailSteps.SEND_EMAIL ? "Cancel" : "Close"}
</Button>
{sendEmailStep === ESendEmailSteps.SEND_EMAIL && (
<Button variant="primary" size="sm" loading={isLoading} onClick={handleSubmit} tabIndex={3}>
{isLoading ? "Sending email..." : "Send email"}
</Button>
)}
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
);
};
+9
View File
@@ -0,0 +1,9 @@
"use client";
export default function RootErrorPage() {
return (
<div>
<p>Something went wrong.</p>
</div>
);
}
+140
View File
@@ -0,0 +1,140 @@
"use client";
import { FC } from "react";
import { observer } from "mobx-react-lite";
import { Controller, useForm } from "react-hook-form";
import { Telescope } from "lucide-react";
// types
import { IInstance, IInstanceAdmin } from "@plane/types";
// ui
import { Button, Input, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
// components
import { ControllerInput } from "@/components/common";
// hooks
import { useInstance } from "@/hooks/store";
export interface IGeneralConfigurationForm {
instance: IInstance;
instanceAdmins: IInstanceAdmin[];
}
export const GeneralConfigurationForm: FC<IGeneralConfigurationForm> = observer((props) => {
const { instance, instanceAdmins } = props;
// hooks
const { updateInstanceInfo } = useInstance();
// form data
const {
handleSubmit,
control,
formState: { errors, isSubmitting },
} = useForm<Partial<IInstance>>({
defaultValues: {
instance_name: instance?.instance_name,
is_telemetry_enabled: instance?.is_telemetry_enabled,
},
});
const onSubmit = async (formData: Partial<IInstance>) => {
const payload: Partial<IInstance> = { ...formData };
console.log("payload", payload);
await updateInstanceInfo(payload)
.then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "Settings updated successfully",
})
)
.catch((err) => console.error(err));
};
return (
<div className="space-y-8">
<div className="space-y-3">
<div className="text-lg font-medium">Instance details</div>
<div className="grid-col grid w-full grid-cols-1 items-center justify-between gap-8 md:grid-cols-2 lg:grid-cols-3">
<ControllerInput
key="instance_name"
name="instance_name"
control={control}
type="text"
label="Name of instance"
placeholder="Instance name"
error={Boolean(errors.instance_name)}
required
/>
<div className="flex flex-col gap-1">
<h4 className="text-sm text-custom-text-300">Email</h4>
<Input
id="email"
name="email"
type="email"
value={instanceAdmins[0]?.user_detail?.email ?? ""}
placeholder="Admin email"
className="w-full cursor-not-allowed !text-custom-text-400"
disabled
/>
</div>
<div className="flex flex-col gap-1">
<h4 className="text-sm text-custom-text-300">Instance ID</h4>
<Input
id="instance_id"
name="instance_id"
type="text"
value={instance.instance_id}
className="w-full cursor-not-allowed rounded-md font-medium !text-custom-text-400"
disabled
/>
</div>
</div>
</div>
<div className="space-y-3">
<div className="text-lg font-medium">Telemetry</div>
<div className="flex items-center gap-14 px-4 py-3 border border-custom-border-200 rounded">
<div className="grow flex items-center gap-4">
<div className="shrink-0">
<div className="flex items-center justify-center w-10 h-10 bg-custom-background-80 rounded-full">
<Telescope className="w-6 h-6 text-custom-text-300/80 p-0.5" />
</div>
</div>
<div className="grow">
<div className="text-sm font-medium text-custom-text-100 leading-5">
Allow Plane to collect anonymous usage events
</div>
<div className="text-xs font-normal text-custom-text-300 leading-5">
We collect usage events without any PII to analyse and improve Plane.{" "}
<a
href="https://docs.plane.so/self-hosting/telemetry"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
Know more.
</a>
</div>
</div>
</div>
<div className={`shrink-0 ${isSubmitting && "opacity-70"}`}>
<Controller
control={control}
name="is_telemetry_enabled"
render={({ field: { value, onChange } }) => (
<ToggleSwitch value={value ?? false} onChange={onChange} size="sm" disabled={isSubmitting} />
)}
/>
</div>
</div>
</div>
<div>
<Button variant="primary" onClick={handleSubmit(onSubmit)} loading={isSubmitting}>
{isSubmitting ? "Saving..." : "Save changes"}
</Button>
</div>
</div>
);
});
+11
View File
@@ -0,0 +1,11 @@
import { ReactNode } from "react";
import { Metadata } from "next";
import { AdminLayout } from "@/layouts/admin-layout";
export const metadata: Metadata = {
title: "General Settings - God Mode",
};
export default function GeneralLayout({ children }: { children: ReactNode }) {
return <AdminLayout>{children}</AdminLayout>;
}
+31
View File
@@ -0,0 +1,31 @@
"use client";
import { observer } from "mobx-react-lite";
// hooks
import { useInstance } from "@/hooks/store";
// components
import { GeneralConfigurationForm } from "./form";
function GeneralPage() {
const { instance, instanceAdmins } = useInstance();
console.log("instance", instance);
return (
<>
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<div className="text-xl font-medium text-custom-text-100">General settings</div>
<div className="text-sm font-normal text-custom-text-300">
Change the name of your instance and instance admin e-mail addresses. Enable or disable telemetry in your
instance.
</div>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{instance && instanceAdmins && (
<GeneralConfigurationForm instance={instance} instanceAdmins={instanceAdmins} />
)}
</div>
</div>
</>
);
}
export default observer(GeneralPage);
+384
View File
@@ -0,0 +1,384 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600;700;800&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,400,0,0&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.text-1\.5xl {
font-size: 1.375rem;
line-height: 1.875rem;
}
.text-2\.5xl {
font-size: 1.75rem;
line-height: 2.25rem;
}
}
@layer base {
html {
font-family: "Inter", sans-serif;
}
:root {
color-scheme: light !important;
--color-primary-10: 236, 241, 255;
--color-primary-20: 217, 228, 255;
--color-primary-30: 197, 214, 255;
--color-primary-40: 178, 200, 255;
--color-primary-50: 159, 187, 255;
--color-primary-60: 140, 173, 255;
--color-primary-70: 121, 159, 255;
--color-primary-80: 101, 145, 255;
--color-primary-90: 82, 132, 255;
--color-primary-100: 63, 118, 255;
--color-primary-200: 57, 106, 230;
--color-primary-300: 50, 94, 204;
--color-primary-400: 44, 83, 179;
--color-primary-500: 38, 71, 153;
--color-primary-600: 32, 59, 128;
--color-primary-700: 25, 47, 102;
--color-primary-800: 19, 35, 76;
--color-primary-900: 13, 24, 51;
--color-background-100: 255, 255, 255; /* primary bg */
--color-background-90: 247, 247, 247; /* secondary bg */
--color-background-80: 232, 232, 232; /* tertiary bg */
--color-text-100: 23, 23, 23; /* primary text */
--color-text-200: 58, 58, 58; /* secondary text */
--color-text-300: 82, 82, 82; /* tertiary text */
--color-text-400: 163, 163, 163; /* placeholder text */
--color-scrollbar: 163, 163, 163; /* scrollbar thumb */
--color-border-100: 245, 245, 245; /* subtle border= 1 */
--color-border-200: 229, 229, 229; /* subtle border- 2 */
--color-border-300: 212, 212, 212; /* strong border- 1 */
--color-border-400: 185, 185, 185; /* strong border- 2 */
--color-shadow-2xs: 0px 0px 1px 0px rgba(23, 23, 23, 0.06), 0px 1px 2px 0px rgba(23, 23, 23, 0.06),
0px 1px 2px 0px rgba(23, 23, 23, 0.14);
--color-shadow-xs: 0px 1px 2px 0px rgba(0, 0, 0, 0.16), 0px 2px 4px 0px rgba(16, 24, 40, 0.12),
0px 1px 8px -1px rgba(16, 24, 40, 0.1);
--color-shadow-sm: 0px 1px 4px 0px rgba(0, 0, 0, 0.01), 0px 4px 8px 0px rgba(0, 0, 0, 0.02),
0px 1px 12px 0px rgba(0, 0, 0, 0.12);
--color-shadow-rg: 0px 3px 6px 0px rgba(0, 0, 0, 0.1), 0px 4px 4px 0px rgba(16, 24, 40, 0.08),
0px 1px 12px 0px rgba(16, 24, 40, 0.04);
--color-shadow-md: 0px 4px 8px 0px rgba(0, 0, 0, 0.12), 0px 6px 12px 0px rgba(16, 24, 40, 0.12),
0px 1px 16px 0px rgba(16, 24, 40, 0.12);
--color-shadow-lg: 0px 6px 12px 0px rgba(0, 0, 0, 0.12), 0px 8px 16px 0px rgba(0, 0, 0, 0.12),
0px 1px 24px 0px rgba(16, 24, 40, 0.12);
--color-shadow-xl: 0px 0px 18px 0px rgba(0, 0, 0, 0.16), 0px 0px 24px 0px rgba(16, 24, 40, 0.16),
0px 0px 52px 0px rgba(16, 24, 40, 0.16);
--color-shadow-2xl: 0px 8px 16px 0px rgba(0, 0, 0, 0.12), 0px 12px 24px 0px rgba(16, 24, 40, 0.12),
0px 1px 32px 0px rgba(16, 24, 40, 0.12);
--color-shadow-3xl: 0px 12px 24px 0px rgba(0, 0, 0, 0.12), 0px 16px 32px 0px rgba(0, 0, 0, 0.12),
0px 1px 48px 0px rgba(16, 24, 40, 0.12);
--color-shadow-4xl: 0px 8px 40px 0px rgba(0, 0, 61, 0.05), 0px 12px 32px -16px rgba(0, 0, 0, 0.05);
--color-sidebar-background-100: var(--color-background-100); /* primary sidebar bg */
--color-sidebar-background-90: var(--color-background-90); /* secondary sidebar bg */
--color-sidebar-background-80: var(--color-background-80); /* tertiary sidebar bg */
--color-sidebar-text-100: var(--color-text-100); /* primary sidebar text */
--color-sidebar-text-200: var(--color-text-200); /* secondary sidebar text */
--color-sidebar-text-300: var(--color-text-300); /* tertiary sidebar text */
--color-sidebar-text-400: var(--color-text-400); /* sidebar placeholder text */
--color-sidebar-border-100: var(--color-border-100); /* subtle sidebar border= 1 */
--color-sidebar-border-200: var(--color-border-100); /* subtle sidebar border- 2 */
--color-sidebar-border-300: var(--color-border-100); /* strong sidebar border- 1 */
--color-sidebar-border-400: var(--color-border-100); /* strong sidebar border- 2 */
--color-sidebar-shadow-2xs: var(--color-shadow-2xs);
--color-sidebar-shadow-xs: var(--color-shadow-xs);
--color-sidebar-shadow-sm: var(--color-shadow-sm);
--color-sidebar-shadow-rg: var(--color-shadow-rg);
--color-sidebar-shadow-md: var(--color-shadow-md);
--color-sidebar-shadow-lg: var(--color-shadow-lg);
--color-sidebar-shadow-xl: var(--color-shadow-xl);
--color-sidebar-shadow-2xl: var(--color-shadow-2xl);
--color-sidebar-shadow-3xl: var(--color-shadow-3xl);
--color-sidebar-shadow-4xl: var(--color-shadow-4xl);
}
[data-theme="light"],
[data-theme="light-contrast"] {
color-scheme: light !important;
--color-background-100: 255, 255, 255; /* primary bg */
--color-background-90: 247, 247, 247; /* secondary bg */
--color-background-80: 232, 232, 232; /* tertiary bg */
}
[data-theme="light"] {
--color-text-100: 23, 23, 23; /* primary text */
--color-text-200: 58, 58, 58; /* secondary text */
--color-text-300: 82, 82, 82; /* tertiary text */
--color-text-400: 163, 163, 163; /* placeholder text */
--color-scrollbar: 163, 163, 163; /* scrollbar thumb */
--color-border-100: 245, 245, 245; /* subtle border= 1 */
--color-border-200: 229, 229, 229; /* subtle border- 2 */
--color-border-300: 212, 212, 212; /* strong border- 1 */
--color-border-400: 185, 185, 185; /* strong border- 2 */
/* onboarding colors */
--gradient-onboarding-100: linear-gradient(106deg, #f2f6ff 29.8%, #e1eaff 99.34%);
--gradient-onboarding-200: linear-gradient(129deg, rgba(255, 255, 255, 0) -22.23%, rgba(255, 255, 255, 0.8) 62.98%);
--gradient-onboarding-300: linear-gradient(164deg, #fff 4.25%, rgba(255, 255, 255, 0.06) 93.5%);
--gradient-onboarding-400: linear-gradient(129deg, rgba(255, 255, 255, 0) -22.23%, rgba(255, 255, 255, 0.8) 62.98%);
--color-onboarding-text-100: 23, 23, 23;
--color-onboarding-text-200: 58, 58, 58;
--color-onboarding-text-300: 82, 82, 82;
--color-onboarding-text-400: 163, 163, 163;
--color-onboarding-background-100: 236, 241, 255;
--color-onboarding-background-200: 255, 255, 255;
--color-onboarding-background-300: 236, 241, 255;
--color-onboarding-background-400: 177, 206, 250;
--color-onboarding-border-100: 229, 229, 229;
--color-onboarding-border-200: 217, 228, 255;
--color-onboarding-border-300: 229, 229, 229, 0.5;
--color-onboarding-shadow-sm: 0px 4px 20px 0px rgba(126, 139, 171, 0.1);
/* toast theme */
--color-toast-success-text: 62, 155, 79;
--color-toast-error-text: 220, 62, 66;
--color-toast-warning-text: 255, 186, 24;
--color-toast-info-text: 51, 88, 212;
--color-toast-loading-text: 28, 32, 36;
--color-toast-secondary-text: 128, 131, 141;
--color-toast-tertiary-text: 96, 100, 108;
--color-toast-success-background: 253, 253, 254;
--color-toast-error-background: 255, 252, 252;
--color-toast-warning-background: 254, 253, 251;
--color-toast-info-background: 253, 253, 254;
--color-toast-loading-background: 253, 253, 254;
--color-toast-success-border: 218, 241, 219;
--color-toast-error-border: 255, 219, 220;
--color-toast-warning-border: 255, 247, 194;
--color-toast-info-border: 210, 222, 255;
--color-toast-loading-border: 224, 225, 230;
}
[data-theme="light-contrast"] {
--color-text-100: 11, 11, 11; /* primary text */
--color-text-200: 38, 38, 38; /* secondary text */
--color-text-300: 58, 58, 58; /* tertiary text */
--color-text-400: 115, 115, 115; /* placeholder text */
--color-scrollbar: 115, 115, 115; /* scrollbar thumb */
--color-border-100: 34, 34, 34; /* subtle border= 1 */
--color-border-200: 38, 38, 38; /* subtle border- 2 */
--color-border-300: 46, 46, 46; /* strong border- 1 */
--color-border-400: 58, 58, 58; /* strong border- 2 */
}
[data-theme="dark"],
[data-theme="dark-contrast"] {
color-scheme: dark !important;
--color-background-100: 25, 25, 25; /* primary bg */
--color-background-90: 32, 32, 32; /* secondary bg */
--color-background-80: 44, 44, 44; /* tertiary bg */
--color-shadow-2xs: 0px 0px 1px 0px rgba(0, 0, 0, 0.15), 0px 1px 3px 0px rgba(0, 0, 0, 0.5);
--color-shadow-xs: 0px 0px 2px 0px rgba(0, 0, 0, 0.2), 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
--color-shadow-sm: 0px 0px 4px 0px rgba(0, 0, 0, 0.2), 0px 2px 6px 0px rgba(0, 0, 0, 0.5);
--color-shadow-rg: 0px 0px 6px 0px rgba(0, 0, 0, 0.2), 0px 4px 6px 0px rgba(0, 0, 0, 0.5);
--color-shadow-md: 0px 2px 8px 0px rgba(0, 0, 0, 0.2), 0px 4px 8px 0px rgba(0, 0, 0, 0.5);
--color-shadow-lg: 0px 4px 12px 0px rgba(0, 0, 0, 0.25), 0px 4px 10px 0px rgba(0, 0, 0, 0.55);
--color-shadow-xl: 0px 0px 14px 0px rgba(0, 0, 0, 0.25), 0px 6px 10px 0px rgba(0, 0, 0, 0.55);
--color-shadow-2xl: 0px 0px 18px 0px rgba(0, 0, 0, 0.25), 0px 8px 12px 0px rgba(0, 0, 0, 0.6);
--color-shadow-3xl: 0px 4px 24px 0px rgba(0, 0, 0, 0.3), 0px 12px 40px 0px rgba(0, 0, 0, 0.65);
}
[data-theme="dark"] {
--color-text-100: 229, 229, 229; /* primary text */
--color-text-200: 163, 163, 163; /* secondary text */
--color-text-300: 115, 115, 115; /* tertiary text */
--color-text-400: 82, 82, 82; /* placeholder text */
--color-scrollbar: 82, 82, 82; /* scrollbar thumb */
--color-border-100: 34, 34, 34; /* subtle border= 1 */
--color-border-200: 38, 38, 38; /* subtle border- 2 */
--color-border-300: 46, 46, 46; /* strong border- 1 */
--color-border-400: 58, 58, 58; /* strong border- 2 */
/* onboarding colors */
--gradient-onboarding-100: linear-gradient(106deg, #18191b 25.17%, #18191b 99.34%);
--gradient-onboarding-200: linear-gradient(129deg, rgba(47, 49, 53, 0.8) -22.23%, rgba(33, 34, 37, 0.8) 62.98%);
--gradient-onboarding-300: linear-gradient(167deg, rgba(47, 49, 53, 0.45) 19.22%, #212225 98.48%);
--color-onboarding-text-100: 237, 238, 240;
--color-onboarding-text-200: 176, 180, 187;
--color-onboarding-text-300: 118, 123, 132;
--color-onboarding-text-400: 105, 110, 119;
--color-onboarding-background-100: 54, 58, 64;
--color-onboarding-background-200: 40, 42, 45;
--color-onboarding-background-300: 40, 42, 45;
--color-onboarding-background-400: 67, 72, 79;
--color-onboarding-border-100: 54, 58, 64;
--color-onboarding-border-200: 54, 58, 64;
--color-onboarding-border-300: 34, 35, 38, 0.5;
--color-onboarding-shadow-sm: 0px 4px 20px 0px rgba(39, 44, 56, 0.1);
/* toast theme */
--color-toast-success-text: 178, 221, 181;
--color-toast-error-text: 206, 44, 49;
--color-toast-warning-text: 255, 186, 24;
--color-toast-info-text: 141, 164, 239;
--color-toast-loading-text: 255, 255, 255;
--color-toast-secondary-text: 185, 187, 198;
--color-toast-tertiary-text: 139, 141, 152;
--color-toast-success-background: 46, 46, 46;
--color-toast-error-background: 46, 46, 46;
--color-toast-warning-background: 46, 46, 46;
--color-toast-info-background: 46, 46, 46;
--color-toast-loading-background: 46, 46, 46;
--color-toast-success-border: 42, 126, 59;
--color-toast-error-border: 100, 23, 35;
--color-toast-warning-border: 79, 52, 34;
--color-toast-info-border: 58, 91, 199;
--color-toast-loading-border: 96, 100, 108;
}
[data-theme="dark-contrast"] {
--color-text-100: 250, 250, 250; /* primary text */
--color-text-200: 241, 241, 241; /* secondary text */
--color-text-300: 212, 212, 212; /* tertiary text */
--color-text-400: 115, 115, 115; /* placeholder text */
--color-scrollbar: 115, 115, 115; /* scrollbar thumb */
--color-border-100: 245, 245, 245; /* subtle border= 1 */
--color-border-200: 229, 229, 229; /* subtle border- 2 */
--color-border-300: 212, 212, 212; /* strong border- 1 */
--color-border-400: 185, 185, 185; /* strong border- 2 */
}
[data-theme="light"],
[data-theme="dark"],
[data-theme="light-contrast"],
[data-theme="dark-contrast"] {
--color-primary-10: 236, 241, 255;
--color-primary-20: 217, 228, 255;
--color-primary-30: 197, 214, 255;
--color-primary-40: 178, 200, 255;
--color-primary-50: 159, 187, 255;
--color-primary-60: 140, 173, 255;
--color-primary-70: 121, 159, 255;
--color-primary-80: 101, 145, 255;
--color-primary-90: 82, 132, 255;
--color-primary-100: 63, 118, 255;
--color-primary-200: 57, 106, 230;
--color-primary-300: 50, 94, 204;
--color-primary-400: 44, 83, 179;
--color-primary-500: 38, 71, 153;
--color-primary-600: 32, 59, 128;
--color-primary-700: 25, 47, 102;
--color-primary-800: 19, 35, 76;
--color-primary-900: 13, 24, 51;
--color-sidebar-background-100: var(--color-background-100); /* primary sidebar bg */
--color-sidebar-background-90: var(--color-background-90); /* secondary sidebar bg */
--color-sidebar-background-80: var(--color-background-80); /* tertiary sidebar bg */
--color-sidebar-text-100: var(--color-text-100); /* primary sidebar text */
--color-sidebar-text-200: var(--color-text-200); /* secondary sidebar text */
--color-sidebar-text-300: var(--color-text-300); /* tertiary sidebar text */
--color-sidebar-text-400: var(--color-text-400); /* sidebar placeholder text */
--color-sidebar-border-100: var(--color-border-100); /* subtle sidebar border= 1 */
--color-sidebar-border-200: var(--color-border-200); /* subtle sidebar border- 2 */
--color-sidebar-border-300: var(--color-border-300); /* strong sidebar border- 1 */
--color-sidebar-border-400: var(--color-border-400); /* strong sidebar border- 2 */
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
font-variant-ligatures: none;
-webkit-font-variant-ligatures: none;
text-rendering: optimizeLegibility;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
body {
color: rgba(var(--color-text-100));
}
/* scrollbar style */
::-webkit-scrollbar {
display: none;
}
.horizontal-scroll-enable {
overflow-x: scroll;
}
.horizontal-scroll-enable::-webkit-scrollbar {
display: block;
height: 7px;
width: 0;
}
.horizontal-scroll-enable::-webkit-scrollbar-track {
height: 7px;
background-color: rgba(var(--color-background-100));
}
.horizontal-scroll-enable::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: rgba(var(--color-scrollbar));
}
.vertical-scroll-enable::-webkit-scrollbar {
display: block;
width: 5px;
}
.vertical-scroll-enable::-webkit-scrollbar-track {
width: 5px;
}
.vertical-scroll-enable::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: rgba(var(--color-background-90));
}
/* end scrollbar style */
/* progress bar */
.progress-bar {
fill: currentColor;
color: rgba(var(--color-sidebar-background-100));
}
::-webkit-input-placeholder,
::placeholder,
:-ms-input-placeholder {
color: rgb(var(--color-text-400));
}
+79
View File
@@ -0,0 +1,79 @@
import { FC } from "react";
import { useForm } from "react-hook-form";
import { IFormattedInstanceConfiguration, TInstanceImageConfigurationKeys } from "@plane/types";
import { Button, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ControllerInput } from "@/components/common";
// hooks
import { useInstance } from "@/hooks/store";
type IInstanceImageConfigForm = {
config: IFormattedInstanceConfiguration;
};
type ImageConfigFormValues = Record<TInstanceImageConfigurationKeys, string>;
export const InstanceImageConfigForm: FC<IInstanceImageConfigForm> = (props) => {
const { config } = props;
// store hooks
const { updateInstanceConfigurations } = useInstance();
// form data
const {
handleSubmit,
control,
formState: { errors, isSubmitting },
} = useForm<ImageConfigFormValues>({
defaultValues: {
UNSPLASH_ACCESS_KEY: config["UNSPLASH_ACCESS_KEY"],
},
});
const onSubmit = async (formData: ImageConfigFormValues) => {
const payload: Partial<ImageConfigFormValues> = { ...formData };
await updateInstanceConfigurations(payload)
.then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "Image Configuration Settings updated successfully",
})
)
.catch((err) => console.error(err));
};
return (
<div className="space-y-8">
<div className="grid-col grid w-full grid-cols-1 items-center justify-between gap-x-16 gap-y-8 lg:grid-cols-2">
<ControllerInput
control={control}
type="password"
name="UNSPLASH_ACCESS_KEY"
label="Access key from your Unsplash account"
description={
<>
You will find your access key in your Unsplash developer console.&nbsp;
<a
href="https://unsplash.com/documentation#creating-a-developer-account"
target="_blank"
className="text-custom-primary-100 hover:underline"
rel="noreferrer"
>
Learn more.
</a>
</>
}
placeholder="oXgq-sdfadsaeweqasdfasdf3234234rassd"
error={Boolean(errors.UNSPLASH_ACCESS_KEY)}
required
/>
</div>
<div>
<Button variant="primary" onClick={handleSubmit(onSubmit)} loading={isSubmitting}>
{isSubmitting ? "Saving..." : "Save changes"}
</Button>
</div>
</div>
);
};
+15
View File
@@ -0,0 +1,15 @@
import { ReactNode } from "react";
import { Metadata } from "next";
import { AdminLayout } from "@/layouts/admin-layout";
interface ImageLayoutProps {
children: ReactNode;
}
export const metadata: Metadata = {
title: "Images Settings - God Mode",
};
const ImageLayout = ({ children }: ImageLayoutProps) => <AdminLayout>{children}</AdminLayout>;
export default ImageLayout;
+44
View File
@@ -0,0 +1,44 @@
"use client";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import { Loader } from "@plane/ui";
// components
import { PageHeader } from "@/components/core";
// hooks
import { useInstance } from "@/hooks/store";
// local
import { InstanceImageConfigForm } from "./form";
const InstanceImagePage = observer(() => {
// store
const { formattedConfig, fetchInstanceConfigurations } = useInstance();
useSWR("INSTANCE_CONFIGURATIONS", () => fetchInstanceConfigurations());
return (
<>
<PageHeader title="Image - God Mode" />
<div className="relative container mx-auto w-full h-full p-8 py-4 space-y-6 flex flex-col">
<div className="border-b border-custom-border-100 pb-3 space-y-1 flex-shrink-0">
<div className="text-xl font-medium text-custom-text-100">Third-party image libraries</div>
<div className="text-sm font-normal text-custom-text-300">
Let your users search and choose images from third-party libraries
</div>
</div>
<div className="flex-grow overflow-hidden overflow-y-auto">
{formattedConfig ? (
<InstanceImageConfigForm config={formattedConfig} />
) : (
<Loader className="space-y-8">
<Loader.Item height="50px" width="50%" />
<Loader.Item height="50px" width="20%" />
</Loader>
)}
</div>
</div>
</>
);
});
export default InstanceImagePage;
+48
View File
@@ -0,0 +1,48 @@
"use client";
import { ReactNode } from "react";
import { ThemeProvider, useTheme } from "next-themes";
import { SWRConfig } from "swr";
// ui
import { Toast } from "@plane/ui";
// constants
import { SWR_CONFIG } from "@/constants/swr-config";
// helpers
import { ASSET_PREFIX, resolveGeneralTheme } from "@/helpers/common.helper";
// lib
import { InstanceProvider } from "@/lib/instance-provider";
import { StoreProvider } from "@/lib/store-provider";
import { UserProvider } from "@/lib/user-provider";
// styles
import "./globals.css";
function RootLayout({ children }: { children: ReactNode }) {
// themes
const { resolvedTheme } = useTheme();
return (
<html lang="en">
<head>
<link rel="apple-touch-icon" sizes="180x180" href={`${ASSET_PREFIX}/favicon/apple-touch-icon.png`} />
<link rel="icon" type="image/png" sizes="32x32" href={`${ASSET_PREFIX}/favicon/favicon-32x32.png`} />
<link rel="icon" type="image/png" sizes="16x16" href={`${ASSET_PREFIX}/favicon/favicon-16x16.png`} />
<link rel="manifest" href={`${ASSET_PREFIX}/site.webmanifest.json`} />
<link rel="shortcut icon" href={`${ASSET_PREFIX}/favicon/favicon.ico`} />
</head>
<body className={`antialiased`}>
<ThemeProvider themes={["light", "dark"]} defaultTheme="system" enableSystem>
<Toast theme={resolveGeneralTheme(resolvedTheme)} />
<SWRConfig value={SWR_CONFIG}>
<StoreProvider>
<InstanceProvider>
<UserProvider>{children}</UserProvider>
</InstanceProvider>
</StoreProvider>
</SWRConfig>
</ThemeProvider>
</body>
</html>
);
}
export default RootLayout;
+30
View File
@@ -0,0 +1,30 @@
import { Metadata } from "next";
// components
import { InstanceSignInForm } from "@/components/login";
// layouts
import { DefaultLayout } from "@/layouts/default-layout";
export const metadata: Metadata = {
title: "Plane | Simple, extensible, open-source project management tool.",
description:
"Open-source project management tool to manage issues, sprints, and product roadmaps with peace of mind.",
openGraph: {
title: "Plane | Simple, extensible, open-source project management tool.",
description:
"Open-source project management tool to manage issues, sprints, and product roadmaps with peace of mind.",
url: "https://plane.so/",
},
keywords:
"software development, customer feedback, software, accelerate, code management, release management, project management, issue tracking, agile, scrum, kanban, collaboration",
twitter: {
site: "@planepowers",
},
};
export default async function LoginPage() {
return (
<DefaultLayout>
<InstanceSignInForm />
</DefaultLayout>
);
}
@@ -1,11 +1,14 @@
"use client";
import { FC, useState, useRef } from "react";
import { observer } from "mobx-react-lite";
import Link from "next/link";
import { ExternalLink, FileText, HelpCircle, MoveLeft } from "lucide-react";
import { Transition } from "@headlessui/react";
import { FileText, HelpCircle, MessagesSquare, MoveLeft } from "lucide-react";
import { DiscordIcon, GithubIcon, Tooltip } from "@plane/ui";
// hooks
import { DiscordIcon, GithubIcon } from "@plane/ui";
import { useApplication } from "hooks/store";
// icons
import { WEB_BASE_URL } from "@/helpers/common.helper";
import { useTheme } from "@/hooks/store";
// assets
import packageJson from "package.json";
@@ -25,56 +28,56 @@ const helpOptions = [
href: "https://github.com/makeplane/plane/issues/new/choose",
Icon: GithubIcon,
},
{
name: "Chat with us",
href: null,
onClick: () => (window as any).$crisp.push(["do", "chat:show"]),
Icon: MessagesSquare,
},
];
export const InstanceHelpSection: FC = () => {
export const HelpSection: FC = observer(() => {
// states
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
// store
const {
theme: { sidebarCollapsed, toggleSidebar },
} = useApplication();
const { isSidebarCollapsed, toggleSidebar } = useTheme();
// refs
const helpOptionsRef = useRef<HTMLDivElement | null>(null);
const redirectionLink = encodeURI(WEB_BASE_URL + "/create-workspace");
return (
<div
className={`flex w-full items-center justify-between gap-1 self-baseline border-t border-custom-border-200 bg-custom-sidebar-background-100 px-4 py-2 ${
sidebarCollapsed ? "flex-col" : ""
className={`flex w-full items-center justify-between gap-1 self-baseline border-t border-custom-sidebar-border-200 bg-custom-sidebar-background-100 px-4 py-2 ${
isSidebarCollapsed ? "flex-col" : ""
}`}
>
<div className={`flex items-center gap-1 ${sidebarCollapsed ? "flex-col justify-center" : "w-full justify-end"}`}>
<button
type="button"
className={`grid place-items-center rounded-md p-1.5 text-custom-text-200 outline-none hover:bg-custom-background-90 hover:text-custom-text-100 ${
sidebarCollapsed ? "w-full" : ""
}`}
onClick={() => setIsNeedHelpOpen((prev) => !prev)}
>
<HelpCircle className="h-3.5 w-3.5" />
</button>
<button
type="button"
className="grid place-items-center rounded-md p-1.5 text-custom-text-200 outline-none hover:bg-custom-background-90 hover:text-custom-text-100 md:hidden"
onClick={() => toggleSidebar()}
>
<MoveLeft className="h-3.5 w-3.5" />
</button>
<button
type="button"
className={`hidden place-items-center rounded-md p-1.5 text-custom-text-200 outline-none hover:bg-custom-background-90 hover:text-custom-text-100 md:grid ${
sidebarCollapsed ? "w-full" : ""
}`}
onClick={() => toggleSidebar()}
>
<MoveLeft className={`h-3.5 w-3.5 duration-300 ${sidebarCollapsed ? "rotate-180" : ""}`} />
</button>
<div className={`flex items-center gap-1 ${isSidebarCollapsed ? "flex-col justify-center" : "w-full"}`}>
<Tooltip tooltipContent="Redirect to plane" position="right" className="ml-4" disabled={!isSidebarCollapsed}>
<a
href={redirectionLink}
className={`relative px-2 py-1.5 flex items-center gap-2 font-medium rounded border border-custom-primary-100/20 bg-custom-primary-100/10 text-xs text-custom-primary-200 whitespace-nowrap`}
>
<ExternalLink size={14} />
{!isSidebarCollapsed && "Redirect to plane"}
</a>
</Tooltip>
<Tooltip tooltipContent="Help" position={isSidebarCollapsed ? "right" : "top"} className="ml-4">
<button
type="button"
className={`ml-auto grid place-items-center rounded-md p-1.5 text-custom-text-200 outline-none hover:bg-custom-background-90 hover:text-custom-text-100 ${
isSidebarCollapsed ? "w-full" : ""
}`}
onClick={() => setIsNeedHelpOpen((prev) => !prev)}
>
<HelpCircle className="h-3.5 w-3.5" />
</button>
</Tooltip>
<Tooltip tooltipContent="Toggle sidebar" position={isSidebarCollapsed ? "right" : "top"} className="ml-4">
<button
type="button"
className={`grid place-items-center rounded-md p-1.5 text-custom-text-200 outline-none hover:bg-custom-background-90 hover:text-custom-text-100 ${
isSidebarCollapsed ? "w-full" : ""
}`}
onClick={() => toggleSidebar(!isSidebarCollapsed)}
>
<MoveLeft className={`h-3.5 w-3.5 duration-300 ${isSidebarCollapsed ? "rotate-180" : ""}`} />
</button>
</Tooltip>
</div>
<div className="relative">
@@ -89,12 +92,12 @@ export const InstanceHelpSection: FC = () => {
>
<div
className={`absolute bottom-2 min-w-[10rem] ${
sidebarCollapsed ? "left-full" : "-left-[75px]"
isSidebarCollapsed ? "left-full" : "-left-[75px]"
} divide-y divide-custom-border-200 whitespace-nowrap rounded bg-custom-background-100 p-1 shadow-custom-shadow-xs`}
ref={helpOptionsRef}
>
<div className="space-y-1 pb-2">
{helpOptions.map(({ name, Icon, href, onClick }) => {
{helpOptions.map(({ name, Icon, href }) => {
if (href)
return (
<Link href={href} key={name} target="_blank">
@@ -111,7 +114,6 @@ export const InstanceHelpSection: FC = () => {
<button
key={name}
type="button"
onClick={onClick ?? undefined}
className="flex w-full items-center gap-x-2 rounded px-2 py-1 text-xs hover:bg-custom-background-80"
>
<div className="grid flex-shrink-0 place-items-center">
@@ -128,4 +130,4 @@ export const InstanceHelpSection: FC = () => {
</div>
</div>
);
};
});
+5
View File
@@ -0,0 +1,5 @@
export * from "./root";
export * from "./help-section";
export * from "./sidebar-menu";
export * from "./sidebar-dropdown";
export * from "./sidebar-menu-hamburger-toogle";
+57
View File
@@ -0,0 +1,57 @@
"use client";
import { FC, useEffect, useRef } from "react";
import { observer } from "mobx-react-lite";
// hooks
import { HelpSection, SidebarMenu, SidebarDropdown } from "@/components/admin-sidebar";
import { useTheme } from "@/hooks/store";
import useOutsideClickDetector from "hooks/use-outside-click-detector";
// components
export interface IInstanceSidebar {}
export const InstanceSidebar: FC<IInstanceSidebar> = observer(() => {
// store
const { isSidebarCollapsed, toggleSidebar } = useTheme();
const ref = useRef<HTMLDivElement>(null);
useOutsideClickDetector(ref, () => {
if (isSidebarCollapsed === false) {
if (window.innerWidth < 768) {
toggleSidebar(!isSidebarCollapsed);
}
}
});
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 768) {
toggleSidebar(true);
}
};
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, [toggleSidebar]);
return (
<div
className={`inset-y-0 z-20 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-custom-sidebar-border-200 bg-custom-sidebar-background-100 duration-300
fixed md:relative
${isSidebarCollapsed ? "-ml-[280px]" : ""}
sm:${isSidebarCollapsed ? "-ml-[280px]" : ""}
md:ml-0 ${isSidebarCollapsed ? "w-[80px]" : "w-[280px]"}
lg:ml-0 ${isSidebarCollapsed ? "w-[80px]" : "w-[280px]"}
`}
>
<div ref={ref} className="flex h-full w-full flex-1 flex-col">
<SidebarDropdown />
<SidebarMenu />
<HelpSection />
</div>
</div>
);
});
@@ -0,0 +1,147 @@
"use client";
import { Fragment, useEffect, useState } from "react";
import { observer } from "mobx-react-lite";
import { useTheme as useNextTheme } from "next-themes";
import { LogOut, UserCog2, Palette } from "lucide-react";
import { Menu, Transition } from "@headlessui/react";
import { Avatar } from "@plane/ui";
// hooks
import { API_BASE_URL, cn } from "@/helpers/common.helper";
import { useTheme, useUser } from "@/hooks/store";
// helpers
// services
import { AuthService } from "@/services/auth.service";
// service initialization
const authService = new AuthService();
export const SidebarDropdown = observer(() => {
// store hooks
const { isSidebarCollapsed } = useTheme();
const { currentUser, signOut } = useUser();
// hooks
const { resolvedTheme, setTheme } = useNextTheme();
// state
const [csrfToken, setCsrfToken] = useState<string | undefined>(undefined);
const handleThemeSwitch = () => {
const newTheme = resolvedTheme === "dark" ? "light" : "dark";
setTheme(newTheme);
};
const handleSignOut = () => signOut();
const getSidebarMenuItems = () => (
<Menu.Items
className={cn(
"absolute left-0 z-20 mt-1.5 flex w-52 flex-col divide-y divide-custom-sidebar-border-100 rounded-md border border-custom-sidebar-border-200 bg-custom-sidebar-background-100 px-1 py-2 text-xs shadow-lg outline-none",
{
"left-4": isSidebarCollapsed,
}
)}
>
<div className="flex flex-col gap-2.5 pb-2">
<span className="px-2 text-custom-sidebar-text-200">{currentUser?.email}</span>
</div>
<div className="py-2">
<Menu.Item
as="button"
type="button"
className="flex w-full items-center gap-2 rounded px-2 py-1 hover:bg-custom-sidebar-background-80"
onClick={handleThemeSwitch}
>
<Palette className="h-4 w-4 stroke-[1.5]" />
Switch to {resolvedTheme === "dark" ? "light" : "dark"} mode
</Menu.Item>
</div>
<div className="py-2">
<form method="POST" action={`${API_BASE_URL}/api/instances/admins/sign-out/`} onSubmit={handleSignOut}>
<input type="hidden" name="csrfmiddlewaretoken" value={csrfToken} />
<Menu.Item
as="button"
type="submit"
className="flex w-full items-center gap-2 rounded px-2 py-1 hover:bg-custom-sidebar-background-80"
>
<LogOut className="h-4 w-4 stroke-[1.5]" />
Sign out
</Menu.Item>
</form>
</div>
</Menu.Items>
);
useEffect(() => {
if (csrfToken === undefined)
authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token));
}, [csrfToken]);
return (
<div className="flex max-h-[3.75rem] items-center gap-x-5 gap-y-2 border-b border-custom-sidebar-border-200 px-4 py-3.5">
<div className="h-full w-full truncate">
<div
className={`flex flex-grow items-center gap-x-2 truncate rounded py-1 ${
isSidebarCollapsed ? "justify-center" : ""
}`}
>
<Menu as="div" className="flex-shrink-0">
<Menu.Button
className={cn("grid place-items-center outline-none", {
"cursor-default": !isSidebarCollapsed,
})}
>
<div className="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded bg-custom-sidebar-background-80">
<UserCog2 className="h-5 w-5 text-custom-text-200" />
</div>
</Menu.Button>
{isSidebarCollapsed && (
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
{getSidebarMenuItems()}
</Transition>
)}
</Menu>
{!isSidebarCollapsed && (
<div className="flex w-full gap-2">
<h4 className="grow truncate text-base font-medium text-custom-text-200">Instance admin</h4>
</div>
)}
</div>
</div>
{!isSidebarCollapsed && currentUser && (
<Menu as="div" className="relative flex-shrink-0">
<Menu.Button className="grid place-items-center outline-none">
<Avatar
name={currentUser.display_name}
src={currentUser.avatar ?? undefined}
size={24}
shape="square"
className="!text-base"
/>
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
{getSidebarMenuItems()}
</Transition>
</Menu>
)}
</div>
);
});
@@ -0,0 +1,20 @@
"use client";
import { FC } from "react";
import { observer } from "mobx-react-lite";
// hooks
import { Menu } from "lucide-react";
import { useTheme } from "@/hooks/store";
// icons
export const SidebarHamburgerToggle: FC = observer(() => {
const { isSidebarCollapsed, toggleSidebar } = useTheme();
return (
<div
className="w-7 h-7 rounded flex justify-center items-center bg-custom-background-80 transition-all hover:bg-custom-background-90 cursor-pointer group md:hidden"
onClick={() => toggleSidebar(!isSidebarCollapsed)}
>
<Menu size={14} className="text-custom-text-200 group-hover:text-custom-text-100 transition-all" />
</div>
);
});
@@ -0,0 +1,104 @@
"use client";
import { observer } from "mobx-react-lite";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Image, BrainCog, Cog, Lock, Mail } from "lucide-react";
import { Tooltip } from "@plane/ui";
// hooks
import { cn } from "@/helpers/common.helper";
import { useTheme } from "@/hooks/store";
// helpers
const INSTANCE_ADMIN_LINKS = [
{
Icon: Cog,
name: "General",
description: "Identify your instances and get key details",
href: `/general/`,
},
{
Icon: Mail,
name: "Email",
description: "Set up emails to your users",
href: `/email/`,
},
{
Icon: Lock,
name: "Authentication",
description: "Configure authentication modes",
href: `/authentication/`,
},
{
Icon: BrainCog,
name: "Artificial intelligence",
description: "Configure your OpenAI creds",
href: `/ai/`,
},
{
Icon: Image,
name: "Images in Plane",
description: "Allow third-party image libraries",
href: `/image/`,
},
];
export const SidebarMenu = observer(() => {
// store hooks
const { isSidebarCollapsed, toggleSidebar } = useTheme();
// router
const pathName = usePathname();
const handleItemClick = () => {
if (window.innerWidth < 768) {
toggleSidebar(!isSidebarCollapsed);
}
};
return (
<div className="flex h-full w-full flex-col gap-2.5 overflow-y-auto px-4 py-4">
{INSTANCE_ADMIN_LINKS.map((item, index) => {
const isActive = item.href === pathName || pathName.includes(item.href);
return (
<Link key={index} href={item.href} onClick={handleItemClick}>
<div>
<Tooltip tooltipContent={item.name} position="right" className="ml-2" disabled={!isSidebarCollapsed}>
<div
className={cn(
`group flex w-full items-center gap-3 rounded-md px-3 py-2 outline-none transition-colors`,
isActive
? "bg-custom-primary-100/10 text-custom-primary-100"
: "text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80",
isSidebarCollapsed ? "justify-center" : "w-[260px]"
)}
>
{<item.Icon className="h-4 w-4 flex-shrink-0" />}
{!isSidebarCollapsed && (
<div className="w-full ">
<div
className={cn(
`text-sm font-medium transition-colors`,
isActive ? "text-custom-primary-100" : "text-custom-sidebar-text-200"
)}
>
{item.name}
</div>
<div
className={cn(
`text-[10px] transition-colors`,
isActive ? "text-custom-primary-90" : "text-custom-sidebar-text-400"
)}
>
{item.description}
</div>
</div>
)}
</div>
</Tooltip>
</div>
</Link>
);
})}
</div>
);
});
+90
View File
@@ -0,0 +1,90 @@
"use client";
import { FC } from "react";
import { observer } from "mobx-react-lite";
import { usePathname } from "next/navigation";
// mobx
// ui
import { Settings } from "lucide-react";
// icons
import { Breadcrumbs } from "@plane/ui";
// components
import { SidebarHamburgerToggle } from "@/components/admin-sidebar";
import { BreadcrumbLink } from "components/common";
export const InstanceHeader: FC = observer(() => {
const pathName = usePathname();
const getHeaderTitle = (pathName: string) => {
switch (pathName) {
case "general":
return "General";
case "ai":
return "Artificial Intelligence";
case "email":
return "Email";
case "authentication":
return "Authentication";
case "image":
return "Image";
case "google":
return "Google";
case "github":
return "Github";
default:
return pathName.toUpperCase();
}
};
// Function to dynamically generate breadcrumb items based on pathname
const generateBreadcrumbItems = (pathname: string) => {
const pathSegments = pathname.split("/").slice(1); // removing the first empty string.
pathSegments.pop();
let currentUrl = "";
const breadcrumbItems = pathSegments.map((segment) => {
currentUrl += "/" + segment;
return {
title: getHeaderTitle(segment),
href: currentUrl,
};
});
return breadcrumbItems;
};
const breadcrumbItems = generateBreadcrumbItems(pathName);
return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-sidebar-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
<SidebarHamburgerToggle />
{breadcrumbItems.length >= 0 && (
<div>
<Breadcrumbs>
<Breadcrumbs.BreadcrumbItem
type="text"
link={
<BreadcrumbLink
href="/general/"
label="Settings"
icon={<Settings className="h-4 w-4 text-custom-text-300" />}
/>
}
/>
{breadcrumbItems.map(
(item) =>
item.title && (
<Breadcrumbs.BreadcrumbItem
key={item.title}
type="text"
link={<BreadcrumbLink href={item.href} label={item.title} />}
/>
)
)}
</Breadcrumbs>
</div>
)}
</div>
</div>
);
});
+32
View File
@@ -0,0 +1,32 @@
import { FC } from "react";
import { AlertCircle, CheckCircle2 } from "lucide-react";
type TBanner = {
type: "success" | "error";
message: string;
};
export const Banner: FC<TBanner> = (props) => {
const { type, message } = props;
return (
<div
className={`rounded-md p-2 w-full border ${type === "error" ? "bg-red-500/5 border-red-400" : "bg-green-500/5 border-green-400"}`}
>
<div className="flex items-center justify-center">
<div className="flex-shrink-0">
{type === "error" ? (
<span className="flex items-center justify-center h-6 w-6 rounded-full">
<AlertCircle className="h-5 w-5 text-red-600" aria-hidden="true" />
</span>
) : (
<CheckCircle2 className="h-5 w-5 text-green-600" aria-hidden="true" />
)}
</div>
<div className="ml-1">
<p className={`text-sm font-medium ${type === "error" ? "text-red-600" : "text-green-600"}`}>{message}</p>
</div>
</div>
</div>
);
};
@@ -0,0 +1,36 @@
import Link from "next/link";
import { Tooltip } from "@plane/ui";
type Props = {
label?: string;
href?: string;
icon?: React.ReactNode | undefined;
};
export const BreadcrumbLink: React.FC<Props> = (props) => {
const { href, label, icon } = props;
return (
<Tooltip tooltipContent={label} position="bottom">
<li className="flex items-center space-x-2" tabIndex={-1}>
<div className="flex flex-wrap items-center gap-2.5">
{href ? (
<Link
className="flex items-center gap-1 text-sm font-medium text-custom-text-300 hover:text-custom-text-100"
href={href}
>
{icon && (
<div className="flex h-5 w-5 items-center justify-center overflow-hidden !text-[1rem]">{icon}</div>
)}
<div className="relative line-clamp-1 block max-w-[150px] overflow-hidden truncate">{label}</div>
</Link>
) : (
<div className="flex cursor-default items-center gap-1 text-sm font-medium text-custom-text-100">
{icon && <div className="flex h-5 w-5 items-center justify-center overflow-hidden">{icon}</div>}
<div className="relative line-clamp-1 block max-w-[150px] overflow-hidden truncate">{label}</div>
</div>
)}
</div>
</li>
</Tooltip>
);
};
@@ -0,0 +1,83 @@
import React from "react";
import Link from "next/link";
// headless ui
import { Dialog, Transition } from "@headlessui/react";
// ui
import { Button, getButtonStyling } from "@plane/ui";
type Props = {
isOpen: boolean;
handleClose: () => void;
onDiscardHref: string;
};
export const ConfirmDiscardModal: React.FC<Props> = (props) => {
const { isOpen, handleClose, onDiscardHref } = props;
return (
<Transition.Root show={isOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-50" onClose={handleClose}>
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-custom-backdrop transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="my-10 flex items-center justify-center p-4 text-center sm:p-0 md:my-32">
<Transition.Child
as={React.Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-custom-background-100 text-left shadow-custom-shadow-md transition-all sm:my-8 sm:w-[30rem]">
<div className="px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mt-3 text-center sm:mt-0 sm:text-left">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-custom-text-300"
>
You have unsaved changes
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-custom-text-400">
Changes you made will be lost if you go back. Do you
wish to go back?
</p>
</div>
</div>
</div>
</div>
<div className="flex justify-end items-center p-4 sm:px-6 gap-2">
<Button
variant="neutral-primary"
size="sm"
onClick={handleClose}
>
Keep editing
</Button>
<Link
href={onDiscardHref}
className={getButtonStyling("primary", "sm")}
>
Go back
</Link>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
);
};
@@ -0,0 +1,86 @@
"use client";
import React, { useState } from "react";
import { Controller, Control } from "react-hook-form";
// icons
import { Eye, EyeOff } from "lucide-react";
// ui
import { Input } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common.helper";
type Props = {
control: Control<any>;
type: "text" | "password";
name: string;
label: string;
description?: string | JSX.Element;
placeholder: string;
error: boolean;
required: boolean;
};
export type TControllerInputFormField = {
key: string;
type: "text" | "password";
label: string;
description?: string | JSX.Element;
placeholder: string;
error: boolean;
required: boolean;
};
export const ControllerInput: React.FC<Props> = (props) => {
const { name, control, type, label, description, placeholder, error, required } = props;
// states
const [showPassword, setShowPassword] = useState(false);
return (
<div className="flex flex-col gap-1">
<h4 className="text-sm text-custom-text-300">
{label} {!required && "(optional)"}
</h4>
<div className="relative">
<Controller
control={control}
name={name}
rules={{ required: required ? `${label} is required.` : false }}
render={({ field: { value, onChange, ref } }) => (
<Input
id={name}
name={name}
type={type === "password" && showPassword ? "text" : type}
value={value}
onChange={onChange}
ref={ref}
hasError={error}
placeholder={placeholder}
className={cn("w-full rounded-md font-medium", {
"pr-10": type === "password",
})}
/>
)}
/>
{type === "password" &&
(showPassword ? (
<button
tabIndex={-1}
className="absolute right-3 top-2.5 flex items-center justify-center text-custom-text-400"
onClick={() => setShowPassword(false)}
>
<EyeOff className="h-4 w-4" />
</button>
) : (
<button
tabIndex={-1}
className="absolute right-3 top-2.5 flex items-center justify-center text-custom-text-400"
onClick={() => setShowPassword(true)}
>
<Eye className="h-4 w-4" />
</button>
))}
</div>
{description && <p className="text-xs text-custom-text-300">{description}</p>}
</div>
);
};
+46
View File
@@ -0,0 +1,46 @@
"use client";
import React from "react";
// ui
import { Copy } from "lucide-react";
import { Button, TOAST_TYPE, setToast } from "@plane/ui";
// icons
type Props = {
label: string;
url: string;
description: string | JSX.Element;
};
export type TCopyField = {
key: string;
label: string;
url: string;
description: string | JSX.Element;
};
export const CopyField: React.FC<Props> = (props) => {
const { label, url, description } = props;
return (
<div className="flex flex-col gap-1">
<h4 className="text-sm text-custom-text-300">{label}</h4>
<Button
variant="neutral-primary"
className="flex items-center justify-between py-2"
onClick={() => {
navigator.clipboard.writeText(url);
setToast({
type: TOAST_TYPE.INFO,
title: "Copied to clipboard",
message: `The ${label} has been successfully copied to your clipboard`,
});
}}
>
<p className="text-sm font-medium">{url}</p>
<Copy size={18} color="#B9B9B9" />
</Button>
<div className="text-xs text-custom-text-400">{description}</div>
</div>
);
};
+46
View File
@@ -0,0 +1,46 @@
import React from "react";
import Image from "next/image";
import { Button } from "@plane/ui";
type Props = {
title: string;
description?: React.ReactNode;
image?: any;
primaryButton?: {
icon?: any;
text: string;
onClick: () => void;
};
secondaryButton?: React.ReactNode;
disabled?: boolean;
};
export const EmptyState: React.FC<Props> = ({
title,
description,
image,
primaryButton,
secondaryButton,
disabled = false,
}) => (
<div className={`flex h-full w-full items-center justify-center`}>
<div className="flex w-full flex-col items-center text-center">
{image && <Image src={image} className="w-52 sm:w-60" alt={primaryButton?.text || "button image"} />}
<h6 className="mb-3 mt-6 text-xl font-semibold sm:mt-8">{title}</h6>
{description && <p className="mb-7 px-5 text-custom-text-300 sm:mb-8">{description}</p>}
<div className="flex items-center gap-4">
{primaryButton && (
<Button
variant="primary"
prependIcon={primaryButton.icon}
onClick={primaryButton.onClick}
disabled={disabled}
>
{primaryButton.text}
</Button>
)}
{secondaryButton}
</div>
</div>
</div>
);
+9
View File
@@ -0,0 +1,9 @@
export * from "./breadcrumb-link";
export * from "./confirm-discard-modal";
export * from "./controller-input";
export * from "./copy-field";
export * from "./password-strength-meter";
export * from "./banner";
export * from "./empty-state";
export * from "./logo-spinner";
export * from "./toast";
+17
View File
@@ -0,0 +1,17 @@
import Image from "next/image";
import { useTheme } from "next-themes";
// assets
import LogoSpinnerDark from "@/public/images/logo-spinner-dark.gif";
import LogoSpinnerLight from "@/public/images/logo-spinner-light.gif";
export const LogoSpinner = () => {
const { resolvedTheme } = useTheme();
const logoSrc = resolvedTheme === "dark" ? LogoSpinnerDark : LogoSpinnerLight;
return (
<div className="flex items-center justify-center">
<Image src={logoSrc} alt="logo" className="w-[82px] h-[82px] mr-2" priority={false} />
</div>
);
};
@@ -0,0 +1,69 @@
"use client";
// helpers
import { CircleCheck } from "lucide-react";
import { cn } from "@/helpers/common.helper";
import { getPasswordStrength } from "@/helpers/password.helper";
// icons
type Props = {
password: string;
};
export const PasswordStrengthMeter: React.FC<Props> = (props: Props) => {
const { password } = props;
const strength = getPasswordStrength(password);
let bars = [];
let text = "";
let textColor = "";
if (password.length === 0) {
bars = [`bg-[#F0F0F3]`, `bg-[#F0F0F3]`, `bg-[#F0F0F3]`];
text = "Password requirements";
} else if (password.length < 8) {
bars = [`bg-[#DC3E42]`, `bg-[#F0F0F3]`, `bg-[#F0F0F3]`];
text = "Password is too short";
textColor = `text-[#DC3E42]`;
} else if (strength < 3) {
bars = [`bg-[#FFBA18]`, `bg-[#FFBA18]`, `bg-[#F0F0F3]`];
text = "Password is weak";
textColor = `text-[#FFBA18]`;
} else {
bars = [`bg-[#3E9B4F]`, `bg-[#3E9B4F]`, `bg-[#3E9B4F]`];
text = "Password is strong";
textColor = `text-[#3E9B4F]`;
}
const criteria = [
{ label: "Min 8 characters", isValid: password.length >= 8 },
{ label: "Min 1 upper-case letter", isValid: /[A-Z]/.test(password) },
{ label: "Min 1 number", isValid: /\d/.test(password) },
{ label: "Min 1 special character", isValid: /[!@#$%^&*]/.test(password) },
];
return (
<div className="w-full">
<div className="flex w-full gap-1.5">
{bars.map((color, index) => (
<div key={index} className={cn("w-full h-1 rounded-full", color)} />
))}
</div>
<p className={cn("text-xs font-medium py-1", textColor)}>{text}</p>
<div className="flex flex-wrap gap-x-4 gap-y-2">
{criteria.map((criterion, index) => (
<div
key={index}
className={cn(
"flex items-center gap-1 text-xs font-medium",
criterion.isValid ? `text-[#3E9B4F]` : "text-custom-text-400"
)}
>
<CircleCheck width={14} height={14} />
{criterion.label}
</div>
))}
</div>
</div>
);
};
+11
View File
@@ -0,0 +1,11 @@
import { useTheme } from "next-themes";
// ui
import { Toast as ToastComponent } from "@plane/ui";
// helpers
import { resolveGeneralTheme } from "@/helpers/common.helper";
export const Toast = () => {
const { theme } = useTheme();
return <ToastComponent theme={resolveGeneralTheme(theme)} />;
};
+1
View File
@@ -0,0 +1 @@
export * from "./page-header";
+17
View File
@@ -0,0 +1,17 @@
"use client";
type TPageHeader = {
title?: string;
description?: string;
};
export const PageHeader: React.FC<TPageHeader> = (props) => {
const { title = "God Mode - Plane", description = "Plane god mode" } = props;
return (
<>
<title>{title}</title>
<meta name="description" content={description} />
</>
);
};
+3
View File
@@ -0,0 +1,3 @@
export * from "./instance-not-ready";
export * from "./instance-failure-view";
export * from "./setup-form";
@@ -0,0 +1,42 @@
"use client";
import { FC } from "react";
import Image from "next/image";
import { useTheme } from "next-themes";
import { Button } from "@plane/ui";
// assets
import InstanceFailureDarkImage from "@/public/instance/instance-failure-dark.svg";
import InstanceFailureImage from "@/public/instance/instance-failure.svg";
type InstanceFailureViewProps = {
// mutate: () => void;
};
export const InstanceFailureView: FC<InstanceFailureViewProps> = () => {
const { resolvedTheme } = useTheme();
const instanceImage = resolvedTheme === "dark" ? InstanceFailureDarkImage : InstanceFailureImage;
const handleRetry = () => {
window.location.reload();
};
return (
<div className="h-full w-full relative container px-5 mx-auto flex justify-center items-center">
<div className="w-auto max-w-2xl relative space-y-8 py-10">
<div className="relative flex flex-col justify-center items-center space-y-4">
<Image src={instanceImage} alt="Plane Logo" />
<h3 className="font-medium text-2xl text-white ">Unable to fetch instance details.</h3>
<p className="font-medium text-base text-center">
We were unable to fetch the details of the instance. <br />
Fret not, it might just be a connectivity issue.
</p>
</div>
<div className="flex justify-center">
<Button size="md" onClick={handleRetry}>
Retry
</Button>
</div>
</div>
</div>
);
};
@@ -0,0 +1,30 @@
"use client";
import { FC } from "react";
import Image from "next/image";
import Link from "next/link";
import { Button } from "@plane/ui";
// assets
import PlaneTakeOffImage from "@/public/images/plane-takeoff.png";
export const InstanceNotReady: FC = () => (
<div className="h-full w-full relative container px-5 mx-auto flex justify-center items-center">
<div className="w-auto max-w-2xl relative space-y-8 py-10">
<div className="relative flex flex-col justify-center items-center space-y-4">
<h1 className="text-3xl font-bold pb-3">Welcome aboard Plane!</h1>
<Image src={PlaneTakeOffImage} alt="Plane Logo" />
<p className="font-medium text-base text-onboarding-text-400">
Get started by setting up your instance and workspace
</p>
</div>
<div>
<Link href={"/setup/?auth_enabled=0"}>
<Button size="lg" className="w-full">
Get started
</Button>
</Link>
</div>
</div>
</div>
);
+354
View File
@@ -0,0 +1,354 @@
"use client";
import { FC, useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
// icons
import { Eye, EyeOff } from "lucide-react";
// ui
import { Button, Checkbox, Input, Spinner } from "@plane/ui";
// components
import { Banner, PasswordStrengthMeter } from "@/components/common";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
import { getPasswordStrength } from "@/helpers/password.helper";
// services
import { AuthService } from "@/services/auth.service";
// service initialization
const authService = new AuthService();
// error codes
enum EErrorCodes {
INSTANCE_NOT_CONFIGURED = "INSTANCE_NOT_CONFIGURED",
ADMIN_ALREADY_EXIST = "ADMIN_ALREADY_EXIST",
REQUIRED_EMAIL_PASSWORD_FIRST_NAME = "REQUIRED_EMAIL_PASSWORD_FIRST_NAME",
INVALID_EMAIL = "INVALID_EMAIL",
INVALID_PASSWORD = "INVALID_PASSWORD",
USER_ALREADY_EXISTS = "USER_ALREADY_EXISTS",
}
type TError = {
type: EErrorCodes | undefined;
message: string | undefined;
};
// form data
type TFormData = {
first_name: string;
last_name: string;
email: string;
company_name: string;
password: string;
confirm_password?: string;
is_telemetry_enabled: boolean;
};
const defaultFromData: TFormData = {
first_name: "",
last_name: "",
email: "",
company_name: "",
password: "",
is_telemetry_enabled: true,
};
export const InstanceSetupForm: FC = (props) => {
const {} = props;
// search params
const searchParams = useSearchParams();
const firstNameParam = searchParams.get("first_name") || undefined;
const lastNameParam = searchParams.get("last_name") || undefined;
const companyParam = searchParams.get("company") || undefined;
const emailParam = searchParams.get("email") || undefined;
const isTelemetryEnabledParam = (searchParams.get("is_telemetry_enabled") === "True" ? true : false) || true;
const errorCode = searchParams.get("error_code") || undefined;
const errorMessage = searchParams.get("error_message") || undefined;
// state
const [showPassword, setShowPassword] = useState({
password: false,
retypePassword: false,
});
const [csrfToken, setCsrfToken] = useState<string | undefined>(undefined);
const [formData, setFormData] = useState<TFormData>(defaultFromData);
const [isPasswordInputFocused, setIsPasswordInputFocused] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [isRetryPasswordInputFocused, setIsRetryPasswordInputFocused] = useState(false);
const handleShowPassword = (key: keyof typeof showPassword) =>
setShowPassword((prev) => ({ ...prev, [key]: !prev[key] }));
const handleFormChange = (key: keyof TFormData, value: string | boolean) =>
setFormData((prev) => ({ ...prev, [key]: value }));
useEffect(() => {
if (csrfToken === undefined)
authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token));
}, [csrfToken]);
useEffect(() => {
if (firstNameParam) setFormData((prev) => ({ ...prev, first_name: firstNameParam }));
if (lastNameParam) setFormData((prev) => ({ ...prev, last_name: lastNameParam }));
if (companyParam) setFormData((prev) => ({ ...prev, company_name: companyParam }));
if (emailParam) setFormData((prev) => ({ ...prev, email: emailParam }));
if (isTelemetryEnabledParam) setFormData((prev) => ({ ...prev, is_telemetry_enabled: isTelemetryEnabledParam }));
}, [firstNameParam, lastNameParam, companyParam, emailParam, isTelemetryEnabledParam]);
// derived values
const errorData: TError = useMemo(() => {
if (errorCode && errorMessage) {
switch (errorCode) {
case EErrorCodes.INSTANCE_NOT_CONFIGURED:
return { type: EErrorCodes.INSTANCE_NOT_CONFIGURED, message: errorMessage };
case EErrorCodes.ADMIN_ALREADY_EXIST:
return { type: EErrorCodes.ADMIN_ALREADY_EXIST, message: errorMessage };
case EErrorCodes.REQUIRED_EMAIL_PASSWORD_FIRST_NAME:
return { type: EErrorCodes.REQUIRED_EMAIL_PASSWORD_FIRST_NAME, message: errorMessage };
case EErrorCodes.INVALID_EMAIL:
return { type: EErrorCodes.INVALID_EMAIL, message: errorMessage };
case EErrorCodes.INVALID_PASSWORD:
return { type: EErrorCodes.INVALID_PASSWORD, message: errorMessage };
case EErrorCodes.USER_ALREADY_EXISTS:
return { type: EErrorCodes.USER_ALREADY_EXISTS, message: errorMessage };
default:
return { type: undefined, message: undefined };
}
} else return { type: undefined, message: undefined };
}, [errorCode, errorMessage]);
const isButtonDisabled = useMemo(
() =>
!isSubmitting &&
formData.first_name &&
formData.email &&
formData.password &&
getPasswordStrength(formData.password) >= 3 &&
formData.password === formData.confirm_password
? false
: true,
[formData.confirm_password, formData.email, formData.first_name, formData.password, isSubmitting]
);
const password = formData?.password ?? "";
const confirmPassword = formData?.confirm_password ?? "";
const renderPasswordMatchError = !isRetryPasswordInputFocused || confirmPassword.length >= password.length;
return (
<div className="max-w-lg lg:max-w-md w-full">
<div className="relative flex flex-col space-y-6">
<div className="text-center space-y-1">
<h3 className="flex gap-4 justify-center text-3xl font-bold text-onboarding-text-100">
Setup your Plane Instance
</h3>
<p className="font-medium text-onboarding-text-400">
Post setup you will be able to manage this Plane instance.
</p>
</div>
{errorData.type &&
errorData?.message &&
![EErrorCodes.INVALID_EMAIL, EErrorCodes.INVALID_PASSWORD].includes(errorData.type) && (
<Banner type="error" message={errorData?.message} />
)}
<form
className="space-y-4"
method="POST"
action={`${API_BASE_URL}/api/instances/admins/sign-up/`}
onSubmit={() => setIsSubmitting(true)}
onError={() => setIsSubmitting(false)}
>
<input type="hidden" name="csrfmiddlewaretoken" value={csrfToken} />
<div className="flex flex-col sm:flex-row items-center gap-4">
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="first_name">
First name <span className="text-red-500">*</span>
</label>
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="first_name"
name="first_name"
type="text"
inputSize="md"
placeholder="Wilber"
value={formData.first_name}
onChange={(e) => handleFormChange("first_name", e.target.value)}
autoFocus
/>
</div>
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="last_name">
Last name <span className="text-red-500">*</span>
</label>
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="last_name"
name="last_name"
type="text"
inputSize="md"
placeholder="Wright"
value={formData.last_name}
onChange={(e) => handleFormChange("last_name", e.target.value)}
/>
</div>
</div>
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="email">
Email <span className="text-red-500">*</span>
</label>
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="email"
name="email"
type="email"
inputSize="md"
placeholder="name@company.com"
value={formData.email}
onChange={(e) => handleFormChange("email", e.target.value)}
hasError={errorData.type && errorData.type === EErrorCodes.INVALID_EMAIL ? true : false}
/>
{errorData.type && errorData.type === EErrorCodes.INVALID_EMAIL && errorData.message && (
<p className="px-1 text-xs text-red-500">{errorData.message}</p>
)}
</div>
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="company_name">
Company name <span className="text-red-500">*</span>
</label>
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="company_name"
name="company_name"
type="text"
inputSize="md"
placeholder="Company name"
value={formData.company_name}
onChange={(e) => handleFormChange("company_name", e.target.value)}
/>
</div>
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="password">
Set a password <span className="text-red-500">*</span>
</label>
<div className="relative">
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="password"
name="password"
type={showPassword.password ? "text" : "password"}
inputSize="md"
placeholder="New password..."
value={formData.password}
onChange={(e) => handleFormChange("password", e.target.value)}
hasError={errorData.type && errorData.type === EErrorCodes.INVALID_PASSWORD ? true : false}
onFocus={() => setIsPasswordInputFocused(true)}
onBlur={() => setIsPasswordInputFocused(false)}
/>
{showPassword.password ? (
<button
type="button"
tabIndex={-1}
className="absolute right-3 top-3.5 flex items-center justify-center text-custom-text-400"
onClick={() => handleShowPassword("password")}
>
<EyeOff className="h-4 w-4" />
</button>
) : (
<button
type="button"
tabIndex={-1}
className="absolute right-3 top-3.5 flex items-center justify-center text-custom-text-400"
onClick={() => handleShowPassword("password")}
>
<Eye className="h-4 w-4" />
</button>
)}
</div>
{errorData.type && errorData.type === EErrorCodes.INVALID_PASSWORD && errorData.message && (
<p className="px-1 text-xs text-red-500">{errorData.message}</p>
)}
{isPasswordInputFocused && <PasswordStrengthMeter password={formData.password} />}
</div>
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="confirm_password">
Confirm password <span className="text-red-500">*</span>
</label>
<div className="relative">
<Input
type={showPassword.retypePassword ? "text" : "password"}
id="confirm_password"
name="confirm_password"
inputSize="md"
value={formData.confirm_password}
onChange={(e) => handleFormChange("confirm_password", e.target.value)}
placeholder="Confirm password"
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
onFocus={() => setIsRetryPasswordInputFocused(true)}
onBlur={() => setIsRetryPasswordInputFocused(false)}
/>
{showPassword.retypePassword ? (
<button
type="button"
tabIndex={-1}
className="absolute right-3 top-3.5 flex items-center justify-center text-custom-text-400"
onClick={() => handleShowPassword("retypePassword")}
>
<EyeOff className="h-4 w-4" />
</button>
) : (
<button
type="button"
tabIndex={-1}
className="absolute right-3 top-3.5 flex items-center justify-center text-custom-text-400"
onClick={() => handleShowPassword("retypePassword")}
>
<Eye className="h-4 w-4" />
</button>
)}
</div>
{!!formData.confirm_password &&
formData.password !== formData.confirm_password &&
renderPasswordMatchError && <span className="text-sm text-red-500">Passwords don{"'"}t match</span>}
</div>
<div className="relative flex items-center pt-2 gap-2">
<div>
<Checkbox
id="is_telemetry_enabled"
name="is_telemetry_enabled"
value={formData.is_telemetry_enabled ? "True" : "False"}
onChange={() => handleFormChange("is_telemetry_enabled", !formData.is_telemetry_enabled)}
checked={formData.is_telemetry_enabled}
/>
</div>
<label
className="text-sm text-onboarding-text-300 font-medium cursor-pointer"
htmlFor="is_telemetry_enabled"
>
Allow Plane to anonymously collect usage events.
</label>
<a
tabIndex={-1}
href="https://docs.plane.so/telemetry"
target="_blank"
rel="noopener noreferrer"
className="text-sm font-medium text-blue-500 hover:text-blue-600"
>
See More
</a>
</div>
<div className="py-2">
<Button type="submit" size="lg" className="w-full" disabled={isButtonDisabled}>
{isSubmitting ? <Spinner height="20px" width="20px" /> : "Continue"}
</Button>
</div>
</form>
</div>
</div>
);
};
@@ -1,2 +1 @@
export * from "./root";
export * from "./sign-in-form";
+179
View File
@@ -0,0 +1,179 @@
"use client";
import { FC, useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
// services
import { Eye, EyeOff } from "lucide-react";
import { Button, Input, Spinner } from "@plane/ui";
// components
import { Banner } from "@/components/common";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
import { AuthService } from "@/services/auth.service";
// ui
// icons
// service initialization
const authService = new AuthService();
// error codes
enum EErrorCodes {
INSTANCE_NOT_CONFIGURED = "INSTANCE_NOT_CONFIGURED",
REQUIRED_EMAIL_PASSWORD = "REQUIRED_EMAIL_PASSWORD",
INVALID_EMAIL = "INVALID_EMAIL",
USER_DOES_NOT_EXIST = "USER_DOES_NOT_EXIST",
AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED",
}
type TError = {
type: EErrorCodes | undefined;
message: string | undefined;
};
// form data
type TFormData = {
email: string;
password: string;
};
const defaultFromData: TFormData = {
email: "",
password: "",
};
export const InstanceSignInForm: FC = (props) => {
const {} = props;
// search params
const searchParams = useSearchParams();
const emailParam = searchParams.get("email") || undefined;
const errorCode = searchParams.get("error_code") || undefined;
const errorMessage = searchParams.get("error_message") || undefined;
// state
const [showPassword, setShowPassword] = useState(false);
const [csrfToken, setCsrfToken] = useState<string | undefined>(undefined);
const [formData, setFormData] = useState<TFormData>(defaultFromData);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleFormChange = (key: keyof TFormData, value: string | boolean) =>
setFormData((prev) => ({ ...prev, [key]: value }));
console.log("csrfToken", csrfToken);
useEffect(() => {
if (csrfToken === undefined)
authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token));
}, [csrfToken]);
useEffect(() => {
if (emailParam) setFormData((prev) => ({ ...prev, email: emailParam }));
}, [emailParam]);
// derived values
const errorData: TError = useMemo(() => {
if (errorCode && errorMessage) {
switch (errorCode) {
case EErrorCodes.INSTANCE_NOT_CONFIGURED:
return { type: EErrorCodes.INVALID_EMAIL, message: errorMessage };
case EErrorCodes.REQUIRED_EMAIL_PASSWORD:
return { type: EErrorCodes.REQUIRED_EMAIL_PASSWORD, message: errorMessage };
case EErrorCodes.INVALID_EMAIL:
return { type: EErrorCodes.INVALID_EMAIL, message: errorMessage };
case EErrorCodes.USER_DOES_NOT_EXIST:
return { type: EErrorCodes.USER_DOES_NOT_EXIST, message: errorMessage };
case EErrorCodes.AUTHENTICATION_FAILED:
return { type: EErrorCodes.AUTHENTICATION_FAILED, message: errorMessage };
default:
return { type: undefined, message: undefined };
}
} else return { type: undefined, message: undefined };
}, [errorCode, errorMessage]);
const isButtonDisabled = useMemo(
() => (!isSubmitting && formData.email && formData.password ? false : true),
[formData.email, formData.password, isSubmitting]
);
return (
<div className="flex-grow container mx-auto max-w-lg px-10 lg:max-w-md lg:px-5 py-10 lg:pt-28 transition-all">
<div className="relative flex flex-col space-y-6">
<div className="text-center space-y-1">
<h3 className="flex gap-4 justify-center text-3xl font-bold text-onboarding-text-100">
Manage your Plane instance
</h3>
<p className="font-medium text-onboarding-text-400">
Configure instance-wide settings to secure your instance
</p>
</div>
{errorData.type && errorData?.message && <Banner type="error" message={errorData?.message} />}
<form
className="space-y-4"
method="POST"
action={`${API_BASE_URL}/api/instances/admins/sign-in/`}
onSubmit={() => setIsSubmitting(true)}
onError={() => setIsSubmitting(false)}
>
<input type="hidden" name="csrfmiddlewaretoken" value={csrfToken} />
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="email">
Email <span className="text-red-500">*</span>
</label>
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="email"
name="email"
type="email"
inputSize="md"
placeholder="name@company.com"
value={formData.email}
onChange={(e) => handleFormChange("email", e.target.value)}
autoFocus
/>
</div>
<div className="w-full space-y-1">
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="password">
Password <span className="text-red-500">*</span>
</label>
<div className="relative">
<Input
className="w-full border border-onboarding-border-100 !bg-onboarding-background-200 placeholder:text-onboarding-text-400"
id="password"
name="password"
type={showPassword ? "text" : "password"}
inputSize="md"
placeholder="Enter your password"
value={formData.password}
onChange={(e) => handleFormChange("password", e.target.value)}
/>
{showPassword ? (
<button
type="button"
className="absolute right-3 top-3.5 flex items-center justify-center text-custom-text-400"
onClick={() => setShowPassword(false)}
>
<EyeOff className="h-4 w-4" />
</button>
) : (
<button
type="button"
className="absolute right-3 top-3.5 flex items-center justify-center text-custom-text-400"
onClick={() => setShowPassword(true)}
>
<Eye className="h-4 w-4" />
</button>
)}
</div>
</div>
<div className="py-2">
<Button type="submit" size="lg" className="w-full" disabled={isButtonDisabled}>
{isSubmitting ? <Spinner height="20px" width="20px" /> : "Sign in"}
</Button>
</div>
</form>
</div>
</div>
);
};
+56
View File
@@ -0,0 +1,56 @@
"use client";
import React from "react";
import { observer } from "mobx-react-lite";
import Image from "next/image";
import { useTheme as nextUseTheme } from "next-themes";
// ui
import { Button, getButtonStyling } from "@plane/ui";
// helpers
import { resolveGeneralTheme } from "helpers/common.helper";
// hooks
import { useInstance, useTheme } from "@/hooks/store";
// icons
import TakeoffIconLight from "/public/logos/takeoff-icon-light.svg";
import TakeoffIconDark from "/public/logos/takeoff-icon-dark.svg";
export const NewUserPopup: React.FC = observer(() => {
// hooks
const { isNewUserPopup, toggleNewUserPopup } = useTheme();
const { config } = useInstance();
// theme
const { resolvedTheme } = nextUseTheme();
const redirectionLink = `${config?.app_base_url ? `${config?.app_base_url}/create-workspace` : `/god-mode/`}`;
if (!isNewUserPopup) return <></>;
return (
<div className="absolute bottom-8 right-8 p-6 w-96 border border-custom-border-100 shadow-md rounded-lg bg-custom-background-100">
<div className="flex gap-4">
<div className="grow">
<div className="text-base font-semibold">Create workspace</div>
<div className="py-2 text-sm font-medium text-custom-text-300">
Instance setup done! Welcome to Plane instance portal. Start your journey with by creating your first
workspace, you will need to login again.
</div>
<div className="flex items-center gap-4 pt-2">
<a href={redirectionLink} className={getButtonStyling("primary", "sm")}>
Create workspace
</a>
<Button variant="neutral-primary" size="sm" onClick={toggleNewUserPopup}>
Close
</Button>
</div>
</div>
<div className="shrink-0 flex items-center justify-center">
<Image
src={resolveGeneralTheme(resolvedTheme) === "dark" ? TakeoffIconDark : TakeoffIconLight}
height={80}
width={80}
alt="Plane icon"
/>
</div>
</div>
</div>
);
});
+8
View File
@@ -0,0 +1,8 @@
export const SITE_NAME = "Plane | Simple, extensible, open-source project management tool.";
export const SITE_TITLE = "Plane | Simple, extensible, open-source project management tool.";
export const SITE_DESCRIPTION =
"Open-source project management tool to manage issues, sprints, and product roadmaps with peace of mind.";
export const SITE_KEYWORDS =
"software development, plan, ship, software, accelerate, code management, release management, project management, issue tracking, agile, scrum, kanban, collaboration";
export const SITE_URL = "https://app.plane.so/";
export const TWITTER_USER_NAME = "Plane | Simple, extensible, open-source project management tool.";
+8
View File
@@ -0,0 +1,8 @@
export const SWR_CONFIG = {
refreshWhenHidden: false,
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnMount: true,
refreshInterval: 600000,
errorRetryCount: 3,
};
+136
View File
@@ -0,0 +1,136 @@
import { ReactNode } from "react";
import Link from "next/link";
// helpers
import { SUPPORT_EMAIL } from "./common.helper";
export enum EPageTypes {
PUBLIC = "PUBLIC",
NON_AUTHENTICATED = "NON_AUTHENTICATED",
SET_PASSWORD = "SET_PASSWORD",
ONBOARDING = "ONBOARDING",
AUTHENTICATED = "AUTHENTICATED",
}
export enum EAuthModes {
SIGN_IN = "SIGN_IN",
SIGN_UP = "SIGN_UP",
}
export enum EAuthSteps {
EMAIL = "EMAIL",
PASSWORD = "PASSWORD",
UNIQUE_CODE = "UNIQUE_CODE",
}
export enum EErrorAlertType {
BANNER_ALERT = "BANNER_ALERT",
INLINE_FIRST_NAME = "INLINE_FIRST_NAME",
INLINE_EMAIL = "INLINE_EMAIL",
INLINE_PASSWORD = "INLINE_PASSWORD",
INLINE_EMAIL_CODE = "INLINE_EMAIL_CODE",
}
export enum EAuthenticationErrorCodes {
// Admin
ADMIN_ALREADY_EXIST = "5150",
REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME = "5155",
INVALID_ADMIN_EMAIL = "5160",
INVALID_ADMIN_PASSWORD = "5165",
REQUIRED_ADMIN_EMAIL_PASSWORD = "5170",
ADMIN_AUTHENTICATION_FAILED = "5175",
ADMIN_USER_ALREADY_EXIST = "5180",
ADMIN_USER_DOES_NOT_EXIST = "5185",
ADMIN_USER_DEACTIVATED = "5190",
}
export type TAuthErrorInfo = {
type: EErrorAlertType;
code: EAuthenticationErrorCodes;
title: string;
message: ReactNode;
};
const errorCodeMessages: {
[key in EAuthenticationErrorCodes]: { title: string; message: (email?: string | undefined) => ReactNode };
} = {
// admin
[EAuthenticationErrorCodes.ADMIN_ALREADY_EXIST]: {
title: `Admin already exists`,
message: () => `Admin already exists. Please try again.`,
},
[EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME]: {
title: `Email, password and first name required`,
message: () => `Email, password and first name required. Please try again.`,
},
[EAuthenticationErrorCodes.INVALID_ADMIN_EMAIL]: {
title: `Invalid admin email`,
message: () => `Invalid admin email. Please try again.`,
},
[EAuthenticationErrorCodes.INVALID_ADMIN_PASSWORD]: {
title: `Invalid admin password`,
message: () => `Invalid admin password. Please try again.`,
},
[EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD]: {
title: `Email and password required`,
message: () => `Email and password required. Please try again.`,
},
[EAuthenticationErrorCodes.ADMIN_AUTHENTICATION_FAILED]: {
title: `Authentication failed`,
message: () => `Authentication failed. Please try again.`,
},
[EAuthenticationErrorCodes.ADMIN_USER_ALREADY_EXIST]: {
title: `Admin user already exists`,
message: () => (
<div>
Admin user already exists.&nbsp;
<Link className="underline underline-offset-4 font-medium hover:font-bold transition-all" href={`/admin`}>
Sign In
</Link>
&nbsp;now.
</div>
),
},
[EAuthenticationErrorCodes.ADMIN_USER_DOES_NOT_EXIST]: {
title: `Admin user does not exist`,
message: () => (
<div>
Admin user does not exist.&nbsp;
<Link className="underline underline-offset-4 font-medium hover:font-bold transition-all" href={`/admin`}>
Sign In
</Link>
&nbsp;now.
</div>
),
},
[EAuthenticationErrorCodes.ADMIN_USER_DEACTIVATED]: {
title: `User account deactivated`,
message: () => `User account deactivated. Please contact ${!!SUPPORT_EMAIL ? SUPPORT_EMAIL : "administrator"}.`,
},
};
export const authErrorHandler = (
errorCode: EAuthenticationErrorCodes,
email?: string | undefined
): TAuthErrorInfo | undefined => {
const bannerAlertErrorCodes = [
EAuthenticationErrorCodes.ADMIN_ALREADY_EXIST,
EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME,
EAuthenticationErrorCodes.INVALID_ADMIN_EMAIL,
EAuthenticationErrorCodes.INVALID_ADMIN_PASSWORD,
EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD,
EAuthenticationErrorCodes.ADMIN_AUTHENTICATION_FAILED,
EAuthenticationErrorCodes.ADMIN_USER_ALREADY_EXIST,
EAuthenticationErrorCodes.ADMIN_USER_DOES_NOT_EXIST,
EAuthenticationErrorCodes.ADMIN_USER_DEACTIVATED,
];
if (bannerAlertErrorCodes.includes(errorCode))
return {
type: EErrorAlertType.BANNER_ALERT,
code: errorCode,
title: errorCodeMessages[errorCode]?.title || "Error",
message: errorCodeMessages[errorCode]?.message(email) || "Something went wrong. Please try again.",
};
return undefined;
};
+20
View File
@@ -0,0 +1,20 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || "";
export const ADMIN_BASE_PATH = process.env.NEXT_PUBLIC_ADMIN_BASE_PATH || "";
export const SPACE_BASE_URL = process.env.NEXT_PUBLIC_SPACE_BASE_URL || "";
export const SPACE_BASE_PATH = process.env.NEXT_PUBLIC_SPACE_BASE_PATH || "";
export const WEB_BASE_URL = process.env.NEXT_PUBLIC_WEB_BASE_URL || "";
export const SUPPORT_EMAIL = process.env.NEXT_PUBLIC_SUPPORT_EMAIL || "";
export const ASSET_PREFIX = ADMIN_BASE_PATH;
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));
export const resolveGeneralTheme = (resolvedTheme: string | undefined) =>
resolvedTheme?.includes("light") ? "light" : resolvedTheme?.includes("dark") ? "dark" : "system";
+2
View File
@@ -0,0 +1,2 @@
export * from "./instance.helper";
export * from "./user.helper";
+9
View File
@@ -0,0 +1,9 @@
export enum EInstanceStatus {
ERROR = "ERROR",
NOT_YET_READY = "NOT_YET_READY",
}
export type TInstanceStatus = {
status: EInstanceStatus | undefined;
data?: object;
};
+16
View File
@@ -0,0 +1,16 @@
import zxcvbn from "zxcvbn";
export const isPasswordCriteriaMet = (password: string) => {
const criteria = [password.length >= 8, /[A-Z]/.test(password), /\d/.test(password), /[!@#$%^&*]/.test(password)];
return criteria.every((criterion) => criterion);
};
export const getPasswordStrength = (password: string) => {
if (password.length === 0) return 0;
if (password.length < 8) return 1;
if (!isPasswordCriteriaMet(password)) return 2;
const result = zxcvbn(password);
return result.score;
};
+21
View File
@@ -0,0 +1,21 @@
export enum EAuthenticationPageType {
STATIC = "STATIC",
NOT_AUTHENTICATED = "NOT_AUTHENTICATED",
AUTHENTICATED = "AUTHENTICATED",
}
export enum EInstancePageType {
PRE_SETUP = "PRE_SETUP",
POST_SETUP = "POST_SETUP",
}
export enum EUserStatus {
ERROR = "ERROR",
AUTHENTICATION_NOT_DONE = "AUTHENTICATION_NOT_DONE",
NOT_YET_READY = "NOT_YET_READY",
}
export type TUserStatus = {
status: EUserStatus | undefined;
message?: string;
};
+3
View File
@@ -0,0 +1,3 @@
export * from "./use-theme";
export * from "./use-instance";
export * from "./use-user";
+10
View File
@@ -0,0 +1,10 @@
import { useContext } from "react";
// store
import { StoreContext } from "@/lib/store-provider";
import { IInstanceStore } from "@/store/instance.store";
export const useInstance = (): IInstanceStore => {
const context = useContext(StoreContext);
if (context === undefined) throw new Error("useInstance must be used within StoreProvider");
return context.instance;
};
+10
View File
@@ -0,0 +1,10 @@
import { useContext } from "react";
// store
import { StoreContext } from "@/lib/store-provider";
import { IThemeStore } from "@/store/theme.store";
export const useTheme = (): IThemeStore => {
const context = useContext(StoreContext);
if (context === undefined) throw new Error("useTheme must be used within StoreProvider");
return context.theme;
};
+10
View File
@@ -0,0 +1,10 @@
import { useContext } from "react";
// store
import { StoreContext } from "@/lib/store-provider";
import { IUserStore } from "@/store/user.store";
export const useUser = (): IUserStore => {
const context = useContext(StoreContext);
if (context === undefined) throw new Error("useUser must be used within StoreProvider");
return context.user;
};
@@ -0,0 +1,21 @@
"use client";
import React, { useEffect } from "react";
const useOutsideClickDetector = (ref: React.RefObject<HTMLElement>, callback: () => void) => {
const handleClick = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
callback();
}
};
useEffect(() => {
document.addEventListener("mousedown", handleClick);
return () => {
document.removeEventListener("mousedown", handleClick);
};
});
};
export default useOutsideClickDetector;
+47
View File
@@ -0,0 +1,47 @@
"use client";
import { FC, ReactNode, useEffect } from "react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/navigation";
// components
import { InstanceSidebar } from "@/components/admin-sidebar";
import { InstanceHeader } from "@/components/auth-header";
import { LogoSpinner } from "@/components/common";
import { NewUserPopup } from "@/components/new-user-popup";
// hooks
import { useUser } from "@/hooks/store";
type TAdminLayout = {
children: ReactNode;
};
export const AdminLayout: FC<TAdminLayout> = observer((props) => {
const { children } = props;
// router
const router = useRouter();
const { isUserLoggedIn } = useUser();
useEffect(() => {
if (isUserLoggedIn === false) {
router.push("/");
}
}, [router, isUserLoggedIn]);
if (isUserLoggedIn === undefined) {
return (
<div className="relative flex h-screen w-full items-center justify-center">
<LogoSpinner />
</div>
);
}
return (
<div className="relative flex h-screen w-screen overflow-hidden">
<InstanceSidebar />
<main className="relative flex h-full w-full flex-col overflow-hidden bg-custom-background-100">
<InstanceHeader />
<div className="h-full w-full overflow-hidden">{children}</div>
</main>
<NewUserPopup />
</div>
);
});
+45
View File
@@ -0,0 +1,45 @@
"use client";
import { FC, ReactNode } from "react";
import Image from "next/image";
import Link from "next/link";
import { useTheme } from "next-themes";
// logo/ images
import PlaneBackgroundPatternDark from "public/auth/background-pattern-dark.svg";
import PlaneBackgroundPattern from "public/auth/background-pattern.svg";
import BlackHorizontalLogo from "public/plane-logos/black-horizontal-with-blue-logo.png";
import WhiteHorizontalLogo from "public/plane-logos/white-horizontal-with-blue-logo.png";
type TDefaultLayout = {
children: ReactNode;
withoutBackground?: boolean;
};
export const DefaultLayout: FC<TDefaultLayout> = (props) => {
const { children, withoutBackground = false } = props;
// hooks
const { resolvedTheme } = useTheme();
const patternBackground = resolvedTheme === "dark" ? PlaneBackgroundPatternDark : PlaneBackgroundPattern;
const logo = resolvedTheme === "light" ? BlackHorizontalLogo : WhiteHorizontalLogo;
return (
<div className="relative">
<div className="h-screen w-full overflow-hidden overflow-y-auto flex flex-col">
<div className="container h-[110px] flex-shrink-0 mx-auto px-5 lg:px-0 flex items-center justify-between gap-5 z-50">
<div className="flex items-center gap-x-2 py-10">
<Link href={`/`} className="h-[30px] w-[133px]">
<Image src={logo} alt="Plane logo" />
</Link>
</div>
</div>
{!withoutBackground && (
<div className="absolute inset-0 z-0">
<Image src={patternBackground} className="w-screen h-full object-cover" alt="Plane background pattern" />
</div>
)}
<div className="relative z-10 flex-grow">{children}</div>
</div>
</div>
);
};
+55
View File
@@ -0,0 +1,55 @@
import { FC, ReactNode } from "react";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
// components
import { LogoSpinner } from "@/components/common";
import { InstanceSetupForm, InstanceFailureView } from "@/components/instance";
// hooks
import { useInstance } from "@/hooks/store";
// layout
import { DefaultLayout } from "@/layouts/default-layout";
type InstanceProviderProps = {
children: ReactNode;
};
export const InstanceProvider: FC<InstanceProviderProps> = observer((props) => {
const { children } = props;
// store hooks
const { instance, error, fetchInstanceInfo } = useInstance();
// fetching instance details
useSWR("INSTANCE_DETAILS", () => fetchInstanceInfo(), {
revalidateOnFocus: false,
revalidateIfStale: false,
errorRetryCount: 0,
});
if (!instance && !error)
return (
<div className="flex h-screen min-h-[500px] w-full justify-center items-center">
<LogoSpinner />
</div>
);
if (error) {
return (
<DefaultLayout>
<div className="relative h-full w-full overflow-y-auto px-6 py-10 mx-auto flex justify-center items-center">
<InstanceFailureView />
</div>
</DefaultLayout>
);
}
if (!instance?.is_setup_done) {
return (
<DefaultLayout>
<div className="relative h-full w-full overflow-y-auto px-6 py-10 mx-auto flex justify-center items-center">
<InstanceSetupForm />
</div>
</DefaultLayout>
);
}
return <>{children}</>;
});
+34
View File
@@ -0,0 +1,34 @@
"use client";
import { ReactNode, createContext } from "react";
// store
import { RootStore } from "@/store/root.store";
let rootStore = new RootStore();
export const StoreContext = createContext(rootStore);
function initializeStore(initialData = {}) {
const singletonRootStore = rootStore ?? new RootStore();
// If your page has Next.js data fetching methods that use a Mobx store, it will
// get hydrated here, check `pages/ssg.js` and `pages/ssr.js` for more details
if (initialData) {
singletonRootStore.hydrate(initialData);
}
// For SSG and SSR always create a new store
if (typeof window === "undefined") return singletonRootStore;
// Create the store once in the client
if (!rootStore) rootStore = singletonRootStore;
return singletonRootStore;
}
export type StoreProviderProps = {
children: ReactNode;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
initialState?: any;
};
export const StoreProvider = ({ children, initialState = {} }: StoreProviderProps) => {
const store = initializeStore(initialState);
return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;
};
+31
View File
@@ -0,0 +1,31 @@
"use client";
import { FC, ReactNode, useEffect } from "react";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
// hooks
import { useInstance, useTheme, useUser } from "@/hooks/store";
interface IUserProvider {
children: ReactNode;
}
export const UserProvider: FC<IUserProvider> = observer(({ children }) => {
// hooks
const { isSidebarCollapsed, toggleSidebar } = useTheme();
const { currentUser, fetchCurrentUser } = useUser();
const { fetchInstanceAdmins } = useInstance();
useSWR("CURRENT_USER", () => fetchCurrentUser(), {
shouldRetryOnError: false,
});
useSWR("INSTANCE_ADMINS", () => fetchInstanceAdmins());
useEffect(() => {
const localValue = localStorage && localStorage.getItem("god_mode_sidebar_collapsed");
const localBoolValue = localValue ? (localValue === "true" ? true : false) : false;
if (isSidebarCollapsed === undefined && localBoolValue != isSidebarCollapsed) toggleSidebar(localBoolValue);
}, [isSidebarCollapsed, currentUser, toggleSidebar]);
return <>{children}</>;
});
+5
View File
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
+13
View File
@@ -0,0 +1,13 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
trailingSlash: true,
reactStrictMode: false,
swcMinify: true,
output: "standalone",
images: {
unoptimized: true,
},
basePath: process.env.NEXT_PUBLIC_ADMIN_BASE_PATH || "",
};
module.exports = nextConfig;
+50
View File
@@ -0,0 +1,50 @@
{
"name": "admin",
"version": "0.20.0",
"private": true,
"scripts": {
"dev": "turbo run develop",
"develop": "next dev --port 3001",
"build": "next build",
"preview": "next build && next start",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@headlessui/react": "^1.7.19",
"@plane/types": "*",
"@plane/ui": "*",
"@plane/constants": "*",
"@tailwindcss/typography": "^0.5.9",
"@types/lodash": "^4.17.0",
"autoprefixer": "10.4.14",
"axios": "^1.6.7",
"js-cookie": "^3.0.5",
"lodash": "^4.17.21",
"lucide-react": "^0.356.0",
"mobx": "^6.12.0",
"mobx-react-lite": "^4.0.5",
"next": "^14.2.3",
"next-themes": "^0.2.1",
"postcss": "^8.4.38",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.51.0",
"swr": "^2.2.4",
"tailwindcss": "3.3.2",
"uuid": "^9.0.1",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@types/js-cookie": "^3.0.6",
"@types/node": "18.16.1",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"@types/uuid": "^9.0.8",
"@types/zxcvbn": "^4.4.4",
"eslint-config-custom": "*",
"tailwind-config-custom": "*",
"tsconfig": "*",
"typescript": "^5.4.2"
}
}
+8
View File
@@ -0,0 +1,8 @@
module.exports = {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
},
};

Some files were not shown because too many files have changed in this diff Show More