Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1750ba3
fix: my issue duplication (#1882)
pablohashescobar Aug 16, 2023
2b6deba
Updated setup document to include tiptap pro install (#1871)
aditipatelpro Aug 16, 2023
10dface
chore: updated error pages 404 and project-not-found in plane deploy …
gurusainath Aug 16, 2023
b24622e
fix: validation for issue activity description (#1887)
NarayanBavisetti Aug 16, 2023
f849712
style: fixed display name coming twice on profile page (#1889)
dakshesh14 Aug 16, 2023
5b6b43f
fix: quick action buttons: (#1884)
aaryan610 Aug 16, 2023
65295f6
chore: updating the theme using MobX from command k (#1879)
gurusainath Aug 16, 2023
0afd72d
fix: updated theming in workspace preferences (#1890)
gurusainath Aug 16, 2023
abb8782
fix: handled default view on plane deploy (#1893)
gurusainath Aug 17, 2023
e593a8d
chore: Edited Setup Script to take TipTap Auth Token and Generate .np…
henit-chobisa Aug 18, 2023
d74ec7b
fix: ui improvement and bug fixes (#1883)
anmolsinghbhatia Aug 18, 2023
c3c6ba9
chore: link edit functionality (#1895)
anmolsinghbhatia Aug 18, 2023
93fec2c
fix: completed cycle validation , style: assignee count alignment fix…
anmolsinghbhatia Aug 18, 2023
b67e30f
chore: analytics start date property for x-axis and group (#1888)
aaryan610 Aug 18, 2023
6344f6f
chore: set order by to manual on gantt chart (#1886)
aaryan610 Aug 18, 2023
9316475
style: analytics stats empty state (#1903)
anmolsinghbhatia Aug 18, 2023
02ac4ce
chore: renamed target date to start date (#1902)
NarayanBavisetti Aug 18, 2023
125e909
chore: module link model (#1905)
NarayanBavisetti Aug 18, 2023
1f8117c
fix: dashboard upcoming issues list (#1904)
aaryan610 Aug 18, 2023
d825dc5
style: showing first name for bot profile (#1894)
dakshesh14 Aug 18, 2023
2f39181
fix: priority ordering (#1908)
NarayanBavisetti Aug 18, 2023
0fbdc0b
style: consistent ui for create update issue modal (#1907)
anmolsinghbhatia Aug 18, 2023
8d50183
chore: add favorite project from sidebar (#1909)
anmolsinghbhatia Aug 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ chmod +x setup.sh

> If running in a cloud env replace localhost with public facing IP address of the VM

- Setup Tiptap Pro

Visit [Tiptap Pro](https://collab.tiptap.dev/pro-extensions) and signup (it is free).

Create a **`.npmrc`** file, copy the following and replace your registry token generated from Tiptap Pro.

```
@tiptap-pro:registry=https://registry.tiptap.dev/
//registry.tiptap.dev/:_authToken=YOUR_REGISTRY_TOKEN
```
- Run Docker compose up

```bash
Expand Down
2 changes: 1 addition & 1 deletion apiserver/plane/api/views/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def get(self, request, slug):
)
)
.filter(**filters)
)
).distinct()

# Priority Ordering
if order_by_param == "priority" or order_by_param == "-priority":
Expand Down
5 changes: 3 additions & 2 deletions apiserver/plane/api/views/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -994,11 +994,11 @@ def get(self, request, slug):

upcoming_issues = Issue.issue_objects.filter(
~Q(state__group__in=["completed", "cancelled"]),
target_date__gte=timezone.now(),
start_date__gte=timezone.now(),
workspace__slug=slug,
assignees__in=[request.user],
completed_at__isnull=True,
).values("id", "name", "workspace__slug", "project_id", "target_date")
).values("id", "name", "workspace__slug", "project_id", "start_date")

return Response(
{
Expand Down Expand Up @@ -1083,6 +1083,7 @@ def get(self, request, slug, user_id):
.filter(**filters)
.values("priority")
.annotate(priority_count=Count("priority"))
.filter(priority_count__gte=1)
.annotate(
priority_order=Case(
*[
Expand Down
31 changes: 18 additions & 13 deletions apiserver/plane/bgtasks/issue_activites_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,24 @@ def track_description(
if current_instance.get("description_html") != requested_data.get(
"description_html"
):
issue_activities.append(
IssueActivity(
issue_id=issue_id,
actor=actor,
verb="updated",
old_value=current_instance.get("description_html"),
new_value=requested_data.get("description_html"),
field="description",
project=project,
workspace=project.workspace,
comment=f"updated the description to {requested_data.get('description_html')}",
)
)
last_activity = IssueActivity.objects.filter(issue_id=issue_id).order_by("-created_at").first()
if(last_activity is not None and last_activity.field == "description" and actor.id == last_activity.actor_id):
last_activity.created_at = timezone.now()
last_activity.save(update_fields=["created_at"])
else:
issue_activities.append(
IssueActivity(
issue_id=issue_id,
actor=actor,
verb="updated",
old_value=current_instance.get("description_html"),
new_value=requested_data.get("description_html"),
field="description",
project=project,
workspace=project.workspace,
comment=f"updated the description to {requested_data.get('description_html')}",
)
)


# Track changes in issue target date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ class Migration(migrations.Migration):
'unique_together': {('issue', 'actor')},
},
),
migrations.AlterField(
model_name='modulelink',
name='title',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.RunPython(generate_display_name),
migrations.RunPython(rectify_field_issue_activity),
migrations.RunPython(update_assignee_issue_activity),
Expand Down
2 changes: 1 addition & 1 deletion apiserver/plane/db/models/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def __str__(self):


class ModuleLink(ProjectBaseModel):
title = models.CharField(max_length=255, null=True)
title = models.CharField(max_length=255, blank=True, null=True)
url = models.URLField()
module = models.ForeignKey(
Module, on_delete=models.CASCADE, related_name="link_module"
Expand Down
17 changes: 15 additions & 2 deletions apps/app/components/analytics/scope-and-demand/leaderboard.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// ui
import { ProfileEmptyState } from "components/ui";
// image
import emptyUsers from "public/empty-state/empty_users.svg";

type Props = {
users: {
avatar: string | null;
Expand All @@ -8,10 +13,16 @@ type Props = {
id: string;
}[];
title: string;
emptyStateMessage: string;
workspaceSlug: string;
};

export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title, workspaceSlug }) => (
export const AnalyticsLeaderboard: React.FC<Props> = ({
users,
title,
emptyStateMessage,
workspaceSlug,
}) => (
<div className="p-3 border border-custom-border-200 rounded-[10px]">
<h6 className="text-base font-medium">{title}</h6>
{users.length > 0 ? (
Expand Down Expand Up @@ -47,7 +58,9 @@ export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title, workspaceS
))}
</div>
) : (
<div className="text-custom-text-200 text-center text-sm py-8">No matching data found.</div>
<div className="px-7 py-4">
<ProfileEmptyState title="No Data yet" description={emptyStateMessage} image={emptyUsers} />
</div>
)}
</div>
);
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const ScopeAndDemand: React.FC<Props> = ({ fullScreen = true }) => {
id: user?.created_by__id,
}))}
title="Most issues created"
emptyStateMessage="Co-workers and the number issues created by them appears here."
workspaceSlug={workspaceSlug?.toString() ?? ""}
/>
<AnalyticsLeaderboard
Expand All @@ -75,6 +76,7 @@ export const ScopeAndDemand: React.FC<Props> = ({ fullScreen = true }) => {
id: user?.assignees__id,
}))}
title="Most issues closed"
emptyStateMessage="Co-workers and the number issues closed by them appears here."
workspaceSlug={workspaceSlug?.toString() ?? ""}
/>
<div className={fullScreen ? "md:col-span-2" : ""}>
Expand Down
12 changes: 9 additions & 3 deletions apps/app/components/analytics/scope-and-demand/scope.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ui
import { BarGraph } from "components/ui";
import { BarGraph, ProfileEmptyState } from "components/ui";
// image
import emptyBarGraph from "public/empty-state/empty_bar_graph.svg";
// types
import { IDefaultAnalyticsResponse } from "types";

Expand Down Expand Up @@ -70,8 +72,12 @@ export const AnalyticsScope: React.FC<Props> = ({ defaultAnalytics }) => (
}}
/>
) : (
<div className="text-custom-text-200 text-center text-sm py-8">
No matching data found.
<div className="px-7 py-4">
<ProfileEmptyState
title="No Data yet"
description="Analysis of pending issues by co-workers appears here."
image={emptyBarGraph}
/>
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// ui
import { LineGraph } from "components/ui";
import { LineGraph, ProfileEmptyState } from "components/ui";
// image
import emptyGraph from "public/empty-state/empty_graph.svg";
// types
import { IDefaultAnalyticsResponse } from "types";
// constants
Expand Down Expand Up @@ -48,7 +50,13 @@ export const AnalyticsYearWiseIssues: React.FC<Props> = ({ defaultAnalytics }) =
enableArea
/>
) : (
<div className="text-custom-text-200 text-center text-sm py-8">No matching data found.</div>
<div className="px-7 py-4">
<ProfileEmptyState
title="No Data yet"
description="Close issues to view analysis of the same in the form of a graph."
image={emptyGraph}
/>
</div>
)}
</div>
);
36 changes: 12 additions & 24 deletions apps/app/components/command-palette/change-interface-theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ import userService from "services/user.service";
import useUser from "hooks/use-user";
// helper
import { unsetCustomCssVariables } from "helpers/theme.helper";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";

type Props = {
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
};

export const ChangeInterfaceTheme: React.FC<Props> = ({ setIsPaletteOpen }) => {
export const ChangeInterfaceTheme: React.FC<Props> = observer(({ setIsPaletteOpen }) => {
const store: any = useMobxStore();

const [mounted, setMounted] = useState(false);

const { setTheme } = useTheme();
Expand All @@ -23,29 +29,11 @@ export const ChangeInterfaceTheme: React.FC<Props> = ({ setIsPaletteOpen }) => {

const updateUserTheme = (newTheme: string) => {
if (!user) return;

unsetCustomCssVariables();

setTheme(newTheme);

mutateUser((prevData: any) => {
if (!prevData) return prevData;

return {
...prevData,
theme: {
...prevData?.theme,
theme: newTheme,
},
};
}, false);

userService.updateUser({
theme: {
...user.theme,
theme: newTheme,
},
});
return store.user
.updateCurrentUserSettings({ theme: { ...user.theme, theme: newTheme } })
.then((response: any) => response)
.catch((error: any) => error);
};

// useEffect only runs on the client, so now we can safely show the UI
Expand Down Expand Up @@ -74,4 +62,4 @@ export const ChangeInterfaceTheme: React.FC<Props> = ({ setIsPaletteOpen }) => {
))}
</>
);
};
});
2 changes: 1 addition & 1 deletion apps/app/components/core/modals/gpt-assistant-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export const GptAssistantModal: React.FC<Props> = ({
}`}
>
{((content && content !== "") || (htmlContent && htmlContent !== "<p></p>")) && (
<div id="tiptap-container" className="text-sm">
<div className="text-sm">
Content:
<TiptapEditor
value={htmlContent ?? `<p>${content}</p>`}
Expand Down
56 changes: 44 additions & 12 deletions apps/app/components/core/modals/link-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect } from "react";

// react-hook-form
import { useForm } from "react-hook-form";
Expand All @@ -7,20 +7,30 @@ import { Dialog, Transition } from "@headlessui/react";
// ui
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
// types
import type { IIssueLink, ModuleLink } from "types";
import type { IIssueLink, linkDetails, ModuleLink } from "types";

type Props = {
isOpen: boolean;
handleClose: () => void;
onFormSubmit: (formData: IIssueLink | ModuleLink) => Promise<void>;
data?: linkDetails | null;
status: boolean;
createIssueLink: (formData: IIssueLink | ModuleLink) => Promise<void>;
updateIssueLink: (formData: IIssueLink | ModuleLink, linkId: string) => Promise<void>;
};

const defaultValues: IIssueLink | ModuleLink = {
title: "",
url: "",
};

export const LinkModal: React.FC<Props> = ({ isOpen, handleClose, onFormSubmit }) => {
export const LinkModal: React.FC<Props> = ({
isOpen,
handleClose,
createIssueLink,
updateIssueLink,
status,
data,
}) => {
const {
register,
formState: { errors, isSubmitting },
Expand All @@ -30,11 +40,6 @@ export const LinkModal: React.FC<Props> = ({ isOpen, handleClose, onFormSubmit }
defaultValues,
});

const onSubmit = async (formData: IIssueLink | ModuleLink) => {
await onFormSubmit({ title: formData.title, url: formData.url });
onClose();
};

const onClose = () => {
handleClose();
const timeout = setTimeout(() => {
Expand All @@ -43,6 +48,27 @@ export const LinkModal: React.FC<Props> = ({ isOpen, handleClose, onFormSubmit }
}, 500);
};

const handleFormSubmit = async (formData: IIssueLink | ModuleLink) => {
if (!data) await createIssueLink({ title: formData.title, url: formData.url });
else await updateIssueLink({ title: formData.title, url: formData.url }, data.id);
onClose();
};

const handleCreateUpdatePage = async (formData: IIssueLink | ModuleLink) => {
await handleFormSubmit(formData);

reset({
...defaultValues,
});
};

useEffect(() => {
reset({
...defaultValues,
...data,
});
}, [data, reset]);

return (
<Transition.Root show={isOpen} as={React.Fragment}>
<Dialog as="div" className="relative z-20" onClose={onClose}>
Expand Down Expand Up @@ -70,14 +96,14 @@ export const LinkModal: React.FC<Props> = ({ isOpen, handleClose, onFormSubmit }
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 border border-custom-border-200 px-5 py-8 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl sm:p-6">
<form onSubmit={handleSubmit(onSubmit)}>
<form onSubmit={handleSubmit(handleCreateUpdatePage)}>
<div>
<div className="space-y-5">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-custom-text-100"
>
Add Link
{status ? "Update Link" : "Add Link"}
</Dialog.Title>
<div className="mt-2 space-y-3">
<div>
Expand Down Expand Up @@ -113,7 +139,13 @@ export const LinkModal: React.FC<Props> = ({ isOpen, handleClose, onFormSubmit }
<div className="mt-5 flex justify-end gap-2">
<SecondaryButton onClick={onClose}>Cancel</SecondaryButton>
<PrimaryButton type="submit" loading={isSubmitting}>
{isSubmitting ? "Adding Link..." : "Add Link"}
{status
? isSubmitting
? "Updating Link..."
: "Update Link"
: isSubmitting
? "Adding Link..."
: "Add Link"}
</PrimaryButton>
</div>
</form>
Expand Down
Loading