Skip to content

Commit

Permalink
feat: label grouping in dropdowns, default state in project settings (#…
Browse files Browse the repository at this point in the history
…266)

* feat: label grouping in dropdowns, default state in project settings

* feat: label disclosure default open

* refactor: label setting page

* chore: tooltip component updated

* chore: tooltip component updated

* feat/state_sequence_change
  • Loading branch information
aaryan610 authored Feb 10, 2023
1 parent 7c06be1 commit a403c0c
Show file tree
Hide file tree
Showing 27 changed files with 1,018 additions and 656 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// TODO: Refactor this component: into a different file, use this file to export the components
import React, { useState, useCallback, useEffect } from "react";

import { useRouter } from "next/router";
Expand All @@ -14,7 +13,7 @@ import useTheme from "hooks/use-theme";
import useToast from "hooks/use-toast";
import useUser from "hooks/use-user";
// components
import ShortcutsModal from "components/command-palette/shortcuts";
import { ShortcutsModal } from "components/command-palette";
import { BulkDeleteIssuesModal } from "components/core";
import { CreateProjectModal } from "components/project";
import { CreateUpdateIssueModal } from "components/issues";
Expand All @@ -36,7 +35,7 @@ import { IIssue } from "types";
// fetch-keys
import { USER_ISSUE } from "constants/fetch-keys";

const CommandPalette: React.FC = () => {
export const CommandPalette: React.FC = () => {
const [query, setQuery] = useState("");

const [isPaletteOpen, setIsPaletteOpen] = useState(false);
Expand Down Expand Up @@ -369,5 +368,3 @@ const CommandPalette: React.FC = () => {
</>
);
};

export default CommandPalette;
2 changes: 2 additions & 0 deletions apps/app/components/command-palette/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./command-pallette";
export * from "./shortcuts-modal";
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const shortcuts = [
},
];

const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
export const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
const [query, setQuery] = useState("");

const filteredShortcuts = shortcuts.filter((shortcut) =>
Expand Down Expand Up @@ -150,5 +150,3 @@ const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
</Transition.Root>
);
};

export default ShortcutsModal;
1 change: 1 addition & 0 deletions apps/app/components/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./board-view";
export * from "./list-view";
export * from "./sidebar";
export * from "./bulk-delete-issues-modal";
export * from "./existing-issues-list-modal";
export * from "./image-upload-modal";
Expand Down
2 changes: 2 additions & 0 deletions apps/app/components/core/sidebar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./sidebar-progress-stats";
export * from "./single-progress-stats";
6 changes: 2 additions & 4 deletions apps/app/components/core/sidebar/sidebar-progress-stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Tab } from "@headlessui/react";
import issuesServices from "services/issues.service";
import projectService from "services/project.service";
// components
import SingleProgressStats from "components/core/sidebar/single-progress-stats";
import { SingleProgressStats } from "components/core";
// ui
import { Avatar } from "components/ui";
// icons
Expand All @@ -36,7 +36,7 @@ const stateGroupColours: {
completed: "#096e8d",
};

const SidebarProgressStats: React.FC<Props> = ({ groupedIssues, issues }) => {
export const SidebarProgressStats: React.FC<Props> = ({ groupedIssues, issues }) => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const { data: issueLabels } = useSWR<IIssueLabels[]>(
Expand Down Expand Up @@ -180,5 +180,3 @@ const SidebarProgressStats: React.FC<Props> = ({ groupedIssues, issues }) => {
</div>
);
};

export default SidebarProgressStats;
32 changes: 16 additions & 16 deletions apps/app/components/core/sidebar/single-progress-stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ type TSingleProgressStatsProps = {
total: number;
};

const SingleProgressStats: React.FC<TSingleProgressStatsProps> = ({ title, completed, total }) => (
<>
<div className="flex items-center justify-between w-full py-3 text-xs border-b-[1px] border-gray-200">
<div className="flex items-center justify-start w-1/2 gap-2">{title}</div>
<div className="flex items-center justify-end w-1/2 gap-1 px-2">
<div className="flex h-5 justify-center items-center gap-1 ">
<span className="h-4 w-4 ">
<CircularProgressbar value={completed} maxValue={total} strokeWidth={10} />
</span>
<span className="w-8 text-right">{Math.floor((completed / total) * 100)}%</span>
</div>
<span>of</span>
<span>{total}</span>
export const SingleProgressStats: React.FC<TSingleProgressStatsProps> = ({
title,
completed,
total,
}) => (
<div className="flex items-center justify-between w-full py-3 text-xs border-b-[1px] border-gray-200">
<div className="flex items-center justify-start w-1/2 gap-2">{title}</div>
<div className="flex items-center justify-end w-1/2 gap-1 px-2">
<div className="flex h-5 justify-center items-center gap-1 ">
<span className="h-4 w-4 ">
<CircularProgressbar value={completed} maxValue={total} strokeWidth={10} />
</span>
<span className="w-8 text-right">{Math.floor((completed / total) * 100)}%</span>
</div>
<span>of</span>
<span>{total}</span>
</div>
</>
</div>
);

export default SingleProgressStats;
39 changes: 23 additions & 16 deletions apps/app/components/cycles/modal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Fragment } from "react";

import { mutate } from "swr";

// headless ui
import { Dialog, Transition } from "@headlessui/react";
// services
import cycleService from "services/cycles.service";
// hooks
import useToast from "hooks/use-toast";
// components
import { CycleForm } from "components/cycles";
// helpers
import { renderDateFormat } from "helpers/date-time.helper";
// types
import type { ICycle } from "types";
// fetch keys
Expand All @@ -20,8 +23,14 @@ export interface CycleModalProps {
initialData?: ICycle;
}

export const CycleModal: React.FC<CycleModalProps> = (props) => {
const { isOpen, handleClose, initialData, projectId, workspaceSlug } = props;
export const CycleModal: React.FC<CycleModalProps> = ({
isOpen,
handleClose,
initialData,
projectId,
workspaceSlug,
}) => {
const { setToastAlert } = useToast();

const createCycle = (payload: Partial<ICycle>) => {
cycleService
Expand All @@ -31,12 +40,11 @@ export const CycleModal: React.FC<CycleModalProps> = (props) => {
handleClose();
})
.catch((err) => {
// TODO: Handle this ERROR.
// Object.keys(err).map((key) => {
// setError(key as keyof typeof defaultValues, {
// message: err[key].join(", "),
// });
// });
setToastAlert({
type: "error",
title: "Error",
message: "Error in creating cycle. Please try again!",
});
});
};

Expand All @@ -48,12 +56,11 @@ export const CycleModal: React.FC<CycleModalProps> = (props) => {
handleClose();
})
.catch((err) => {
// TODO: Handle this ERROR.
// Object.keys(err).map((key) => {
// setError(key as keyof typeof defaultValues, {
// message: err[key].join(", "),
// });
// });
setToastAlert({
type: "error",
title: "Error",
message: "Error in updating cycle. Please try again!",
});
});
};

Expand Down
100 changes: 61 additions & 39 deletions apps/app/components/issues/select/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useForm } from "react-hook-form";
// headless ui
import { Combobox, Transition } from "@headlessui/react";
// icons
import { TagIcon } from "@heroicons/react/24/outline";
import { RectangleGroupIcon, TagIcon } from "@heroicons/react/24/outline";
// services
import issuesServices from "services/issues.service";
// types
Expand Down Expand Up @@ -58,8 +58,6 @@ export const IssueLabelSelect: React.FC<Props> = ({ value, onChange, projectId }
};

const {
register,
handleSubmit,
formState: { isSubmitting },
setFocus,
reset,
Expand All @@ -69,16 +67,10 @@ export const IssueLabelSelect: React.FC<Props> = ({ value, onChange, projectId }
isOpen && setFocus("name");
}, [isOpen, setFocus]);

const options = issueLabels?.map((label) => ({
value: label.id,
display: label.name,
color: label.color,
}));

const filteredOptions =
query === ""
? options
: options?.filter((option) => option.display.toLowerCase().includes(query.toLowerCase()));
? issueLabels
: issueLabels?.filter((l) => l.name.toLowerCase().includes(query.toLowerCase()));

return (
<>
Expand All @@ -98,10 +90,9 @@ export const IssueLabelSelect: React.FC<Props> = ({ value, onChange, projectId }
<TagIcon className="h-3 w-3 text-gray-500" />
<span className={`flex items-center gap-2 ${!value ? "" : "text-gray-900"}`}>
{Array.isArray(value)
? value
.map((v) => options?.find((option) => option.value === v)?.display)
.join(", ") || "Labels"
: options?.find((option) => option.value === value)?.display || "Labels"}
? value.map((v) => issueLabels?.find((l) => l.id === v)?.name).join(", ") ||
"Labels"
: issueLabels?.find((l) => l.id === value)?.name || "Labels"}
</span>
</Combobox.Button>

Expand All @@ -122,31 +113,62 @@ export const IssueLabelSelect: React.FC<Props> = ({ value, onChange, projectId }
displayValue={(assigned: any) => assigned?.name}
/>
<div className="py-1">
{filteredOptions ? (
{issueLabels && filteredOptions ? (
filteredOptions.length > 0 ? (
filteredOptions.map((option) => (
<Combobox.Option
key={option.value}
className={({ active, selected }) =>
`${active ? "bg-indigo-50" : ""} ${
selected ? "bg-indigo-50 font-medium" : ""
} flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900`
}
value={option.value}
>
{issueLabels && (
<>
<span
className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
style={{
backgroundColor: option.color,
}}
/>
{option.display}
</>
)}
</Combobox.Option>
))
filteredOptions.map((label) => {
const children = issueLabels?.filter((l) => l.parent === label.id);

if (children.length === 0) {
if (!label.parent)
return (
<Combobox.Option
key={label.id}
className={({ active, selected }) =>
`${active ? "bg-indigo-50" : ""} ${
selected ? "bg-indigo-50 font-medium" : ""
} flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900`
}
value={label.id}
>
<span
className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
style={{
backgroundColor: label?.color ?? "green",
}}
/>
{label.name}
</Combobox.Option>
);
} else
return (
<div className="bg-gray-50 border-y border-gray-400">
<div className="flex select-none font-medium items-center gap-2 truncate p-2 text-gray-900">
<RectangleGroupIcon className="h-3 w-3" /> {label.name}
</div>
<div>
{children.map((child) => (
<Combobox.Option
key={child.id}
className={({ active, selected }) =>
`${active ? "bg-indigo-50" : ""} ${
selected ? "bg-indigo-50 font-medium" : ""
} flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900`
}
value={child.id}
>
<span
className="h-2 w-2 flex-shrink-0 rounded-full"
style={{
backgroundColor: child?.color ?? "green",
}}
/>
{child.name}
</Combobox.Option>
))}
</div>
</div>
);
})
) : (
<p className="text-xs text-gray-500 px-2">No labels found</p>
)
Expand Down
Loading

1 comment on commit a403c0c

@vercel
Copy link

@vercel vercel bot commented on a403c0c Feb 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

plane-dev – ./apps/app

plane-dev.vercel.app
plane-dev-git-develop-caravel.vercel.app
plane-dev-caravel.vercel.app

Please sign in to comment.