Improve record settings

This commit is contained in:
Hakan Shehu
2024-11-19 17:47:07 +01:00
parent e5df4c79c9
commit 0efba0caac
5 changed files with 104 additions and 8 deletions

View File

@@ -2,13 +2,17 @@ import { RecordName } from '@/renderer/components/records/record-name';
import { useDatabase } from '@/renderer/contexts/database';
import { RecordField } from '@/renderer/components/records/record-field';
import { RecordFieldValue } from '@/renderer/components/records/record-field-value';
import { RecordAvatar } from '@/renderer/components/records/record-avatar';
export const RecordAttributes = () => {
const database = useDatabase();
return (
<div className="flex flex-col gap-2">
<RecordName />
<div className="flex flex-row gap-2">
<RecordAvatar />
<RecordName />
</div>
<div className="flex flex-row gap-2">
<div className="flex w-60 flex-col gap-2">
{database.fields.map((field) => (

View File

@@ -0,0 +1,54 @@
import { useRecord } from '@/renderer/contexts/record';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { AvatarPopover } from '@/renderer/components/avatars/avatar-popover';
import { Button } from '@/renderer/components/ui/button';
import { Avatar } from '@/renderer/components/avatars/avatar';
export const RecordAvatar = () => {
const workspace = useWorkspace();
const record = useRecord();
const { mutate, isPending } = useMutation();
if (!record.canEdit) {
return (
<Button type="button" variant="outline" size="icon">
<Avatar
id={record.id}
name={record.name}
avatar={record.avatar}
className="h-6 w-6"
/>
</Button>
);
}
return (
<AvatarPopover
onPick={(avatar) => {
if (isPending) return;
if (avatar === record.avatar) return;
mutate({
input: {
type: 'node_attribute_set',
nodeId: record.id,
path: 'avatar',
value: avatar,
userId: workspace.userId,
},
});
}}
>
<Button type="button" variant="outline" size="icon">
<Avatar
id={record.id}
name={record.name}
avatar={record.avatar}
className="h-6 w-6"
/>
</Button>
</AvatarPopover>
);
};

View File

@@ -30,7 +30,7 @@ export const RecordHeader = ({ nodes, record, role }: RecordHeaderProps) => {
nodes={nodes}
role={role}
/>
<RecordSettings nodeId={record.id} />
<RecordSettings record={record} role={role} />
</div>
</div>
</Header>

View File

@@ -11,6 +11,7 @@ export const RecordName = () => {
return (
<SmartTextInput
value={record.name}
readOnly={!record.canEdit}
onChange={(value) => {
if (isPending) {
return;

View File

@@ -3,24 +3,36 @@ import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/renderer/components/ui/dropdown-menu';
import { Copy, Settings, Trash2 } from 'lucide-react';
import { hasEditorAccess, NodeRole, RecordNode } from '@colanode/core';
import { NodeCollaboratorAudit } from '@/renderer/components/collaborators/node-collaborator-audit';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { RecordDeleteDialog } from '@/renderer/components/records/record-delete-dialog';
interface RecordSettingsProps {
nodeId: string;
record: RecordNode;
role: NodeRole;
}
export const RecordSettings = ({ nodeId }: RecordSettingsProps) => {
const [showDeleteModal, setShowDeleteModal] = React.useState(false);
export const RecordSettings = ({ record, role }: RecordSettingsProps) => {
const workspace = useWorkspace();
const [showDeleteDialog, setShowDeleteModal] = React.useState(false);
const canDelete =
record.createdBy === workspace.userId || hasEditorAccess(role);
return (
<React.Fragment>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Settings className="size-5 cursor-pointer text-muted-foreground hover:text-foreground" />
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" className="mr-2 w-56">
<DropdownMenuContent side="bottom" className="mr-2 w-80">
<DropdownMenuLabel>{record.attributes.name}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem className="flex items-center gap-2" disabled>
<Copy className="size-4" />
Duplicate
@@ -28,17 +40,42 @@ export const RecordSettings = ({ nodeId }: RecordSettingsProps) => {
<DropdownMenuItem
className="flex items-center gap-2"
onClick={() => {
if (!canDelete) {
return;
}
setShowDeleteModal(true);
}}
disabled={!canDelete}
>
<Trash2 className="size-4" />
Delete
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>Created by</DropdownMenuLabel>
<DropdownMenuItem>
<NodeCollaboratorAudit
collaboratorId={record.createdBy}
date={record.createdAt}
/>
</DropdownMenuItem>
{record.updatedBy && (
<React.Fragment>
<DropdownMenuSeparator />
<DropdownMenuLabel>Last updated by</DropdownMenuLabel>
<DropdownMenuItem>
<NodeCollaboratorAudit
collaboratorId={record.updatedBy}
date={record.updatedAt}
/>
</DropdownMenuItem>
</React.Fragment>
)}
</DropdownMenuContent>
</DropdownMenu>
<RecordDeleteDialog
nodeId={nodeId}
open={showDeleteModal}
nodeId={record.id}
open={showDeleteDialog}
onOpenChange={setShowDeleteModal}
/>
</React.Fragment>