refactor: objects folder structure

This commit is contained in:
Aaryan Khandelwal 2023-09-20 18:33:12 +05:30
parent 4a5ca4d51b
commit cd4d56d071
10 changed files with 118 additions and 58 deletions

View File

@ -24,8 +24,7 @@ export const OptionForm: React.FC<Props> = observer(({ objectId, parentId }) =>
const router = useRouter();
const { workspaceSlug } = router.query;
const { customAttributes: customAttributesStore } = useMobxStore();
const { createAttributeOption, createAttributeOptionLoader } = customAttributesStore;
const { customAttributes } = useMobxStore();
const handleCreateOption = async () => {
if (!workspaceSlug) return;
@ -38,13 +37,15 @@ export const OptionForm: React.FC<Props> = observer(({ objectId, parentId }) =>
type: "option",
};
await createAttributeOption(workspaceSlug.toString(), objectId, {
...payload,
parent: parentId,
}).then(() => {
setOptionName("");
setOptionColor("#000000");
});
await customAttributes
.createAttributeOption(workspaceSlug.toString(), objectId, {
...payload,
parent: parentId,
})
.then(() => {
setOptionName("");
setOptionColor("#000000");
});
};
return (
@ -65,9 +66,9 @@ export const OptionForm: React.FC<Props> = observer(({ objectId, parentId }) =>
onClick={handleCreateOption}
size="sm"
className="!py-1.5 !px-2"
loading={createAttributeOptionLoader}
loading={customAttributes.createAttributeOptionLoader}
>
{createAttributeOptionLoader ? "Adding..." : "Add"}
{customAttributes.createAttributeOptionLoader ? "Adding..." : "Add"}
</PrimaryButton>
</div>
</div>

View File

@ -4,7 +4,7 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { useMobxStore } from "lib/mobx/store-provider";
// ui
import { Tooltip } from "components/ui";
import { CustomMenu, Tooltip } from "components/ui";
// icons
import { MoreHorizontal } from "lucide-react";
// types
@ -19,15 +19,31 @@ export const SelectOption: React.FC<Props> = observer(({ objectId, option }) =>
const router = useRouter();
const { workspaceSlug } = router.query;
const { customAttributes: customAttributesStore } = useMobxStore();
const { updateAttributeOption } = customAttributesStore;
const { customAttributes } = useMobxStore();
const handleSetAsDefault = async () => {
if (!workspaceSlug || !option.parent) return;
await updateAttributeOption(workspaceSlug.toString(), objectId, option.parent, option.id, {
is_default: true,
});
await customAttributes.updateAttributeOption(
workspaceSlug.toString(),
objectId,
option.parent,
option.id,
{
is_default: true,
}
);
};
const handleDeleteOption = async () => {
if (!workspaceSlug || !option.parent) return;
await customAttributes.deleteAttributeOption(
workspaceSlug.toString(),
objectId,
option.parent,
option.id
);
};
return (
@ -59,9 +75,16 @@ export const SelectOption: React.FC<Props> = observer(({ objectId, option }) =>
Set as default
</button>
)}
<button type="button">
<MoreHorizontal className="text-custom-text-400" size={14} />
</button>
<CustomMenu
customButton={
<div className="grid place-items-center">
<MoreHorizontal className="text-custom-text-400" size={14} />
</div>
}
>
<CustomMenu.MenuItem>Edit</CustomMenu.MenuItem>
<CustomMenu.MenuItem onClick={handleDeleteOption}>Delete</CustomMenu.MenuItem>
</CustomMenu>
</div>
</div>
);

View File

@ -36,7 +36,7 @@ export const CustomAttributesDescriptionFields: React.FC<Props> = observer((prop
);
return (
<Disclosure defaultOpen>
<Disclosure as="div" defaultOpen>
{({ open }) => (
<>
<div className="flex items-center justify-between gap-2">

View File

@ -200,7 +200,7 @@ export const CustomAttributesFileUploads: React.FC<Props> = observer((props) =>
<Loader.Item height="35px" />
</Loader>
) : (
<Disclosure defaultOpen>
<Disclosure as="div" defaultOpen>
{({ open }) => (
<>
<Disclosure.Button className="font-medium flex items-center gap-2">
@ -211,7 +211,7 @@ export const CustomAttributesFileUploads: React.FC<Props> = observer((props) =>
/>
Attachment attributes
</Disclosure.Button>
<Disclosure.Panel className="mt-2 grid grid-cols-3 gap-4">
<Disclosure.Panel className="grid grid-cols-3 gap-4 mt-2">
{Object.entries(fileUploadFields).map(([attributeId, attribute]) => (
<div key={attributeId}>
<Tooltip tooltipContent={attribute.display_name} position="top-left">

View File

@ -8,7 +8,7 @@ import { TwitterPicker } from "react-color";
type Props = {
onChange: (hexValue: string) => void;
selectedColor: string;
size: number;
size?: number;
};
export const ColorPicker: React.FC<Props> = ({ onChange, selectedColor, size = 14 }) => (

View File

@ -7,3 +7,4 @@ export * from "./input";
export * from "./object-modal";
export * from "./objects-list";
export * from "./objects-select";
export * from "./single-object";

View File

@ -6,14 +6,13 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { useMobxStore } from "lib/mobx/store-provider";
// components
import { DeleteObjectModal } from "components/custom-attributes";
import { DeleteObjectModal, SingleObject } from "components/custom-attributes";
// ui
import { CustomMenu, Loader } from "components/ui";
// icons
import { TableProperties } from "lucide-react";
import { EmptyState, Loader } from "components/ui";
// assets
import emptyCustomObjects from "public/empty-state/custom-objects.svg";
// types
import { ICustomAttribute } from "types";
import { renderEmoji } from "helpers/emoji.helper";
type Props = {
handleEditObject: (object: ICustomAttribute) => void;
@ -54,36 +53,26 @@ export const ObjectsList: React.FC<Props> = observer(({ handleEditObject, projec
}, 300);
}}
/>
<div className="space-y-4 divide-y divide-custom-border-100">
<div className="divide-y divide-custom-border-100">
{entities ? (
entities.length > 0 ? (
entities.map((entity) => (
<div key={entity.id} className="p-4 flex items-center justify-between gap-4">
<div className="flex gap-4">
<div className="bg-custom-background-80 h-10 w-10 grid place-items-center rounded">
{entity.icon ? (
renderEmoji(entity.icon)
) : (
<TableProperties size={20} strokeWidth={1.5} />
)}
</div>
<div>
<h5 className="text-sm font-medium">{entity.display_name}</h5>
<p className="text-custom-text-300 text-xs">{entity.description}</p>
</div>
</div>
<CustomMenu ellipsis>
<CustomMenu.MenuItem renderAs="button" onClick={() => handleEditObject(entity)}>
Edit
</CustomMenu.MenuItem>
<CustomMenu.MenuItem renderAs="button" onClick={() => handleDeleteObject(entity)}>
Delete
</CustomMenu.MenuItem>
</CustomMenu>
</div>
<SingleObject
key={entity.id}
object={entity}
handleDeleteObject={() => handleDeleteObject(entity)}
handleEditObject={() => handleEditObject(entity)}
/>
))
) : (
<p className="text-sm text-custom-text-200 text-center">No objects present</p>
<div className="bg-custom-background-90 border border-custom-border-100 rounded max-w-3xl mt-10 mx-auto">
<EmptyState
title="No custom objects yet"
description="You can think of Pages as an AI-powered notepad."
image={emptyCustomObjects}
isFullScreen={false}
/>
</div>
)
) : (
<Loader className="space-y-4">

View File

@ -0,0 +1,40 @@
// ui
import { CustomMenu } from "components/ui";
// icons
import { TableProperties } from "lucide-react";
// helpers
import { renderEmoji } from "helpers/emoji.helper";
// types
import { ICustomAttribute } from "types";
type Props = {
object: ICustomAttribute;
handleDeleteObject: () => void;
handleEditObject: () => void;
};
export const SingleObject: React.FC<Props> = (props) => {
const { object, handleDeleteObject, handleEditObject } = props;
return (
<div className="flex items-center justify-between gap-4 py-4">
<div className={`flex gap-4 ${object.description === "" ? "items-center" : "items-start"}`}>
<div className="bg-custom-background-80 h-10 w-10 grid place-items-center rounded">
{object.icon ? renderEmoji(object.icon) : <TableProperties size={20} strokeWidth={1.5} />}
</div>
<div>
<h5 className="text-sm font-medium">{object.display_name}</h5>
<p className="text-custom-text-300 text-xs">{object.description}</p>
</div>
</div>
<CustomMenu ellipsis>
<CustomMenu.MenuItem renderAs="button" onClick={handleEditObject}>
Edit
</CustomMenu.MenuItem>
<CustomMenu.MenuItem renderAs="button" onClick={handleDeleteObject}>
Delete
</CustomMenu.MenuItem>
</CustomMenu>
</div>
);
};

View File

@ -5,7 +5,6 @@ import { useRouter } from "next/router";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
// hooks
import useToast from "hooks/use-toast";
import useProjectDetails from "hooks/use-project-details";
// components
import { SettingsSidebar } from "components/project";
@ -26,8 +25,6 @@ const CustomObjectSettings: NextPage = () => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const { setToastAlert } = useToast();
const { projectDetails } = useProjectDetails();
const handleEditObject = (object: ICustomAttribute) => {
@ -68,7 +65,7 @@ const CustomObjectSettings: NextPage = () => {
</PrimaryButton>
</div>
<div>
<div className="mt-4 border-y border-custom-border-100">
<div className="mt-4">
<ObjectsList
handleEditObject={handleEditObject}
projectId={projectId?.toString() ?? ""}

View File

@ -0,0 +1,9 @@
<svg width="90" height="90" viewBox="0 0 90 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M44.5229 89.0458C69.1123 89.0458 89.0459 69.1122 89.0459 44.5229C89.0459 19.9336 69.1123 0 44.5229 0C19.9336 0 0 19.9336 0 44.5229C0 69.1122 19.9336 89.0458 44.5229 89.0458Z" fill="#F2F2F2"/>
<mask id="mask0_6341_74161" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="23" y="22" width="44" height="44">
<rect x="23" y="22" width="44" height="44" fill="#D9D9D9"/>
</mask>
<g mask="url(#mask0_6341_74161)">
<path d="M35.8593 52.7056H45.026C45.4162 52.7056 45.7429 52.574 46.0061 52.3108C46.2693 52.0476 46.401 51.7209 46.401 51.3307C46.401 50.9405 46.2693 50.6138 46.0061 50.3506C45.7429 50.0874 45.4162 49.9557 45.026 49.9557H35.8593C35.4692 49.9557 35.1425 50.0874 34.8792 50.3506C34.616 50.6138 34.4844 50.9405 34.4844 51.3307C34.4844 51.7209 34.616 52.0476 34.8792 52.3108C35.1425 52.574 35.4692 52.7056 35.8593 52.7056ZM54.1927 35.2891C53.8025 35.2891 53.4758 35.4207 53.2126 35.6839C52.9493 35.9472 52.8177 36.2739 52.8177 36.664V51.3307C52.8177 51.7209 52.9493 52.0476 53.2126 52.3108C53.4758 52.574 53.8025 52.7056 54.1927 52.7056C54.5828 52.7056 54.9095 52.574 55.1728 52.3108C55.436 52.0476 55.5676 51.7209 55.5676 51.3307V36.664C55.5676 36.2739 55.436 35.9472 55.1728 35.6839C54.9095 35.4207 54.5828 35.2891 54.1927 35.2891ZM35.8593 45.3723H45.026C45.4162 45.3723 45.7429 45.2407 46.0061 44.9775C46.2693 44.7142 46.401 44.3875 46.401 43.9974C46.401 43.6072 46.2693 43.2805 46.0061 43.0173C45.7429 42.754 45.4162 42.6224 45.026 42.6224H35.8593C35.4692 42.6224 35.1425 42.754 34.8792 43.0173C34.616 43.2805 34.4844 43.6072 34.4844 43.9974C34.4844 44.3875 34.616 44.7142 34.8792 44.9775C35.1425 45.2407 35.4692 45.3723 35.8593 45.3723ZM35.8593 38.039H45.026C45.4162 38.039 45.7429 37.9074 46.0061 37.6441C46.2693 37.3809 46.401 37.0542 46.401 36.664C46.401 36.2739 46.2693 35.9472 46.0061 35.6839C45.7429 35.4207 45.4162 35.2891 45.026 35.2891H35.8593C35.4692 35.2891 35.1425 35.4207 34.8792 35.6839C34.616 35.9472 34.4844 36.2739 34.4844 36.664C34.4844 37.0542 34.616 37.3809 34.8792 37.6441C35.1425 37.9074 35.4692 38.039 35.8593 38.039ZM30.9235 59.5806C29.9974 59.5806 29.2135 59.2598 28.5719 58.6181C27.9302 57.9765 27.6094 57.1926 27.6094 56.2665V31.7282C27.6094 30.8021 27.9302 30.0182 28.5719 29.3766C29.2135 28.7349 29.9974 28.4141 30.9235 28.4141H59.1285C60.0546 28.4141 60.8385 28.7349 61.4801 29.3766C62.1218 30.0182 62.4426 30.8021 62.4426 31.7282V56.2665C62.4426 57.1926 62.1218 57.9765 61.4801 58.6181C60.8385 59.2598 60.0546 59.5806 59.1285 59.5806H30.9235ZM30.9235 56.8307H59.1285C59.2695 56.8307 59.3988 56.7719 59.5164 56.6544C59.6339 56.5369 59.6927 56.4076 59.6927 56.2665V31.7282C59.6927 31.5871 59.6339 31.4578 59.5164 31.3403C59.3988 31.2228 59.2695 31.164 59.1285 31.164H30.9235C30.7824 31.164 30.6532 31.2228 30.5356 31.3403C30.4181 31.4578 30.3593 31.5871 30.3593 31.7282V56.2665C30.3593 56.4076 30.4181 56.5369 30.5356 56.6544C30.6532 56.7719 30.7824 56.8307 30.9235 56.8307Z" fill="#A3A3A3"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB