From 88a35efa06585d47c0653bc63a56dd30283280b7 Mon Sep 17 00:00:00 2001 From: Henit Chobisa Date: Tue, 26 Sep 2023 13:46:38 +0530 Subject: [PATCH 1/6] [fix] nginx continuously rewriting and reloading on index page of spaces app (#2236) * chore: shifted index page to /home route * chore: added rewrite logic, to rewrite index to /home * chore: routed home to login route as login page * chore: updated nginx config to route to login * chore: updated path for home --- nginx/nginx.conf.template | 8 +++++++- space/components/accounts/sign-in.tsx | 4 ++-- space/components/views/index.ts | 2 +- space/components/views/{home.tsx => login.tsx} | 2 +- space/pages/index.tsx | 8 -------- space/pages/login/index.tsx | 8 ++++++++ 6 files changed, 19 insertions(+), 13 deletions(-) rename space/components/views/{home.tsx => login.tsx} (88%) delete mode 100644 space/pages/index.tsx create mode 100644 space/pages/login/index.tsx diff --git a/nginx/nginx.conf.template b/nginx/nginx.conf.template index af80b04fa..4775dcbfa 100644 --- a/nginx/nginx.conf.template +++ b/nginx/nginx.conf.template @@ -11,6 +11,11 @@ http { client_max_body_size ${FILE_SIZE_LIMIT}; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Permissions-Policy "interest-cohort=()" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + location / { proxy_pass http://web:3000/; } @@ -20,6 +25,7 @@ http { } location /spaces/ { + rewrite ^/spaces/?$ /spaces/login break; proxy_pass http://space:3000/spaces/; } @@ -27,4 +33,4 @@ http { proxy_pass http://plane-minio:9000/uploads/; } } -} \ No newline at end of file +} diff --git a/space/components/accounts/sign-in.tsx b/space/components/accounts/sign-in.tsx index d3c29103d..c6a151d44 100644 --- a/space/components/accounts/sign-in.tsx +++ b/space/components/accounts/sign-in.tsx @@ -33,7 +33,7 @@ export const SignInView = observer(() => { const onSignInSuccess = (response: any) => { const isOnboarded = response?.user?.onboarding_step?.profile_complete || false; - const nextPath = router.asPath.includes("next_path") ? router.asPath.split("/?next_path=")[1] : "/"; + const nextPath = router.asPath.includes("next_path") ? router.asPath.split("/?next_path=")[1] : "/login"; userStore.setCurrentUser(response?.user); @@ -41,7 +41,7 @@ export const SignInView = observer(() => { router.push(`/onboarding?next_path=${nextPath}`); return; } - router.push((nextPath ?? "/").toString()); + router.push((nextPath ?? "/login").toString()); }; const handleGoogleSignIn = async ({ clientId, credential }: any) => { diff --git a/space/components/views/index.ts b/space/components/views/index.ts index 84d36cd29..f54d11bdd 100644 --- a/space/components/views/index.ts +++ b/space/components/views/index.ts @@ -1 +1 @@ -export * from "./home"; +export * from "./login"; diff --git a/space/components/views/home.tsx b/space/components/views/login.tsx similarity index 88% rename from space/components/views/home.tsx rename to space/components/views/login.tsx index 999fce073..d01a22681 100644 --- a/space/components/views/home.tsx +++ b/space/components/views/login.tsx @@ -4,7 +4,7 @@ import { useMobxStore } from "lib/mobx/store-provider"; // components import { SignInView, UserLoggedIn } from "components/accounts"; -export const HomeView = observer(() => { +export const LoginView = observer(() => { const { user: userStore } = useMobxStore(); if (!userStore.currentUser) return ; diff --git a/space/pages/index.tsx b/space/pages/index.tsx deleted file mode 100644 index fe0b7d33a..000000000 --- a/space/pages/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; - -// components -import { HomeView } from "components/views"; - -const HomePage = () => ; - -export default HomePage; diff --git a/space/pages/login/index.tsx b/space/pages/login/index.tsx new file mode 100644 index 000000000..a80eff873 --- /dev/null +++ b/space/pages/login/index.tsx @@ -0,0 +1,8 @@ +import React from "react"; + +// components +import { LoginView } from "components/views"; + +const LoginPage = () => ; + +export default LoginPage; \ No newline at end of file From 52b57b1e37662de5722fc09e88f2789f0379f2a6 Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:18:06 +0530 Subject: [PATCH 2/6] dev: migration for 0.13 (#2266) * dev: updated migrations * dev: migration for 0.13 --- .../db/migrations/0044_auto_20230913_0709.py | 26 ++++---- .../db/migrations/0045_auto_20230915_0655.py | 62 ++++++++++++++++--- .../db/migrations/0046_auto_20230919_1421.py | 53 ---------------- .../db/migrations/0047_auto_20230921_0758.py | 27 -------- 4 files changed, 65 insertions(+), 103 deletions(-) delete mode 100644 apiserver/plane/db/migrations/0046_auto_20230919_1421.py delete mode 100644 apiserver/plane/db/migrations/0047_auto_20230921_0758.py diff --git a/apiserver/plane/db/migrations/0044_auto_20230913_0709.py b/apiserver/plane/db/migrations/0044_auto_20230913_0709.py index f30062371..19a1449af 100644 --- a/apiserver/plane/db/migrations/0044_auto_20230913_0709.py +++ b/apiserver/plane/db/migrations/0044_auto_20230913_0709.py @@ -26,19 +26,19 @@ def workspace_member_props(old_props): "calendar_date_range": old_props.get("calendarDateRange", ""), }, "display_properties": { - "assignee": old_props.get("properties", {}).get("assignee",None), - "attachment_count": old_props.get("properties", {}).get("attachment_count", None), - "created_on": old_props.get("properties", {}).get("created_on", None), - "due_date": old_props.get("properties", {}).get("due_date", None), - "estimate": old_props.get("properties", {}).get("estimate", None), - "key": old_props.get("properties", {}).get("key", None), - "labels": old_props.get("properties", {}).get("labels", None), - "link": old_props.get("properties", {}).get("link", None), - "priority": old_props.get("properties", {}).get("priority", None), - "start_date": old_props.get("properties", {}).get("start_date", None), - "state": old_props.get("properties", {}).get("state", None), - "sub_issue_count": old_props.get("properties", {}).get("sub_issue_count", None), - "updated_on": old_props.get("properties", {}).get("updated_on", None), + "assignee": old_props.get("properties", {}).get("assignee", True), + "attachment_count": old_props.get("properties", {}).get("attachment_count", True), + "created_on": old_props.get("properties", {}).get("created_on", True), + "due_date": old_props.get("properties", {}).get("due_date", True), + "estimate": old_props.get("properties", {}).get("estimate", True), + "key": old_props.get("properties", {}).get("key", True), + "labels": old_props.get("properties", {}).get("labels", True), + "link": old_props.get("properties", {}).get("link", True), + "priority": old_props.get("properties", {}).get("priority", True), + "start_date": old_props.get("properties", {}).get("start_date", True), + "state": old_props.get("properties", {}).get("state", True), + "sub_issue_count": old_props.get("properties", {}).get("sub_issue_count", True), + "updated_on": old_props.get("properties", {}).get("updated_on", True), }, } return new_props diff --git a/apiserver/plane/db/migrations/0045_auto_20230915_0655.py b/apiserver/plane/db/migrations/0045_auto_20230915_0655.py index a8360c63d..8512594ba 100644 --- a/apiserver/plane/db/migrations/0045_auto_20230915_0655.py +++ b/apiserver/plane/db/migrations/0045_auto_20230915_0655.py @@ -1,24 +1,66 @@ # Generated by Django 4.2.3 on 2023-09-15 06:55 -from django.db import migrations +from django.db import migrations, models +from django.conf import settings +import django.db.models.deletion +import uuid def update_issue_activity(apps, schema_editor): - IssueActivityModel = apps.get_model("db", "IssueActivity") + IssueActivity = apps.get_model("db", "IssueActivity") updated_issue_activity = [] - for obj in IssueActivityModel.objects.all(): - if obj.field == "blocks": - obj.field = "blocked_by" - updated_issue_activity.append(obj) - IssueActivityModel.objects.bulk_update(updated_issue_activity, ["field"], batch_size=100) + for obj in IssueActivity.objects.all(): + obj.epoch = int(obj.created_at.timestamp()) + + # Set the old and new value to none if it is empty for Priority + if obj.field == "priority": + obj.new_value = obj.new_value or "none" + obj.old_value = obj.old_value or "none" + + # Change the field name from blocks to blocked_by + if obj.field == "blocks": + obj.field = "blocked_by" + + updated_issue_activity.append(obj) + IssueActivity.objects.bulk_update( + updated_issue_activity, + ["epoch", "field", "new_value", "old_value"], + batch_size=100, + ) class Migration(migrations.Migration): - dependencies = [ - ('db', '0044_auto_20230913_0709'), + ("db", "0044_auto_20230913_0709"), ] operations = [ - migrations.RunPython(update_issue_activity), + migrations.CreateModel( + name="GlobalView", + fields=[ + ("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At"),), + ("updated_at", models.DateTimeField(auto_now=True, verbose_name="Last Modified At"),), + ("id", models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True,),), + ("name", models.CharField(max_length=255, verbose_name="View Name")), + ("description", models.TextField(blank=True, verbose_name="View Description"),), + ("query", models.JSONField(verbose_name="View Query")), + ("access", models.PositiveSmallIntegerField(choices=[(0, "Private"), (1, "Public")], default=1),), + ("query_data", models.JSONField(default=dict)), + ("created_by", models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="%(class)s_created_by", to=settings.AUTH_USER_MODEL, verbose_name="Created By",),), + ("updated_by", models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="%(class)s_updated_by", to=settings.AUTH_USER_MODEL, verbose_name="Last Modified By",),), + ("workspace", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name="global_views", to="db.workspace",),), + ], + options={ + "verbose_name": "Global View", + "verbose_name_plural": "Global Views", + "db_table": "global_views", + "ordering": ("-created_at",), + }, + ), + migrations.AddField( + model_name="issueactivity", + name="epoch", + field=models.FloatField(null=True), + ), + migrations.RunPython(update_issue_activity), ] diff --git a/apiserver/plane/db/migrations/0046_auto_20230919_1421.py b/apiserver/plane/db/migrations/0046_auto_20230919_1421.py deleted file mode 100644 index 4005a94d4..000000000 --- a/apiserver/plane/db/migrations/0046_auto_20230919_1421.py +++ /dev/null @@ -1,53 +0,0 @@ -# Generated by Django 4.2.3 on 2023-09-19 14:21 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -def update_epoch(apps, schema_editor): - IssueActivity = apps.get_model('db', 'IssueActivity') - updated_issue_activity = [] - for obj in IssueActivity.objects.all(): - obj.epoch = int(obj.created_at.timestamp()) - updated_issue_activity.append(obj) - IssueActivity.objects.bulk_update(updated_issue_activity, ["epoch"], batch_size=100) - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0045_auto_20230915_0655'), - ] - - operations = [ - migrations.CreateModel( - name='GlobalView', - fields=[ - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), - ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Last Modified At')), - ('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), - ('name', models.CharField(max_length=255, verbose_name='View Name')), - ('description', models.TextField(blank=True, verbose_name='View Description')), - ('query', models.JSONField(verbose_name='View Query')), - ('access', models.PositiveSmallIntegerField(choices=[(0, 'Private'), (1, 'Public')], default=1)), - ('query_data', models.JSONField(default=dict)), - ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created_by', to=settings.AUTH_USER_MODEL, verbose_name='Created By')), - ('updated_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Last Modified By')), - ('workspace', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='global_views', to='db.workspace')), - ], - options={ - 'verbose_name': 'Global View', - 'verbose_name_plural': 'Global Views', - 'db_table': 'global_views', - 'ordering': ('-created_at',), - }, - ), - migrations.AddField( - model_name='issueactivity', - name='epoch', - field=models.FloatField(null=True), - ), - migrations.RunPython(update_epoch), - ] diff --git a/apiserver/plane/db/migrations/0047_auto_20230921_0758.py b/apiserver/plane/db/migrations/0047_auto_20230921_0758.py deleted file mode 100644 index 4344963cd..000000000 --- a/apiserver/plane/db/migrations/0047_auto_20230921_0758.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.2.3 on 2023-09-21 07:58 - - -from django.db import migrations - - -def update_priority_history(apps, schema_editor): - IssueActivity = apps.get_model("db", "IssueActivity") - updated_issue_activity = [] - for obj in IssueActivity.objects.all(): - if obj.field == "priority": - obj.new_value = obj.new_value or "none" - obj.old_value = obj.old_value or "none" - updated_issue_activity.append(obj) - IssueActivity.objects.bulk_update( - updated_issue_activity, ["new_value", "old_value"], batch_size=100 - ) - - -class Migration(migrations.Migration): - dependencies = [ - ("db", "0046_auto_20230919_1421"), - ] - - operations = [ - migrations.RunPython(update_priority_history), - ] From 6e0999c35a133a0d8b803d047b1cf3fd8eb8ae27 Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Tue, 26 Sep 2023 16:25:52 +0530 Subject: [PATCH 3/6] dev: re-split migrations into two different files (#2268) * dev: split issue activity migration separate files * dev: resplit migrations into two different files * dev: changed the batch size --- .../db/migrations/0045_auto_20230915_0655.py | 26 +---------- .../db/migrations/0046_auto_20230926_1015.py | 26 +++++++++++ .../db/migrations/0047_auto_20230926_1029.py | 44 +++++++++++++++++++ 3 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 apiserver/plane/db/migrations/0046_auto_20230926_1015.py create mode 100644 apiserver/plane/db/migrations/0047_auto_20230926_1029.py diff --git a/apiserver/plane/db/migrations/0045_auto_20230915_0655.py b/apiserver/plane/db/migrations/0045_auto_20230915_0655.py index 8512594ba..cd9aa6902 100644 --- a/apiserver/plane/db/migrations/0045_auto_20230915_0655.py +++ b/apiserver/plane/db/migrations/0045_auto_20230915_0655.py @@ -6,29 +6,6 @@ import django.db.models.deletion import uuid -def update_issue_activity(apps, schema_editor): - IssueActivity = apps.get_model("db", "IssueActivity") - updated_issue_activity = [] - for obj in IssueActivity.objects.all(): - obj.epoch = int(obj.created_at.timestamp()) - - # Set the old and new value to none if it is empty for Priority - if obj.field == "priority": - obj.new_value = obj.new_value or "none" - obj.old_value = obj.old_value or "none" - - # Change the field name from blocks to blocked_by - if obj.field == "blocks": - obj.field = "blocked_by" - - updated_issue_activity.append(obj) - IssueActivity.objects.bulk_update( - updated_issue_activity, - ["epoch", "field", "new_value", "old_value"], - batch_size=100, - ) - - class Migration(migrations.Migration): dependencies = [ ("db", "0044_auto_20230913_0709"), @@ -61,6 +38,5 @@ class Migration(migrations.Migration): model_name="issueactivity", name="epoch", field=models.FloatField(null=True), - ), - migrations.RunPython(update_issue_activity), + ), ] diff --git a/apiserver/plane/db/migrations/0046_auto_20230926_1015.py b/apiserver/plane/db/migrations/0046_auto_20230926_1015.py new file mode 100644 index 000000000..8bce37d95 --- /dev/null +++ b/apiserver/plane/db/migrations/0046_auto_20230926_1015.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.5 on 2023-09-26 10:15 + +from django.db import migrations + + +def update_issue_activity(apps, schema_editor): + IssueActivity = apps.get_model("db", "IssueActivity") + updated_issue_activity = [] + for obj in IssueActivity.objects.all(): + obj.epoch = int(obj.created_at.timestamp()) + updated_issue_activity.append(obj) + IssueActivity.objects.bulk_update( + updated_issue_activity, + ["epoch"], + batch_size=5000, + ) + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0045_auto_20230915_0655'), + ] + + operations = [ + migrations.RunPython(update_issue_activity), + ] diff --git a/apiserver/plane/db/migrations/0047_auto_20230926_1029.py b/apiserver/plane/db/migrations/0047_auto_20230926_1029.py new file mode 100644 index 000000000..da64e11c8 --- /dev/null +++ b/apiserver/plane/db/migrations/0047_auto_20230926_1029.py @@ -0,0 +1,44 @@ +# Generated by Django 4.2.5 on 2023-09-26 10:29 + +from django.db import migrations + + +def update_issue_activity_priority(apps, schema_editor): + IssueActivity = apps.get_model("db", "IssueActivity") + updated_issue_activity = [] + for obj in IssueActivity.objects.filter(field="priority"): + # Set the old and new value to none if it is empty for Priority + obj.new_value = obj.new_value or "none" + obj.old_value = obj.old_value or "none" + updated_issue_activity.append(obj) + IssueActivity.objects.bulk_update( + updated_issue_activity, + ["new_value", "old_value"], + batch_size=1000, + ) + +def update_issue_activity_blocked(apps, schema_editor): + IssueActivity = apps.get_model("db", "IssueActivity") + updated_issue_activity = [] + for obj in IssueActivity.objects.filter(field="blocks"): + # Set the field to blocked_by + obj.field = "blocked_by" + updated_issue_activity.append(obj) + IssueActivity.objects.bulk_update( + updated_issue_activity, + ["field"], + batch_size=1000, + ) + + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0046_auto_20230926_1015'), + ] + + operations = [ + migrations.RunPython(update_issue_activity_priority), + migrations.RunPython(update_issue_activity_blocked), + ] From b317a14983ac4d1d2a0b10d9a5df7a80d2ebc773 Mon Sep 17 00:00:00 2001 From: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:35:51 +0530 Subject: [PATCH 4/6] fix: bugs in quick-add and draft issues (#2269) * fix: 'Last Drafted Issue' making sidebar look weird on collapsed * feat: scroll to the bottom when issue is created * fix: 'Add Issue' button overlapping issue card in spreadsheet view * fix: wrong placement of quick-add in calender layout * fix: spacing for issue card in spreadsheet view --- .../core/views/calendar-view/calendar.tsx | 5 +- .../inline-create-issue-form.tsx | 23 +++- .../core/views/calendar-view/single-date.tsx | 1 + .../views/inline-issue-create-wrapper.tsx | 10 +- .../spreadsheet-view/spreadsheet-view.tsx | 112 ++++++++++-------- web/components/gantt-chart/sidebar.tsx | 14 +++ .../workspace/sidebar-quick-action.tsx | 20 +++- .../projects/[projectId]/cycles/[cycleId].tsx | 2 +- 8 files changed, 118 insertions(+), 69 deletions(-) diff --git a/web/components/core/views/calendar-view/calendar.tsx b/web/components/core/views/calendar-view/calendar.tsx index 030f8b747..8fbe35305 100644 --- a/web/components/core/views/calendar-view/calendar.tsx +++ b/web/components/core/views/calendar-view/calendar.tsx @@ -183,7 +183,10 @@ export const CalendarView: React.FC = ({ {calendarIssues ? (
-
+
void; onSuccess?: (data: IIssue) => Promise | void; prePopulatedData?: Partial; + dependencies: any[]; }; -const useCheckIfThereIsSpaceOnRight = (ref: React.RefObject) => { +const useCheckIfThereIsSpaceOnRight = (ref: React.RefObject, deps: any[]) => { const [isThereSpaceOnRight, setIsThereSpaceOnRight] = useState(true); + const router = useRouter(); + const { moduleId, cycleId, viewId } = router.query; + + const container = document.getElementById(`calendar-view-${cycleId ?? moduleId ?? viewId}`); + useEffect(() => { if (!ref.current) return; const { right } = ref.current.getBoundingClientRect(); - const width = right + 250; + const width = right; - if (width > window.innerWidth) setIsThereSpaceOnRight(false); + const innerWidth = container?.getBoundingClientRect().width ?? window.innerWidth; + + if (width > innerWidth) setIsThereSpaceOnRight(false); else setIsThereSpaceOnRight(true); - }, [ref]); + }, [ref, deps, container]); return isThereSpaceOnRight; }; @@ -63,11 +74,11 @@ const InlineInput = () => { }; export const CalendarInlineCreateIssueForm: React.FC = (props) => { - const { isOpen } = props; + const { isOpen, dependencies } = props; const ref = useRef(null); - const isSpaceOnRight = useCheckIfThereIsSpaceOnRight(ref); + const isSpaceOnRight = useCheckIfThereIsSpaceOnRight(ref, dependencies); return ( <> diff --git a/web/components/core/views/calendar-view/single-date.tsx b/web/components/core/views/calendar-view/single-date.tsx index 178151204..02ea56678 100644 --- a/web/components/core/views/calendar-view/single-date.tsx +++ b/web/components/core/views/calendar-view/single-date.tsx @@ -83,6 +83,7 @@ export const SingleCalendarDate: React.FC = (props) => { setIsCreateIssueFormOpen(false)} prePopulatedData={{ target_date: date.date, diff --git a/web/components/core/views/inline-issue-create-wrapper.tsx b/web/components/core/views/inline-issue-create-wrapper.tsx index 3c01c50ce..ace407ae1 100644 --- a/web/components/core/views/inline-issue-create-wrapper.tsx +++ b/web/components/core/views/inline-issue-create-wrapper.tsx @@ -218,11 +218,11 @@ export const InlineCreateIssueFormWrapper: React.FC = (props) => { ); if (isDraftIssues) - mutate(PROJECT_DRAFT_ISSUES_LIST_WITH_PARAMS(projectId.toString() ?? "", params)); - if (displayFilters.layout === "calendar") mutate(calendarFetchKey); - if (displayFilters.layout === "gantt_chart") mutate(ganttFetchKey); - if (displayFilters.layout === "spreadsheet") mutate(spreadsheetFetchKey); - if (groupedIssues) mutateMyIssues(); + await mutate(PROJECT_DRAFT_ISSUES_LIST_WITH_PARAMS(projectId.toString() ?? "", params)); + if (displayFilters.layout === "calendar") await mutate(calendarFetchKey); + if (displayFilters.layout === "gantt_chart") await mutate(ganttFetchKey); + if (displayFilters.layout === "spreadsheet") await mutate(spreadsheetFetchKey); + if (groupedIssues) await mutateMyIssues(); setToastAlert({ type: "success", diff --git a/web/components/core/views/spreadsheet-view/spreadsheet-view.tsx b/web/components/core/views/spreadsheet-view/spreadsheet-view.tsx index 2315c21c3..d11fe85d6 100644 --- a/web/components/core/views/spreadsheet-view/spreadsheet-view.tsx +++ b/web/components/core/views/spreadsheet-view/spreadsheet-view.tsx @@ -68,7 +68,11 @@ export const SpreadsheetView: React.FC = ({ workspaceSlug={workspaceSlug?.toString() ?? ""} readOnly={disableUserActions} /> -
+
@@ -89,62 +93,66 @@ export const SpreadsheetView: React.FC = ({ userAuth={userAuth} /> ))} - -
- setIsInlineCreateIssueFormOpen(false)} - prePopulatedData={{ - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - }} - /> - - {type === "issue" - ? !disableUserActions && - !isInlineCreateIssueFormOpen && ( - - ) - : !disableUserActions && - !isInlineCreateIssueFormOpen && ( - - - Add Issue - - } - position="left" - verticalPosition="top" - optionsClassName="left-5 !w-36" - noBorder - > - setIsInlineCreateIssueFormOpen(true)}> - Create new - - {openIssuesListModal && ( - - Add an existing issue - - )} - - )} -
) : ( )}
+ +
+ setIsInlineCreateIssueFormOpen(false)} + prePopulatedData={{ + ...(cycleId && { cycle: cycleId.toString() }), + ...(moduleId && { module: moduleId.toString() }), + }} + /> + + {type === "issue" + ? !disableUserActions && + !isInlineCreateIssueFormOpen && ( + + ) + : !disableUserActions && + !isInlineCreateIssueFormOpen && ( + + + Add Issue + + } + position="left" + verticalPosition="top" + optionsClassName="left-5 !w-36" + noBorder + > + setIsInlineCreateIssueFormOpen(true)}> + Create new + + {openIssuesListModal && ( + + Add an existing issue + + )} + + )} +
); }; diff --git a/web/components/gantt-chart/sidebar.tsx b/web/components/gantt-chart/sidebar.tsx index 35b253ef9..fc2cea1e0 100644 --- a/web/components/gantt-chart/sidebar.tsx +++ b/web/components/gantt-chart/sidebar.tsx @@ -92,6 +92,7 @@ export const GanttSidebar: React.FC = (props) => { {(droppableProvided) => (
= (props) => { setIsCreateIssueFormOpen(false)} + onSuccess={() => { + const ganttSidebar = document.getElementById(`gantt-sidebar-${cycleId}`); + + const timeoutId = setTimeout(() => { + if (ganttSidebar) + ganttSidebar.scrollBy({ + top: ganttSidebar.scrollHeight, + left: 0, + behavior: "smooth", + }); + clearTimeout(timeoutId); + }, 10); + }} prePopulatedData={{ start_date: new Date(Date.now()).toISOString().split("T")[0], target_date: new Date(Date.now() + 86400000).toISOString().split("T")[0], diff --git a/web/components/workspace/sidebar-quick-action.tsx b/web/components/workspace/sidebar-quick-action.tsx index 8923abc14..1c614f694 100644 --- a/web/components/workspace/sidebar-quick-action.tsx +++ b/web/components/workspace/sidebar-quick-action.tsx @@ -44,7 +44,9 @@ export const WorkspaceSidebarQuickAction = () => { > -
+