merge conflicts resolved

This commit is contained in:
Anmol Singh Bhatia 2023-09-26 18:17:47 +05:30
commit c55c021a37
5 changed files with 153 additions and 65 deletions

View File

@ -8,8 +8,8 @@ Before submitting a new issue, please search the [issues](https://github.com/mak
While we want to fix all the [issues](https://github.com/makeplane/plane/issues), before fixing a bug we need to be able to reproduce and confirm it. Please provide us with a minimal reproduction scenario using a repository or [Gist](https://gist.github.com/). Having a live, reproducible scenario gives us the information without asking questions back & forth with additional questions like: While we want to fix all the [issues](https://github.com/makeplane/plane/issues), before fixing a bug we need to be able to reproduce and confirm it. Please provide us with a minimal reproduction scenario using a repository or [Gist](https://gist.github.com/). Having a live, reproducible scenario gives us the information without asking questions back & forth with additional questions like:
- 3rd-party libraries being used and their versions - 3rd-party libraries being used and their versions
- a use-case that fails - a use-case that fails
Without said minimal reproduction, we won't be able to investigate all [issues](https://github.com/makeplane/plane/issues), and the issue might not be resolved. Without said minimal reproduction, we won't be able to investigate all [issues](https://github.com/makeplane/plane/issues), and the issue might not be resolved.
@ -19,10 +19,10 @@ You can open a new issue with this [issue form](https://github.com/makeplane/pla
### Requirements ### Requirements
- Node.js version v16.18.0 - Node.js version v16.18.0
- Python version 3.8+ - Python version 3.8+
- Postgres version v14 - Postgres version v14
- Redis version v6.2.7 - Redis version v6.2.7
### Setup the project ### Setup the project
@ -30,6 +30,48 @@ The project is a monorepo, with backend api and frontend in a single repo.
The backend is a django project which is kept inside apiserver The backend is a django project which is kept inside apiserver
1. Clone the repo
```bash
git clone https://github.com/makeplane/plane
cd plane
chmod +x setup.sh
```
2. Run setup.sh
```bash
./setup.sh
```
3. Define `NEXT_PUBLIC_API_BASE_URL=http://localhost` in **web/.env** and **space/.env** file
```bash
echo "\nNEXT_PUBLIC_API_BASE_URL=http://localhost\n" >> ./web/.env
```
```bash
echo "\nNEXT_PUBLIC_API_BASE_URL=http://localhost\n" >> ./space/.env
```
4. Run Docker compose up
```bash
docker compose up -d
```
5. Install dependencies
```bash
yarn install
```
6. Run the web app in development mode
```bash
yarn dev
```
## Missing a Feature? ## Missing a Feature?
If a feature is missing, you can directly _request_ a new one [here](https://github.com/makeplane/plane/issues/new?assignees=&labels=feature&template=feature_request.yml&title=%F0%9F%9A%80+Feature%3A+). You also can do the same by choosing "🚀 Feature" when raising a [New Issue](https://github.com/makeplane/plane/issues/new/choose) on our GitHub Repository. If a feature is missing, you can directly _request_ a new one [here](https://github.com/makeplane/plane/issues/new?assignees=&labels=feature&template=feature_request.yml&title=%F0%9F%9A%80+Feature%3A+). You also can do the same by choosing "🚀 Feature" when raising a [New Issue](https://github.com/makeplane/plane/issues/new/choose) on our GitHub Repository.
@ -39,8 +81,8 @@ If you would like to _implement_ it, an issue with your proposal must be submitt
To ensure consistency throughout the source code, please keep these rules in mind as you are working: To ensure consistency throughout the source code, please keep these rules in mind as you are working:
- All features or bug fixes must be tested by one or more specs (unit-tests). - All features or bug fixes must be tested by one or more specs (unit-tests).
- We use [Eslint default rule guide](https://eslint.org/docs/rules/), with minor changes. An automated formatter is available using prettier. - We use [Eslint default rule guide](https://eslint.org/docs/rules/), with minor changes. An automated formatter is available using prettier.
## Need help? Questions and suggestions ## Need help? Questions and suggestions
@ -48,11 +90,11 @@ Questions, suggestions, and thoughts are most welcome. We can also be reached in
## Ways to contribute ## Ways to contribute
- Try Plane Cloud and the self hosting platform and give feedback - Try Plane Cloud and the self hosting platform and give feedback
- Add new integrations - Add new integrations
- Help with open [issues](https://github.com/makeplane/plane/issues) or [create your own](https://github.com/makeplane/plane/issues/new/choose) - Help with open [issues](https://github.com/makeplane/plane/issues) or [create your own](https://github.com/makeplane/plane/issues/new/choose)
- Share your thoughts and suggestions with us - Share your thoughts and suggestions with us
- Help create tutorials and blog posts - Help create tutorials and blog posts
- Request a feature by submitting a proposal - Request a feature by submitting a proposal
- Report a bug - Report a bug
- **Improve documentation** - fix incomplete or missing [docs](https://docs.plane.so/), bad wording, examples or explanations. - **Improve documentation** - fix incomplete or missing [docs](https://docs.plane.so/), bad wording, examples or explanations.

View File

@ -93,7 +93,9 @@ export const IssuesFilterView: React.FC = () => {
<Tooltip <Tooltip
key={option.type} key={option.type}
tooltipContent={ tooltipContent={
<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} Layout</span> <span className="capitalize">
{replaceUnderscoreIfSnakeCase(option.type)} Layout
</span>
} }
position="bottom" position="bottom"
> >
@ -318,7 +320,7 @@ export const IssuesFilterView: React.FC = () => {
displayFilters.layout !== "spreadsheet" && displayFilters.layout !== "spreadsheet" &&
displayFilters.layout !== "gantt_chart" && ( displayFilters.layout !== "gantt_chart" && (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-custom-text-200">Show empty states</h4> <h4 className="text-custom-text-200">Show empty groups</h4>
<div className="w-28"> <div className="w-28">
<ToggleSwitch <ToggleSwitch
value={displayFilters.show_empty_groups ?? true} value={displayFilters.show_empty_groups ?? true}

View File

@ -20,7 +20,7 @@ import { renderEmoji } from "helpers/emoji.helper";
// types // types
import { IIssueViewProps, IState, TIssuePriorities, TStateGroups } from "types"; import { IIssueViewProps, IState, TIssuePriorities, TStateGroups } from "types";
// fetch-keys // fetch-keys
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys"; import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, WORKSPACE_LABELS } from "constants/fetch-keys";
// constants // constants
import { STATE_GROUP_COLORS } from "constants/state"; import { STATE_GROUP_COLORS } from "constants/state";
@ -59,6 +59,15 @@ export const BoardHeader: React.FC<Props> = ({
: null : null
); );
const { data: workspaceLabels } = useSWR(
workspaceSlug && displayFilters?.group_by === "labels"
? WORKSPACE_LABELS(workspaceSlug.toString())
: null,
workspaceSlug && displayFilters?.group_by === "labels"
? () => issuesService.getWorkspaceLabels(workspaceSlug.toString())
: null
);
const { data: members } = useSWR( const { data: members } = useSWR(
workspaceSlug && workspaceSlug &&
projectId && projectId &&
@ -82,7 +91,10 @@ export const BoardHeader: React.FC<Props> = ({
title = addSpaceIfCamelCase(currentState?.name ?? ""); title = addSpaceIfCamelCase(currentState?.name ?? "");
break; break;
case "labels": case "labels":
title = issueLabels?.find((label) => label.id === groupTitle)?.name ?? "None"; title =
[...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find(
(label) => label.id === groupTitle
)?.name ?? "None";
break; break;
case "project": case "project":
title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; title = projects?.find((p) => p.id === groupTitle)?.name ?? "None";
@ -137,7 +149,9 @@ export const BoardHeader: React.FC<Props> = ({
break; break;
case "labels": case "labels":
const labelColor = const labelColor =
issueLabels?.find((label) => label.id === groupTitle)?.color ?? "#000000"; [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find(
(label) => label.id === groupTitle
)?.color ?? "#000000";
icon = ( icon = (
<span <span
className="h-3.5 w-3.5 flex-shrink-0 rounded-full" className="h-3.5 w-3.5 flex-shrink-0 rounded-full"

View File

@ -266,7 +266,7 @@ export const ProfileIssuesViewOptions: React.FC = () => {
displayFilters?.layout !== "spreadsheet" && ( displayFilters?.layout !== "spreadsheet" && (
<> <>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-custom-text-200">Show empty states</h4> <h4 className="text-custom-text-200">Show empty groups</h4>
<div className="w-28"> <div className="w-28">
<ToggleSwitch <ToggleSwitch
value={displayFilters?.show_empty_groups ?? true} value={displayFilters?.show_empty_groups ?? true}

View File

@ -31,15 +31,53 @@ import { BoltOutlined, GridViewOutlined } from "@mui/icons-material";
import emptyDashboard from "public/empty-state/dashboard.svg"; import emptyDashboard from "public/empty-state/dashboard.svg";
import githubBlackImage from "/public/logos/github-black.png"; import githubBlackImage from "/public/logos/github-black.png";
import githubWhiteImage from "/public/logos/github-white.png"; import githubWhiteImage from "/public/logos/github-white.png";
// helpers
import { render12HourFormatTime, renderShortDate } from "helpers/date-time.helper";
// types // types
import { ICurrentUserResponse } from "types"; import { ICurrentUserResponse } from "types";
import type { NextPage } from "next"; import type { NextPage } from "next";
// fetch-keys // fetch-keys
import { CURRENT_USER, USER_WORKSPACE_DASHBOARD } from "constants/fetch-keys"; import { CURRENT_USER, USER_WORKSPACE_DASHBOARD } from "constants/fetch-keys";
// constants
import { DAYS } from "constants/project"; const Greeting = ({ user }: { user: ICurrentUserResponse | undefined }) => {
const currentTime = new Date();
const hour = new Intl.DateTimeFormat("en-US", {
hour12: false,
hour: "numeric",
}).format(currentTime);
const date = new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
}).format(currentTime);
const weekDay = new Intl.DateTimeFormat("en-US", {
weekday: "long",
}).format(currentTime);
const timeString = new Intl.DateTimeFormat("en-US", {
timeZone: user?.user_timezone,
hour12: false, // Use 24-hour format
hour: "2-digit",
minute: "2-digit",
}).format(currentTime);
const greeting =
parseInt(hour, 10) < 12 ? "morning" : parseInt(hour, 10) < 18 ? "afternoon" : "evening";
return (
<div>
<h3 className="text-2xl font-semibold">
Good {greeting}, {user?.first_name} {user?.last_name}
</h3>
<h6 className="text-custom-text-400 font-medium flex items-center gap-2">
<div>{greeting === "morning" ? "🌤️" : greeting === "afternoon" ? "🌥️" : "🌙️"}</div>
<div>
{weekDay}, {date} {timeString}
</div>
</h6>
</div>
);
};
const WorkspacePage: NextPage = () => { const WorkspacePage: NextPage = () => {
const [month, setMonth] = useState(new Date().getMonth() + 1); const [month, setMonth] = useState(new Date().getMonth() + 1);
@ -58,10 +96,6 @@ const WorkspacePage: NextPage = () => {
workspaceSlug ? () => userService.userWorkspaceDashboard(workspaceSlug as string, month) : null workspaceSlug ? () => userService.userWorkspaceDashboard(workspaceSlug as string, month) : null
); );
const today = new Date();
const greeting =
today.getHours() < 12 ? "morning" : today.getHours() < 18 ? "afternoon" : "evening";
useEffect(() => { useEffect(() => {
if (!workspaceSlug) return; if (!workspaceSlug) return;
@ -127,9 +161,11 @@ const WorkspacePage: NextPage = () => {
/> />
</div> </div>
)} )}
{projects ? ( <div className="p-8 space-y-8">
projects.length > 0 ? ( <Greeting user={user} />
<div className="p-8">
{projects ? (
projects.length > 0 ? (
<div className="flex flex-col gap-8"> <div className="flex flex-col gap-8">
<IssuesStats data={workspaceDashboardData} /> <IssuesStats data={workspaceDashboardData} />
<div className="grid grid-cols-1 gap-8 lg:grid-cols-2"> <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
@ -143,40 +179,34 @@ const WorkspacePage: NextPage = () => {
/> />
</div> </div>
</div> </div>
</div> ) : (
) : ( <div className="p-8">
<div className="p-8"> <Greeting user={user} />
<h3 className="text-2xl font-semibold"> <div className="mt-7 bg-custom-primary-100/5 flex justify-between gap-5 md:gap-8">
Good {greeting}, {user?.first_name} {user?.last_name} <div className="p-5 md:p-8 pr-0">
</h3> <h5 className="text-xl font-semibold">Create a project</h5>
<h6 className="text-custom-text-400 font-medium"> <p className="mt-2 mb-5">
{greeting === "morning" ? "🌤️" : greeting === "afternoon" ? "🌥️" : "🌙️"} Manage your projects by creating issues, cycles, modules, views and pages.
{DAYS[today.getDay()]}, {renderShortDate(today)} {render12HourFormatTime(today)} </p>
</h6> <PrimaryButton
<div className="mt-7 bg-custom-primary-100/5 flex justify-between gap-5 md:gap-8"> onClick={() => {
<div className="p-5 md:p-8 pr-0"> const e = new KeyboardEvent("keydown", {
<h5 className="text-xl font-semibold">Create a project</h5> key: "p",
<p className="mt-2 mb-5"> });
Manage your projects by creating issues, cycles, modules, views and pages. document.dispatchEvent(e);
</p> }}
<PrimaryButton >
onClick={() => { Create Project
const e = new KeyboardEvent("keydown", { </PrimaryButton>
key: "p", </div>
}); <div className="hidden md:block self-end overflow-hidden pt-8">
document.dispatchEvent(e); <Image src={emptyDashboard} alt="Empty Dashboard" />
}} </div>
>
Create Project
</PrimaryButton>
</div>
<div className="hidden md:block self-end overflow-hidden pt-8">
<Image src={emptyDashboard} alt="Empty Dashboard" />
</div> </div>
</div> </div>
</div> )
) ) : null}
) : null} </div>
</WorkspaceAuthorizationLayout> </WorkspaceAuthorizationLayout>
); );
}; };