mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge pull request #3046 from makeplane/promote/dev-preview
promote: develop to preview
This commit is contained in:
commit
d16a6402cd
@ -27,7 +27,8 @@ WORKDIR /code
|
|||||||
COPY requirements.txt ./requirements.txt
|
COPY requirements.txt ./requirements.txt
|
||||||
ADD requirements ./requirements
|
ADD requirements ./requirements
|
||||||
|
|
||||||
RUN pip install -r requirements.txt --compile --no-cache-dir
|
# Install the local development settings
|
||||||
|
RUN pip install -r requirements/local.txt --compile --no-cache-dir
|
||||||
|
|
||||||
RUN addgroup -S plane && \
|
RUN addgroup -S plane && \
|
||||||
adduser -S captain -G plane
|
adduser -S captain -G plane
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"name": "plane-api",
|
"name": "plane-api",
|
||||||
"version": "0.13.2"
|
"version": "0.14.0"
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,8 @@ class ConfigurationEndpoint(BaseAPIView):
|
|||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
# Authentication
|
# Authentication
|
||||||
data["google_client_id"] = GOOGLE_CLIENT_ID
|
data["google_client_id"] = GOOGLE_CLIENT_ID if GOOGLE_CLIENT_ID and GOOGLE_CLIENT_ID != "\"\"" else None
|
||||||
data["github_client_id"] = GITHUB_CLIENT_ID
|
data["github_client_id"] = GITHUB_CLIENT_ID if GITHUB_CLIENT_ID and GITHUB_CLIENT_ID != "\"\"" else None
|
||||||
data["github_app_name"] = GITHUB_APP_NAME
|
data["github_app_name"] = GITHUB_APP_NAME
|
||||||
data["magic_login"] = (
|
data["magic_login"] = (
|
||||||
bool(EMAIL_HOST_USER) and bool(EMAIL_HOST_PASSWORD)
|
bool(EMAIL_HOST_USER) and bool(EMAIL_HOST_PASSWORD)
|
||||||
@ -106,7 +106,7 @@ class ConfigurationEndpoint(BaseAPIView):
|
|||||||
data["posthog_host"] = POSTHOG_HOST
|
data["posthog_host"] = POSTHOG_HOST
|
||||||
|
|
||||||
# Unsplash
|
# Unsplash
|
||||||
data["has_unsplash_configured"] = UNSPLASH_ACCESS_KEY
|
data["has_unsplash_configured"] = bool(UNSPLASH_ACCESS_KEY)
|
||||||
|
|
||||||
# Open AI settings
|
# Open AI settings
|
||||||
data["has_openai_configured"] = bool(OPENAI_API_KEY)
|
data["has_openai_configured"] = bool(OPENAI_API_KEY)
|
||||||
|
@ -86,7 +86,14 @@ def get_access_token(request_token: str, client_id: str) -> str:
|
|||||||
if not request_token:
|
if not request_token:
|
||||||
raise ValueError("The request token has to be supplied!")
|
raise ValueError("The request token has to be supplied!")
|
||||||
|
|
||||||
CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET")
|
(CLIENT_SECRET,) = get_configuration_value(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"key": "GITHUB_CLIENT_SECRET",
|
||||||
|
"default": os.environ.get("GITHUB_CLIENT_SECRET", None),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
url = f"https://github.com/login/oauth/access_token?client_id={client_id}&client_secret={CLIENT_SECRET}&code={request_token}"
|
url = f"https://github.com/login/oauth/access_token?client_id={client_id}&client_secret={CLIENT_SECRET}&code={request_token}"
|
||||||
headers = {"accept": "application/json"}
|
headers = {"accept": "application/json"}
|
||||||
@ -299,7 +306,7 @@ class OauthEndpoint(BaseAPIView):
|
|||||||
return Response(data, status=status.HTTP_200_OK)
|
return Response(data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
ENABLE_SIGNUP, = get_configuration_value(
|
(ENABLE_SIGNUP,) = get_configuration_value(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"key": "ENABLE_SIGNUP",
|
"key": "ENABLE_SIGNUP",
|
||||||
|
@ -49,6 +49,10 @@ class UserEndpoint(BaseViewSet):
|
|||||||
# Check all workspace user is active
|
# Check all workspace user is active
|
||||||
user = self.get_object()
|
user = self.get_object()
|
||||||
|
|
||||||
|
# Instance admin check
|
||||||
|
if InstanceAdmin.objects.filter(user=user).exists():
|
||||||
|
return Response({"error": "You cannot deactivate your account since you are an instance admin"}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
projects_to_deactivate = []
|
projects_to_deactivate = []
|
||||||
workspaces_to_deactivate = []
|
workspaces_to_deactivate = []
|
||||||
|
|
||||||
|
@ -221,37 +221,6 @@ class InstanceAdminSignInEndpoint(BaseAPIView):
|
|||||||
is_password_autoset=False,
|
is_password_autoset=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# if the current user is not using captain then add the current all users to workspace and projects
|
|
||||||
if user.email != "captain@plane.so":
|
|
||||||
# Add the current user also as a workspace member and project memeber to all the workspaces and projects
|
|
||||||
captain = User.objects.filter(email="captain@plane.so")
|
|
||||||
# Workspace members
|
|
||||||
workspace_members = WorkspaceMember.objects.filter(member=captain)
|
|
||||||
WorkspaceMember.objects.bulk_create(
|
|
||||||
[
|
|
||||||
WorkspaceMember(
|
|
||||||
workspace=member.workspace_id,
|
|
||||||
member=user,
|
|
||||||
role=member.role,
|
|
||||||
)
|
|
||||||
for member in workspace_members
|
|
||||||
],
|
|
||||||
batch_size=100,
|
|
||||||
)
|
|
||||||
# project members
|
|
||||||
project_members = ProjectMember.objects.filter(member=captain)
|
|
||||||
ProjectMember.objects.bulk_create(
|
|
||||||
[
|
|
||||||
ProjectMember(
|
|
||||||
workspace=member.workspace_id,
|
|
||||||
member=user,
|
|
||||||
role=member.role,
|
|
||||||
)
|
|
||||||
for member in project_members
|
|
||||||
],
|
|
||||||
batch_size=100,
|
|
||||||
)
|
|
||||||
|
|
||||||
# settings last active for the user
|
# settings last active for the user
|
||||||
user.is_active = True
|
user.is_active = True
|
||||||
user.last_active = timezone.now()
|
user.last_active = timezone.now()
|
||||||
|
@ -41,7 +41,7 @@ x-app-env : &app-env
|
|||||||
- DEFAULT_PASSWORD=${DEFAULT_PASSWORD:-password123}
|
- DEFAULT_PASSWORD=${DEFAULT_PASSWORD:-password123}
|
||||||
# OPENAI SETTINGS - Deprecated can be configured through admin panel
|
# OPENAI SETTINGS - Deprecated can be configured through admin panel
|
||||||
- OPENAI_API_BASE=${OPENAI_API_BASE:-https://api.openai.com/v1}
|
- OPENAI_API_BASE=${OPENAI_API_BASE:-https://api.openai.com/v1}
|
||||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-"sk-"}
|
- OPENAI_API_KEY=${OPENAI_API_KEY:-""}
|
||||||
- GPT_ENGINE=${GPT_ENGINE:-"gpt-3.5-turbo"}
|
- GPT_ENGINE=${GPT_ENGINE:-"gpt-3.5-turbo"}
|
||||||
# LOGIN/SIGNUP SETTINGS - Deprecated can be configured through admin panel
|
# LOGIN/SIGNUP SETTINGS - Deprecated can be configured through admin panel
|
||||||
- ENABLE_SIGNUP=${ENABLE_SIGNUP:-1}
|
- ENABLE_SIGNUP=${ENABLE_SIGNUP:-1}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"repository": "https://github.com/makeplane/plane.git",
|
"repository": "https://github.com/makeplane/plane.git",
|
||||||
"version": "0.13.2",
|
"version": "0.14.0",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@plane/editor-core",
|
"name": "@plane/editor-core",
|
||||||
"version": "0.0.1",
|
"version": "0.14.0",
|
||||||
"description": "Core Editor that powers Plane",
|
"description": "Core Editor that powers Plane",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./dist/index.mjs",
|
"main": "./dist/index.mjs",
|
||||||
@ -80,4 +80,4 @@
|
|||||||
"nextjs",
|
"nextjs",
|
||||||
"react"
|
"react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@plane/document-editor",
|
"name": "@plane/document-editor",
|
||||||
"version": "0.1.0",
|
"version": "0.14.0",
|
||||||
"description": "Package that powers Plane's Pages Editor",
|
"description": "Package that powers Plane's Pages Editor",
|
||||||
"main": "./dist/index.mjs",
|
"main": "./dist/index.mjs",
|
||||||
"module": "./dist/index.mjs",
|
"module": "./dist/index.mjs",
|
||||||
@ -63,4 +63,4 @@
|
|||||||
"nextjs",
|
"nextjs",
|
||||||
"react"
|
"react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@plane/editor-extensions",
|
"name": "@plane/editor-extensions",
|
||||||
"version": "0.1.0",
|
"version": "0.14.0",
|
||||||
"description": "Package that powers Plane's Editor with extensions",
|
"description": "Package that powers Plane's Editor with extensions",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./dist/index.mjs",
|
"main": "./dist/index.mjs",
|
||||||
@ -57,4 +57,4 @@
|
|||||||
"nextjs",
|
"nextjs",
|
||||||
"react"
|
"react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@plane/lite-text-editor",
|
"name": "@plane/lite-text-editor",
|
||||||
"version": "0.1.0",
|
"version": "0.14.0",
|
||||||
"description": "Package that powers Plane's Comment Editor",
|
"description": "Package that powers Plane's Comment Editor",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./dist/index.mjs",
|
"main": "./dist/index.mjs",
|
||||||
@ -52,4 +52,4 @@
|
|||||||
"nextjs",
|
"nextjs",
|
||||||
"react"
|
"react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@plane/rich-text-editor",
|
"name": "@plane/rich-text-editor",
|
||||||
"version": "0.1.0",
|
"version": "0.14.0",
|
||||||
"description": "Rich Text Editor that powers Plane",
|
"description": "Rich Text Editor that powers Plane",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./dist/index.mjs",
|
"main": "./dist/index.mjs",
|
||||||
@ -55,4 +55,4 @@
|
|||||||
"nextjs",
|
"nextjs",
|
||||||
"react"
|
"react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@plane/editor-types",
|
"name": "@plane/editor-types",
|
||||||
"version": "0.1.0",
|
"version": "0.14.0",
|
||||||
"description": "Package that powers Plane's Editor with extensions",
|
"description": "Package that powers Plane's Editor with extensions",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./dist/index.mjs",
|
"main": "./dist/index.mjs",
|
||||||
@ -48,4 +48,4 @@
|
|||||||
"nextjs",
|
"nextjs",
|
||||||
"react"
|
"react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "eslint-config-custom",
|
"name": "eslint-config-custom",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.13.2",
|
"version": "0.14.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tailwind-config-custom",
|
"name": "tailwind-config-custom",
|
||||||
"version": "0.13.2",
|
"version": "0.14.0",
|
||||||
"description": "common tailwind configuration across monorepo",
|
"description": "common tailwind configuration across monorepo",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tsconfig",
|
"name": "tsconfig",
|
||||||
"version": "0.13.2",
|
"version": "0.14.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"files": [
|
"files": [
|
||||||
"base.json",
|
"base.json",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "@plane/ui",
|
"name": "@plane/ui",
|
||||||
"description": "UI components shared across multiple apps internally",
|
"description": "UI components shared across multiple apps internally",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.0",
|
"version": "0.14.0",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.mjs",
|
"module": "./dist/index.mjs",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@ -38,4 +38,4 @@
|
|||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
"react-popper": "^2.3.0"
|
"react-popper": "^2.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "space",
|
"name": "space",
|
||||||
"version": "0.13.2",
|
"version": "0.14.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "turbo run develop",
|
"dev": "turbo run develop",
|
||||||
|
@ -61,6 +61,8 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = (props) => {
|
|||||||
description_html: issue.description_html,
|
description_html: issue.description_html,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// adding issue.description_html or issue.name to dependency array causes
|
||||||
|
// editor rerendering on every save
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (issue.id) {
|
if (issue.id) {
|
||||||
setLocalIssueDescription({ id: issue.id, description_html: issue.description_html });
|
setLocalIssueDescription({ id: issue.id, description_html: issue.description_html });
|
||||||
@ -100,9 +102,13 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = (props) => {
|
|||||||
});
|
});
|
||||||
}, [issue, reset]);
|
}, [issue, reset]);
|
||||||
|
|
||||||
const debouncedFormSave = debounce(async () => {
|
// ADDING handleDescriptionFormSubmit TO DEPENDENCY ARRAY PRODUCES ADVERSE EFFECTS
|
||||||
handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting("submitted"));
|
const debouncedFormSave = useCallback(
|
||||||
}, 1500);
|
debounce(async () => {
|
||||||
|
handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting("submitted"));
|
||||||
|
}, 1500),
|
||||||
|
[handleSubmit]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
@ -16,7 +16,6 @@ import {
|
|||||||
IViewIssuesFilterStore,
|
IViewIssuesFilterStore,
|
||||||
IViewIssuesStore,
|
IViewIssuesStore,
|
||||||
} from "store/issues";
|
} from "store/issues";
|
||||||
import { IIssueCalendarViewStore } from "store/issue";
|
|
||||||
import { IQuickActionProps } from "../list/list-view-types";
|
import { IQuickActionProps } from "../list/list-view-types";
|
||||||
import { EIssueActions } from "../types";
|
import { EIssueActions } from "../types";
|
||||||
import { IGroupedIssues } from "store/issues/types";
|
import { IGroupedIssues } from "store/issues/types";
|
||||||
@ -28,7 +27,6 @@ interface IBaseCalendarRoot {
|
|||||||
| IModuleIssuesFilterStore
|
| IModuleIssuesFilterStore
|
||||||
| ICycleIssuesFilterStore
|
| ICycleIssuesFilterStore
|
||||||
| IViewIssuesFilterStore;
|
| IViewIssuesFilterStore;
|
||||||
calendarViewStore: IIssueCalendarViewStore;
|
|
||||||
QuickActions: FC<IQuickActionProps>;
|
QuickActions: FC<IQuickActionProps>;
|
||||||
issueActions: {
|
issueActions: {
|
||||||
[EIssueActions.DELETE]: (issue: IIssue) => Promise<void>;
|
[EIssueActions.DELETE]: (issue: IIssue) => Promise<void>;
|
||||||
@ -77,13 +75,14 @@ export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
|
|||||||
<div className="h-full w-full pt-4 bg-custom-background-100 overflow-hidden">
|
<div className="h-full w-full pt-4 bg-custom-background-100 overflow-hidden">
|
||||||
<DragDropContext onDragEnd={onDragEnd}>
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
<CalendarChart
|
<CalendarChart
|
||||||
|
issuesFilterStore={issuesFilterStore}
|
||||||
issues={issues}
|
issues={issues}
|
||||||
groupedIssueIds={groupedIssueIds}
|
groupedIssueIds={groupedIssueIds}
|
||||||
layout={displayFilters?.calendar?.layout}
|
layout={displayFilters?.calendar?.layout}
|
||||||
showWeekends={displayFilters?.calendar?.show_weekends ?? false}
|
showWeekends={displayFilters?.calendar?.show_weekends ?? false}
|
||||||
quickActions={(issue, customActionButton) => (
|
quickActions={(issue, customActionButton) => (
|
||||||
<QuickActions
|
<QuickActions
|
||||||
customActionButton={customActionButton}
|
customActionButton={customActionButton}
|
||||||
issue={issue}
|
issue={issue}
|
||||||
handleDelete={async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.DELETE)}
|
handleDelete={async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.DELETE)}
|
||||||
handleUpdate={
|
handleUpdate={
|
||||||
|
@ -10,8 +10,19 @@ import { Spinner } from "@plane/ui";
|
|||||||
import { ICalendarWeek } from "./types";
|
import { ICalendarWeek } from "./types";
|
||||||
import { IIssue } from "types";
|
import { IIssue } from "types";
|
||||||
import { IGroupedIssues, IIssueResponse } from "store/issues/types";
|
import { IGroupedIssues, IIssueResponse } from "store/issues/types";
|
||||||
|
import {
|
||||||
|
ICycleIssuesFilterStore,
|
||||||
|
IModuleIssuesFilterStore,
|
||||||
|
IProjectIssuesFilterStore,
|
||||||
|
IViewIssuesFilterStore,
|
||||||
|
} from "store/issues";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
issuesFilterStore:
|
||||||
|
| IProjectIssuesFilterStore
|
||||||
|
| IModuleIssuesFilterStore
|
||||||
|
| ICycleIssuesFilterStore
|
||||||
|
| IViewIssuesFilterStore;
|
||||||
issues: IIssueResponse | undefined;
|
issues: IIssueResponse | undefined;
|
||||||
groupedIssueIds: IGroupedIssues;
|
groupedIssueIds: IGroupedIssues;
|
||||||
layout: "month" | "week" | undefined;
|
layout: "month" | "week" | undefined;
|
||||||
@ -27,7 +38,8 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CalendarChart: React.FC<Props> = observer((props) => {
|
export const CalendarChart: React.FC<Props> = observer((props) => {
|
||||||
const { issues, groupedIssueIds, layout, showWeekends, quickActions, quickAddCallback, viewId } = props;
|
const { issuesFilterStore, issues, groupedIssueIds, layout, showWeekends, quickActions, quickAddCallback, viewId } =
|
||||||
|
props;
|
||||||
|
|
||||||
const { calendar: calendarStore } = useMobxStore();
|
const { calendar: calendarStore } = useMobxStore();
|
||||||
|
|
||||||
@ -45,7 +57,7 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="h-full w-full flex flex-col overflow-hidden">
|
<div className="h-full w-full flex flex-col overflow-hidden">
|
||||||
<CalendarHeader />
|
<CalendarHeader issuesFilterStore={issuesFilterStore} />
|
||||||
<CalendarWeekHeader isLoading={!issues} showWeekends={showWeekends} />
|
<CalendarWeekHeader isLoading={!issues} showWeekends={showWeekends} />
|
||||||
<div className="h-full w-full overflow-y-auto">
|
<div className="h-full w-full overflow-y-auto">
|
||||||
{layout === "month" && (
|
{layout === "month" && (
|
||||||
@ -53,6 +65,7 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
|
|||||||
{allWeeksOfActiveMonth &&
|
{allWeeksOfActiveMonth &&
|
||||||
Object.values(allWeeksOfActiveMonth).map((week: ICalendarWeek, weekIndex) => (
|
Object.values(allWeeksOfActiveMonth).map((week: ICalendarWeek, weekIndex) => (
|
||||||
<CalendarWeekDays
|
<CalendarWeekDays
|
||||||
|
issuesFilterStore={issuesFilterStore}
|
||||||
key={weekIndex}
|
key={weekIndex}
|
||||||
week={week}
|
week={week}
|
||||||
issues={issues}
|
issues={issues}
|
||||||
@ -67,6 +80,7 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
|
|||||||
)}
|
)}
|
||||||
{layout === "week" && (
|
{layout === "week" && (
|
||||||
<CalendarWeekDays
|
<CalendarWeekDays
|
||||||
|
issuesFilterStore={issuesFilterStore}
|
||||||
week={calendarStore.allDaysOfActiveWeek}
|
week={calendarStore.allDaysOfActiveWeek}
|
||||||
issues={issues}
|
issues={issues}
|
||||||
groupedIssueIds={groupedIssueIds}
|
groupedIssueIds={groupedIssueIds}
|
||||||
|
@ -11,8 +11,19 @@ import { renderDateFormat } from "helpers/date-time.helper";
|
|||||||
import { MONTHS_LIST } from "constants/calendar";
|
import { MONTHS_LIST } from "constants/calendar";
|
||||||
import { IIssue } from "types";
|
import { IIssue } from "types";
|
||||||
import { IGroupedIssues, IIssueResponse } from "store/issues/types";
|
import { IGroupedIssues, IIssueResponse } from "store/issues/types";
|
||||||
|
import {
|
||||||
|
ICycleIssuesFilterStore,
|
||||||
|
IModuleIssuesFilterStore,
|
||||||
|
IProjectIssuesFilterStore,
|
||||||
|
IViewIssuesFilterStore,
|
||||||
|
} from "store/issues";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
issuesFilterStore:
|
||||||
|
| IProjectIssuesFilterStore
|
||||||
|
| IModuleIssuesFilterStore
|
||||||
|
| ICycleIssuesFilterStore
|
||||||
|
| IViewIssuesFilterStore;
|
||||||
date: ICalendarDate;
|
date: ICalendarDate;
|
||||||
issues: IIssueResponse | undefined;
|
issues: IIssueResponse | undefined;
|
||||||
groupedIssueIds: IGroupedIssues;
|
groupedIssueIds: IGroupedIssues;
|
||||||
@ -28,11 +39,18 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CalendarDayTile: React.FC<Props> = observer((props) => {
|
export const CalendarDayTile: React.FC<Props> = observer((props) => {
|
||||||
const { date, issues, groupedIssueIds, quickActions, enableQuickIssueCreate, quickAddCallback, viewId } = props;
|
const {
|
||||||
|
issuesFilterStore,
|
||||||
|
date,
|
||||||
|
issues,
|
||||||
|
groupedIssueIds,
|
||||||
|
quickActions,
|
||||||
|
enableQuickIssueCreate,
|
||||||
|
quickAddCallback,
|
||||||
|
viewId,
|
||||||
|
} = props;
|
||||||
|
|
||||||
const { issueFilter: issueFilterStore } = useMobxStore();
|
const calendarLayout = issuesFilterStore?.issueFilters?.displayFilters?.calendar?.layout ?? "month";
|
||||||
|
|
||||||
const calendarLayout = issueFilterStore.userDisplayFilters.calendar?.layout ?? "month";
|
|
||||||
|
|
||||||
const issueIdList = groupedIssueIds ? groupedIssueIds[renderDateFormat(date.date)] : null;
|
const issueIdList = groupedIssueIds ? groupedIssueIds[renderDateFormat(date.date)] : null;
|
||||||
|
|
||||||
|
@ -13,12 +13,29 @@ import { Check, ChevronUp } from "lucide-react";
|
|||||||
import { TCalendarLayouts } from "types";
|
import { TCalendarLayouts } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { CALENDAR_LAYOUTS } from "constants/calendar";
|
import { CALENDAR_LAYOUTS } from "constants/calendar";
|
||||||
|
import { EFilterType } from "store/issues/types";
|
||||||
|
import {
|
||||||
|
ICycleIssuesFilterStore,
|
||||||
|
IModuleIssuesFilterStore,
|
||||||
|
IProjectIssuesFilterStore,
|
||||||
|
IViewIssuesFilterStore,
|
||||||
|
} from "store/issues";
|
||||||
|
|
||||||
|
interface ICalendarHeader {
|
||||||
|
issuesFilterStore:
|
||||||
|
| IProjectIssuesFilterStore
|
||||||
|
| IModuleIssuesFilterStore
|
||||||
|
| ICycleIssuesFilterStore
|
||||||
|
| IViewIssuesFilterStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CalendarOptionsDropdown: React.FC<ICalendarHeader> = observer((props) => {
|
||||||
|
const { issuesFilterStore } = props;
|
||||||
|
|
||||||
export const CalendarOptionsDropdown: React.FC = observer(() => {
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
const { issueFilter: issueFilterStore, calendar: calendarStore } = useMobxStore();
|
const { calendar: calendarStore } = useMobxStore();
|
||||||
|
|
||||||
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
|
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
|
||||||
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
||||||
@ -35,18 +52,16 @@ export const CalendarOptionsDropdown: React.FC = observer(() => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const calendarLayout = issueFilterStore.userDisplayFilters.calendar?.layout ?? "month";
|
const calendarLayout = issuesFilterStore.issueFilters?.displayFilters?.calendar?.layout ?? "month";
|
||||||
const showWeekends = issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false;
|
const showWeekends = issuesFilterStore.issueFilters?.displayFilters?.calendar?.show_weekends ?? false;
|
||||||
|
|
||||||
const handleLayoutChange = (layout: TCalendarLayouts) => {
|
const handleLayoutChange = (layout: TCalendarLayouts) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
issueFilterStore.updateUserFilters(workspaceSlug.toString(), projectId.toString(), {
|
issuesFilterStore.updateFilters(workspaceSlug.toString(), projectId.toString(), EFilterType.DISPLAY_FILTERS, {
|
||||||
display_filters: {
|
calendar: {
|
||||||
calendar: {
|
...issuesFilterStore.issueFilters?.displayFilters?.calendar,
|
||||||
...issueFilterStore.userDisplayFilters.calendar,
|
layout,
|
||||||
layout,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -56,16 +71,14 @@ export const CalendarOptionsDropdown: React.FC = observer(() => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleWeekends = () => {
|
const handleToggleWeekends = () => {
|
||||||
const showWeekends = issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false;
|
const showWeekends = issuesFilterStore.issueFilters?.displayFilters?.calendar?.show_weekends ?? false;
|
||||||
|
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
issueFilterStore.updateUserFilters(workspaceSlug.toString(), projectId.toString(), {
|
issuesFilterStore.updateFilters(workspaceSlug.toString(), projectId.toString(), EFilterType.DISPLAY_FILTERS, {
|
||||||
display_filters: {
|
calendar: {
|
||||||
calendar: {
|
...issuesFilterStore.issueFilters?.displayFilters?.calendar,
|
||||||
...issueFilterStore.userDisplayFilters.calendar,
|
show_weekends: !showWeekends,
|
||||||
show_weekends: !showWeekends,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -6,11 +6,27 @@ import { useMobxStore } from "lib/mobx/store-provider";
|
|||||||
import { CalendarMonthsDropdown, CalendarOptionsDropdown } from "components/issues";
|
import { CalendarMonthsDropdown, CalendarOptionsDropdown } from "components/issues";
|
||||||
// icons
|
// icons
|
||||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||||
|
import {
|
||||||
|
ICycleIssuesFilterStore,
|
||||||
|
IModuleIssuesFilterStore,
|
||||||
|
IProjectIssuesFilterStore,
|
||||||
|
IViewIssuesFilterStore,
|
||||||
|
} from "store/issues";
|
||||||
|
|
||||||
export const CalendarHeader: React.FC = observer(() => {
|
interface ICalendarHeader {
|
||||||
const { issueFilter: issueFilterStore, calendar: calendarStore } = useMobxStore();
|
issuesFilterStore:
|
||||||
|
| IProjectIssuesFilterStore
|
||||||
|
| IModuleIssuesFilterStore
|
||||||
|
| ICycleIssuesFilterStore
|
||||||
|
| IViewIssuesFilterStore;
|
||||||
|
}
|
||||||
|
|
||||||
const calendarLayout = issueFilterStore.userDisplayFilters.calendar?.layout ?? "month";
|
export const CalendarHeader: React.FC<ICalendarHeader> = observer((props) => {
|
||||||
|
const { issuesFilterStore } = props;
|
||||||
|
|
||||||
|
const { calendar: calendarStore } = useMobxStore();
|
||||||
|
|
||||||
|
const calendarLayout = issuesFilterStore.issueFilters?.displayFilters?.calendar?.layout ?? "month";
|
||||||
|
|
||||||
const { activeMonthDate, activeWeekDate } = calendarStore.calendarFilters;
|
const { activeMonthDate, activeWeekDate } = calendarStore.calendarFilters;
|
||||||
|
|
||||||
@ -91,7 +107,7 @@ export const CalendarHeader: React.FC = observer(() => {
|
|||||||
>
|
>
|
||||||
Today
|
Today
|
||||||
</button>
|
</button>
|
||||||
<CalendarOptionsDropdown />
|
<CalendarOptionsDropdown issuesFilterStore={issuesFilterStore} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -13,7 +13,6 @@ export const CycleCalendarLayout: React.FC = observer(() => {
|
|||||||
const {
|
const {
|
||||||
cycleIssues: cycleIssueStore,
|
cycleIssues: cycleIssueStore,
|
||||||
cycleIssuesFilter: cycleIssueFilterStore,
|
cycleIssuesFilter: cycleIssueFilterStore,
|
||||||
cycleIssueCalendarView: cycleIssueCalendarViewStore,
|
|
||||||
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
|
||||||
@ -62,7 +61,6 @@ export const CycleCalendarLayout: React.FC = observer(() => {
|
|||||||
<BaseCalendarRoot
|
<BaseCalendarRoot
|
||||||
issueStore={cycleIssueStore}
|
issueStore={cycleIssueStore}
|
||||||
issuesFilterStore={cycleIssueFilterStore}
|
issuesFilterStore={cycleIssueFilterStore}
|
||||||
calendarViewStore={cycleIssueCalendarViewStore}
|
|
||||||
QuickActions={CycleIssueQuickActions}
|
QuickActions={CycleIssueQuickActions}
|
||||||
issueActions={issueActions}
|
issueActions={issueActions}
|
||||||
viewId={cycleId.toString()}
|
viewId={cycleId.toString()}
|
||||||
|
@ -13,7 +13,6 @@ export const ModuleCalendarLayout: React.FC = observer(() => {
|
|||||||
const {
|
const {
|
||||||
moduleIssues: moduleIssueStore,
|
moduleIssues: moduleIssueStore,
|
||||||
moduleIssuesFilter: moduleIssueFilterStore,
|
moduleIssuesFilter: moduleIssueFilterStore,
|
||||||
moduleIssueCalendarView: moduleIssueCalendarViewStore,
|
|
||||||
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
|
||||||
@ -56,7 +55,6 @@ export const ModuleCalendarLayout: React.FC = observer(() => {
|
|||||||
<BaseCalendarRoot
|
<BaseCalendarRoot
|
||||||
issueStore={moduleIssueStore}
|
issueStore={moduleIssueStore}
|
||||||
issuesFilterStore={moduleIssueFilterStore}
|
issuesFilterStore={moduleIssueFilterStore}
|
||||||
calendarViewStore={moduleIssueCalendarViewStore}
|
|
||||||
QuickActions={ModuleIssueQuickActions}
|
QuickActions={ModuleIssueQuickActions}
|
||||||
issueActions={issueActions}
|
issueActions={issueActions}
|
||||||
viewId={moduleId}
|
viewId={moduleId}
|
||||||
|
@ -14,7 +14,6 @@ export const CalendarLayout: React.FC = observer(() => {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
projectIssues: issueStore,
|
projectIssues: issueStore,
|
||||||
issueCalendarView: issueCalendarViewStore,
|
|
||||||
projectIssuesFilter: projectIssueFiltersStore,
|
projectIssuesFilter: projectIssueFiltersStore,
|
||||||
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
@ -49,7 +48,6 @@ export const CalendarLayout: React.FC = observer(() => {
|
|||||||
<BaseCalendarRoot
|
<BaseCalendarRoot
|
||||||
issueStore={issueStore}
|
issueStore={issueStore}
|
||||||
issuesFilterStore={projectIssueFiltersStore}
|
issuesFilterStore={projectIssueFiltersStore}
|
||||||
calendarViewStore={issueCalendarViewStore}
|
|
||||||
QuickActions={ProjectIssueQuickActions}
|
QuickActions={ProjectIssueQuickActions}
|
||||||
issueActions={issueActions}
|
issueActions={issueActions}
|
||||||
handleDragDrop={handleDragDrop}
|
handleDragDrop={handleDragDrop}
|
||||||
|
@ -13,7 +13,6 @@ export const ProjectViewCalendarLayout: React.FC = observer(() => {
|
|||||||
const {
|
const {
|
||||||
viewIssues: projectViewIssuesStore,
|
viewIssues: projectViewIssuesStore,
|
||||||
viewIssuesFilter: projectIssueViewFiltersStore,
|
viewIssuesFilter: projectIssueViewFiltersStore,
|
||||||
projectViewIssueCalendarView: projectViewIssueCalendarViewStore,
|
|
||||||
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
calendarHelpers: { handleDragDrop: handleCalenderDragDrop },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ export const ProjectViewCalendarLayout: React.FC = observer(() => {
|
|||||||
<BaseCalendarRoot
|
<BaseCalendarRoot
|
||||||
issueStore={projectViewIssuesStore}
|
issueStore={projectViewIssuesStore}
|
||||||
issuesFilterStore={projectIssueViewFiltersStore}
|
issuesFilterStore={projectIssueViewFiltersStore}
|
||||||
calendarViewStore={projectViewIssueCalendarViewStore}
|
|
||||||
QuickActions={ProjectIssueQuickActions}
|
QuickActions={ProjectIssueQuickActions}
|
||||||
issueActions={issueActions}
|
issueActions={issueActions}
|
||||||
handleDragDrop={handleDragDrop}
|
handleDragDrop={handleDragDrop}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
// mobx store
|
|
||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
|
||||||
// components
|
// components
|
||||||
import { CalendarDayTile } from "components/issues";
|
import { CalendarDayTile } from "components/issues";
|
||||||
// helpers
|
// helpers
|
||||||
@ -10,8 +7,19 @@ import { renderDateFormat } from "helpers/date-time.helper";
|
|||||||
import { ICalendarDate, ICalendarWeek } from "./types";
|
import { ICalendarDate, ICalendarWeek } from "./types";
|
||||||
import { IIssue } from "types";
|
import { IIssue } from "types";
|
||||||
import { IGroupedIssues, IIssueResponse } from "store/issues/types";
|
import { IGroupedIssues, IIssueResponse } from "store/issues/types";
|
||||||
|
import {
|
||||||
|
ICycleIssuesFilterStore,
|
||||||
|
IModuleIssuesFilterStore,
|
||||||
|
IProjectIssuesFilterStore,
|
||||||
|
IViewIssuesFilterStore,
|
||||||
|
} from "store/issues";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
issuesFilterStore:
|
||||||
|
| IProjectIssuesFilterStore
|
||||||
|
| IModuleIssuesFilterStore
|
||||||
|
| ICycleIssuesFilterStore
|
||||||
|
| IViewIssuesFilterStore;
|
||||||
issues: IIssueResponse | undefined;
|
issues: IIssueResponse | undefined;
|
||||||
groupedIssueIds: IGroupedIssues;
|
groupedIssueIds: IGroupedIssues;
|
||||||
week: ICalendarWeek | undefined;
|
week: ICalendarWeek | undefined;
|
||||||
@ -27,12 +35,19 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CalendarWeekDays: React.FC<Props> = observer((props) => {
|
export const CalendarWeekDays: React.FC<Props> = observer((props) => {
|
||||||
const { issues, groupedIssueIds, week, quickActions, enableQuickIssueCreate, quickAddCallback, viewId } = props;
|
const {
|
||||||
|
issuesFilterStore,
|
||||||
|
issues,
|
||||||
|
groupedIssueIds,
|
||||||
|
week,
|
||||||
|
quickActions,
|
||||||
|
enableQuickIssueCreate,
|
||||||
|
quickAddCallback,
|
||||||
|
viewId,
|
||||||
|
} = props;
|
||||||
|
|
||||||
const { issueFilter: issueFilterStore } = useMobxStore();
|
const calendarLayout = issuesFilterStore?.issueFilters?.displayFilters?.calendar?.layout ?? "month";
|
||||||
|
const showWeekends = issuesFilterStore?.issueFilters?.displayFilters?.calendar?.show_weekends ?? false;
|
||||||
const calendarLayout = issueFilterStore.userDisplayFilters.calendar?.layout ?? "month";
|
|
||||||
const showWeekends = issueFilterStore.userDisplayFilters.calendar?.show_weekends ?? false;
|
|
||||||
|
|
||||||
if (!week) return null;
|
if (!week) return null;
|
||||||
|
|
||||||
@ -47,6 +62,7 @@ export const CalendarWeekDays: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CalendarDayTile
|
<CalendarDayTile
|
||||||
|
issuesFilterStore={issuesFilterStore}
|
||||||
key={renderDateFormat(date.date)}
|
key={renderDateFormat(date.date)}
|
||||||
date={date}
|
date={date}
|
||||||
issues={issues}
|
issues={issues}
|
||||||
|
@ -147,22 +147,22 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex-shrink-0 w-full bg-custom-background-90 py-1 sticky bottom-0 z-[0]">
|
<div className="flex-shrink-0 w-full bg-custom-background-90 py-1 sticky bottom-0 z-[0]">
|
||||||
{enableQuickIssueCreate && (
|
{enableQuickIssueCreate && (
|
||||||
<KanBanQuickAddIssueForm
|
<KanBanQuickAddIssueForm
|
||||||
formKey="name"
|
formKey="name"
|
||||||
groupId={getValueFromObject(_list, listKey) as string}
|
groupId={getValueFromObject(_list, listKey) as string}
|
||||||
subGroupId={sub_group_id}
|
subGroupId={sub_group_id}
|
||||||
prePopulatedData={{
|
prePopulatedData={{
|
||||||
...(group_by && { [group_by]: getValueFromObject(_list, listKey) }),
|
...(group_by && { [group_by]: getValueFromObject(_list, listKey) }),
|
||||||
...(sub_group_by && sub_group_id !== "null" && { [sub_group_by]: sub_group_id }),
|
...(sub_group_by && sub_group_id !== "null" && { [sub_group_by]: sub_group_id }),
|
||||||
}}
|
}}
|
||||||
quickAddCallback={quickAddCallback}
|
quickAddCallback={quickAddCallback}
|
||||||
viewId={viewId}
|
viewId={viewId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* {isDragStarted && isDragDisabled && (
|
{/* {isDragStarted && isDragDisabled && (
|
||||||
|
@ -24,6 +24,7 @@ export const IssueBlocksList: FC<Props> = (props) => {
|
|||||||
{issueIds && issueIds.length > 0 ? (
|
{issueIds && issueIds.length > 0 ? (
|
||||||
issueIds.map(
|
issueIds.map(
|
||||||
(issueId: string) =>
|
(issueId: string) =>
|
||||||
|
issueId != undefined &&
|
||||||
issues[issueId] && (
|
issues[issueId] && (
|
||||||
<IssueBlock
|
<IssueBlock
|
||||||
key={issues[issueId].id}
|
key={issues[issueId].id}
|
||||||
|
@ -87,16 +87,22 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = (props) =
|
|||||||
description_html: issue.description_html,
|
description_html: issue.description_html,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// adding issue.description_html or issue.name to dependency array causes
|
||||||
|
// editor rerendering on every save
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (issue.id) {
|
if (issue.id) {
|
||||||
setLocalIssueDescription({ id: issue.id, description_html: issue.description_html });
|
setLocalIssueDescription({ id: issue.id, description_html: issue.description_html });
|
||||||
setLocalTitleValue(issue.name);
|
setLocalTitleValue(issue.name);
|
||||||
}
|
}
|
||||||
}, [issue.id, issue.description_html, issue.name]);
|
}, [issue.id]);
|
||||||
|
|
||||||
const debouncedFormSave = debounce(async () => {
|
// ADDING handleDescriptionFormSubmit TO DEPENDENCY ARRAY PRODUCES ADVERSE EFFECTS
|
||||||
handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting("submitted"));
|
const debouncedFormSave = useCallback(
|
||||||
}, 1500);
|
debounce(async () => {
|
||||||
|
handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting("submitted"));
|
||||||
|
}, 1500),
|
||||||
|
[handleSubmit]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSubmitting === "submitted") {
|
if (isSubmitting === "submitted") {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.13.2",
|
"version": "0.14.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "turbo run develop",
|
"dev": "turbo run develop",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef, useState, ReactElement } from "react";
|
import React, { useEffect, useRef, useState, ReactElement, useCallback } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import useSWR, { MutatorOptions } from "swr";
|
import useSWR, { MutatorOptions } from "swr";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
@ -59,7 +59,7 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
|||||||
|
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
|
|
||||||
const { handleSubmit, reset, setValue, watch, getValues, control } = useForm<IPage>({
|
const { handleSubmit, setValue, watch, getValues, control } = useForm<IPage>({
|
||||||
defaultValues: { name: "", description_html: "" },
|
defaultValues: { name: "", description_html: "" },
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -152,6 +152,8 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
|||||||
}
|
}
|
||||||
}, [isSubmitting, setShowAlert]);
|
}, [isSubmitting, setShowAlert]);
|
||||||
|
|
||||||
|
// adding pageDetails.description_html to dependency array causes
|
||||||
|
// editor rerendering on every save
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (pageDetails?.description_html) {
|
if (pageDetails?.description_html) {
|
||||||
setLocalIssueDescription({ id: pageId as string, description_html: pageDetails.description_html });
|
setLocalIssueDescription({ id: pageId as string, description_html: pageDetails.description_html });
|
||||||
@ -326,9 +328,13 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
|||||||
description_html: "",
|
description_html: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const debouncedFormSave = debounce(async () => {
|
// ADDING updatePage TO DEPENDENCY ARRAY PRODUCES ADVERSE EFFECTS
|
||||||
handleSubmit(updatePage)().finally(() => setIsSubmitting("submitted"));
|
const debouncedFormSave = useCallback(
|
||||||
}, 1500);
|
debounce(async () => {
|
||||||
|
handleSubmit(updatePage)().finally(() => setIsSubmitting("submitted"));
|
||||||
|
}, 1500),
|
||||||
|
[handleSubmit]
|
||||||
|
);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return (
|
return (
|
||||||
|
Loading…
Reference in New Issue
Block a user