merge conflicts resolved
This commit is contained in:
commit
9003c58d89
360 changed files with 13916 additions and 7344 deletions
|
|
@ -22,7 +22,6 @@ const MyIssuesPage: NextPage = () => {
|
|||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
const { projects } = useProjects();
|
||||
const { user } = useUser();
|
||||
|
||||
const { filters, setFilters } = useMyIssuesFilters(workspaceSlug?.toString());
|
||||
|
|
@ -30,23 +29,37 @@ const MyIssuesPage: NextPage = () => {
|
|||
const tabsList = [
|
||||
{
|
||||
key: "assigned",
|
||||
label: "Assigned to me",
|
||||
label: "Assigned",
|
||||
selected: (filters?.assignees ?? []).length > 0,
|
||||
onClick: () => {
|
||||
setFilters({
|
||||
assignees: [user?.id ?? ""],
|
||||
created_by: null,
|
||||
subscriber: null,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "created",
|
||||
label: "Created by me",
|
||||
label: "Created",
|
||||
selected: (filters?.created_by ?? []).length > 0,
|
||||
onClick: () => {
|
||||
setFilters({
|
||||
created_by: [user?.id ?? ""],
|
||||
assignees: null,
|
||||
created_by: [user?.id ?? ""],
|
||||
subscriber: null,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "subscribed",
|
||||
label: "Subscribed",
|
||||
selected: (filters?.subscriber ?? []).length > 0,
|
||||
onClick: () => {
|
||||
setFilters({
|
||||
assignees: null,
|
||||
created_by: null,
|
||||
subscriber: [user?.id ?? ""],
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
@ -55,7 +68,7 @@ const MyIssuesPage: NextPage = () => {
|
|||
useEffect(() => {
|
||||
if (!filters || !user) return;
|
||||
|
||||
if (!filters.assignees && !filters.created_by) {
|
||||
if (!filters.assignees && !filters.created_by && !filters.subscriber) {
|
||||
setFilters({
|
||||
assignees: [user.id],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
|||
import SettingsNavbar from "layouts/settings-navbar";
|
||||
// components
|
||||
import { ActivityIcon, ActivityMessage } from "components/core";
|
||||
import RemirrorRichTextEditor from "components/rich-text-editor";
|
||||
import Tiptap, { ITiptapRichTextEditor } from "components/tiptap";
|
||||
// icons
|
||||
import { ArrowTopRightOnSquareIcon, ChatBubbleLeftEllipsisIcon } from "@heroicons/react/24/outline";
|
||||
// ui
|
||||
|
|
@ -73,7 +73,7 @@ const ProfileActivity = () => {
|
|||
activityItem.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={activityItem.actor_detail.avatar}
|
||||
alt={activityItem.actor_detail.first_name}
|
||||
alt={activityItem.actor_detail.display_name}
|
||||
height={30}
|
||||
width={30}
|
||||
className="grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white"
|
||||
|
|
@ -82,7 +82,7 @@ const ProfileActivity = () => {
|
|||
<div
|
||||
className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white`}
|
||||
>
|
||||
{activityItem.actor_detail.first_name.charAt(0)}
|
||||
{activityItem.actor_detail.display_name?.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
@ -96,25 +96,25 @@ const ProfileActivity = () => {
|
|||
<div className="min-w-0 flex-1">
|
||||
<div>
|
||||
<div className="text-xs">
|
||||
{activityItem.actor_detail.first_name}
|
||||
{activityItem.actor_detail.is_bot
|
||||
? "Bot"
|
||||
: " " + activityItem.actor_detail.last_name}
|
||||
? activityItem.actor_detail.first_name + " Bot"
|
||||
: activityItem.actor_detail.display_name}
|
||||
</div>
|
||||
<p className="mt-0.5 text-xs text-custom-text-200">
|
||||
Commented {timeAgo(activityItem.created_at)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="issue-comments-section p-0">
|
||||
<RemirrorRichTextEditor
|
||||
<Tiptap
|
||||
value={
|
||||
activityItem.new_value && activityItem.new_value !== ""
|
||||
activityItem?.new_value !== ""
|
||||
? activityItem.new_value
|
||||
: activityItem.old_value
|
||||
}
|
||||
editable={false}
|
||||
noBorder
|
||||
customClassName="text-xs border border-custom-border-200 bg-custom-background-100"
|
||||
noBorder
|
||||
borderOnFocus={false}
|
||||
editable={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -176,7 +176,7 @@ const ProfileActivity = () => {
|
|||
activityItem.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={activityItem.actor_detail.avatar}
|
||||
alt={activityItem.actor_detail.first_name}
|
||||
alt={activityItem.actor_detail.display_name}
|
||||
height={24}
|
||||
width={24}
|
||||
className="rounded-full"
|
||||
|
|
@ -185,7 +185,7 @@ const ProfileActivity = () => {
|
|||
<div
|
||||
className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-700 text-xs text-white`}
|
||||
>
|
||||
{activityItem.actor_detail.first_name.charAt(0)}
|
||||
{activityItem.actor_detail.display_name?.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -206,8 +206,7 @@ const ProfileActivity = () => {
|
|||
href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}
|
||||
>
|
||||
<a className="text-gray font-medium">
|
||||
{activityItem.actor_detail.first_name}{" "}
|
||||
{activityItem.actor_detail.last_name}
|
||||
{activityItem.actor_detail.display_name}
|
||||
</a>
|
||||
</Link>
|
||||
)}{" "}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import useToast from "hooks/use-toast";
|
|||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||
import SettingsNavbar from "layouts/settings-navbar";
|
||||
// components
|
||||
import { ImageUploadModal } from "components/core";
|
||||
import { ImagePickerPopover, ImageUploadModal } from "components/core";
|
||||
// ui
|
||||
import { CustomSelect, DangerButton, Input, SecondaryButton, Spinner } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
|
|
@ -26,6 +26,7 @@ import { USER_ROLES } from "constants/workspace";
|
|||
|
||||
const defaultValues: Partial<IUser> = {
|
||||
avatar: "",
|
||||
cover_image: "",
|
||||
first_name: "",
|
||||
last_name: "",
|
||||
email: "",
|
||||
|
|
@ -68,13 +69,15 @@ const Profile: NextPage = () => {
|
|||
first_name: formData.first_name,
|
||||
last_name: formData.last_name,
|
||||
avatar: formData.avatar,
|
||||
cover_image: formData.cover_image,
|
||||
role: formData.role,
|
||||
display_name: formData.display_name,
|
||||
};
|
||||
|
||||
await userService
|
||||
.updateUser(payload)
|
||||
.then((res) => {
|
||||
mutateUser((prevData) => {
|
||||
mutateUser((prevData: any) => {
|
||||
if (!prevData) return prevData;
|
||||
|
||||
return { ...prevData, ...res };
|
||||
|
|
@ -109,7 +112,7 @@ const Profile: NextPage = () => {
|
|||
title: "Success!",
|
||||
message: "Profile picture removed successfully.",
|
||||
});
|
||||
mutateUser((prevData) => {
|
||||
mutateUser((prevData: any) => {
|
||||
if (!prevData) return prevData;
|
||||
return { ...prevData, avatar: "" };
|
||||
}, false);
|
||||
|
|
@ -176,7 +179,7 @@ const Profile: NextPage = () => {
|
|||
src={watch("avatar")}
|
||||
className="absolute top-0 left-0 h-full w-full object-cover rounded-md"
|
||||
onClick={() => setIsImageUploadModalOpen(true)}
|
||||
alt={myProfile.first_name}
|
||||
alt={myProfile.display_name}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -203,11 +206,42 @@ const Profile: NextPage = () => {
|
|||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 sm:gap-16">
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
<h4 className="text-lg font-semibold text-custom-text-100">Full Name</h4>
|
||||
<h4 className="text-lg font-semibold">Cover Photo</h4>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
This name will be reflected on all the projects you are working on.
|
||||
Select your cover photo from the given library.
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
<div className="h-32 w-full rounded border border-custom-border-200 p-1">
|
||||
<div className="relative h-full w-full rounded">
|
||||
<img
|
||||
src={
|
||||
watch("cover_image") ??
|
||||
"https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"
|
||||
}
|
||||
className="absolute top-0 left-0 h-full w-full object-cover rounded"
|
||||
alt={myProfile?.name ?? "Cover image"}
|
||||
/>
|
||||
<div className="absolute bottom-0 flex w-full justify-end">
|
||||
<ImagePickerPopover
|
||||
label={"Change cover"}
|
||||
onChange={(imageUrl) => {
|
||||
setValue("cover_image", imageUrl);
|
||||
}}
|
||||
value={
|
||||
watch("cover_image") ??
|
||||
"https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 sm:gap-16">
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
<h4 className="text-lg font-semibold text-custom-text-100">Full Name</h4>
|
||||
</div>
|
||||
<div className="col-span-12 flex items-center gap-2 sm:col-span-6">
|
||||
<Input
|
||||
name="first_name"
|
||||
|
|
@ -227,6 +261,43 @@ const Profile: NextPage = () => {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 sm:gap-16">
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
<h4 className="text-lg font-semibold text-custom-text-100">Display Name</h4>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
This could be your first name, or a nickname — however you{"'"}d like people to
|
||||
refer to you in Plane.
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
<Input
|
||||
id="display_name"
|
||||
name="display_name"
|
||||
autoComplete="off"
|
||||
register={register}
|
||||
error={errors.display_name}
|
||||
className="w-full"
|
||||
placeholder="Enter your display name"
|
||||
validations={{
|
||||
required: "Display name is required.",
|
||||
validate: (value) => {
|
||||
if (value.trim().length < 1) return "Display name can't be empty.";
|
||||
|
||||
if (value.split(" ").length > 1)
|
||||
return "Display name can't have two consecutive spaces.";
|
||||
|
||||
if (value.replace(/\s/g, "").length < 1)
|
||||
return "Display name must be at least 1 characters long.";
|
||||
|
||||
if (value.replace(/\s/g, "").length > 20)
|
||||
return "Display name must be less than 20 characters long.";
|
||||
|
||||
return true;
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 sm:gap-16">
|
||||
<div className="col-span-12 sm:col-span-6">
|
||||
<h4 className="text-lg font-semibold text-custom-text-100">Email</h4>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
import { useEffect, useState } from "react";
|
||||
|
||||
// next-themes
|
||||
import { useTheme } from "next-themes";
|
||||
// hooks
|
||||
import useUserAuth from "hooks/use-user-auth";
|
||||
// layouts
|
||||
|
|
@ -14,37 +11,47 @@ import { Spinner } from "components/ui";
|
|||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// types
|
||||
import { ICustomTheme } from "types";
|
||||
// mobx react lite
|
||||
import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// next themes
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
const ProfilePreferences = () => {
|
||||
const [customThemeSelectorOptions, setCustomThemeSelectorOptions] = useState(false);
|
||||
const [preLoadedData, setPreLoadedData] = useState<ICustomTheme | null>(null);
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
const ProfilePreferences = observer(() => {
|
||||
const { user: myProfile } = useUserAuth();
|
||||
|
||||
const store: any = useMobxStore();
|
||||
const { theme } = useTheme();
|
||||
|
||||
console.log("store", store?.theme?.theme);
|
||||
console.log("theme", theme);
|
||||
|
||||
const [customThemeSelectorOptions, setCustomThemeSelectorOptions] = useState(false);
|
||||
|
||||
const [preLoadedData, setPreLoadedData] = useState<ICustomTheme | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (theme === "custom") {
|
||||
if (myProfile?.theme.palette)
|
||||
if (store?.user && store?.theme?.theme === "custom") {
|
||||
const currentTheme = store?.user?.currentUserSettings?.theme;
|
||||
if (currentTheme.palette)
|
||||
setPreLoadedData({
|
||||
background: myProfile.theme.background !== "" ? myProfile.theme.background : "#0d101b",
|
||||
text: myProfile.theme.text !== "" ? myProfile.theme.text : "#c5c5c5",
|
||||
primary: myProfile.theme.primary !== "" ? myProfile.theme.primary : "#3f76ff",
|
||||
background: currentTheme.background !== "" ? currentTheme.background : "#0d101b",
|
||||
text: currentTheme.text !== "" ? currentTheme.text : "#c5c5c5",
|
||||
primary: currentTheme.primary !== "" ? currentTheme.primary : "#3f76ff",
|
||||
sidebarBackground:
|
||||
myProfile.theme.sidebarBackground !== ""
|
||||
? myProfile.theme.sidebarBackground
|
||||
: "#0d101b",
|
||||
sidebarText: myProfile.theme.sidebarText !== "" ? myProfile.theme.sidebarText : "#c5c5c5",
|
||||
currentTheme.sidebarBackground !== "" ? currentTheme.sidebarBackground : "#0d101b",
|
||||
sidebarText: currentTheme.sidebarText !== "" ? currentTheme.sidebarText : "#c5c5c5",
|
||||
darkPalette: false,
|
||||
palette:
|
||||
myProfile.theme.palette !== ",,,,"
|
||||
? myProfile.theme.palette
|
||||
currentTheme.palette !== ",,,,"
|
||||
? currentTheme.palette
|
||||
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
|
||||
theme: "custom",
|
||||
});
|
||||
if (!customThemeSelectorOptions) setCustomThemeSelectorOptions(true);
|
||||
setCustomThemeSelectorOptions((prevData) => true);
|
||||
}
|
||||
}, [myProfile, theme, customThemeSelectorOptions]);
|
||||
}, [store, store?.theme?.theme]);
|
||||
|
||||
return (
|
||||
<WorkspaceAuthorizationLayout
|
||||
|
|
@ -91,6 +98,6 @@ const ProfilePreferences = () => {
|
|||
)}
|
||||
</WorkspaceAuthorizationLayout>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default ProfilePreferences;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue