Implement avatar for database views

This commit is contained in:
Hakan Shehu
2024-10-25 16:33:16 +02:00
parent 075c6405ba
commit f7ec9037cc
6 changed files with 58 additions and 17 deletions

View File

@@ -119,6 +119,7 @@ export class DatabaseViewListQueryHandler
private buildTableViewNode = (node: LocalNode): TableViewNode => {
const name = node.attributes.name;
const avatar = node.attributes.avatar;
const hiddenFields = node.attributes.hiddenFields;
const fieldIndexes = node.attributes.fieldIndexes;
const fieldWidths = node.attributes.fieldWidths;
@@ -130,6 +131,7 @@ export class DatabaseViewListQueryHandler
return {
id: node.id,
name: name ?? 'Unnamed',
avatar,
type: 'table_view',
hiddenFields,
fieldIndexes,
@@ -143,6 +145,7 @@ export class DatabaseViewListQueryHandler
private buildBoardViewNode = (node: LocalNode): BoardViewNode => {
const name = node.attributes.name;
const avatar = node.attributes.avatar;
const groupBy = node.attributes.groupBy;
const viewFilters = node.attributes.filters;
const viewSorts = node.attributes.sorts;
@@ -150,6 +153,7 @@ export class DatabaseViewListQueryHandler
return {
id: node.id,
name: name ?? 'Unnamed',
avatar,
type: 'board_view',
filters: viewFilters ?? [],
sorts: viewSorts ?? [],
@@ -159,6 +163,7 @@ export class DatabaseViewListQueryHandler
private buildCalendarViewNode = (node: LocalNode): CalendarViewNode => {
const name = node.attributes.name;
const avatar = node.attributes.avatar;
const groupBy = node.attributes.groupBy;
const viewFilters = node.attributes.filters;
@@ -167,6 +172,7 @@ export class DatabaseViewListQueryHandler
return {
id: node.id,
name: name ?? 'Unnamed',
avatar,
type: 'calendar_view',
filters: viewFilters ?? [],
sorts: viewSorts ?? [],

View File

@@ -20,6 +20,9 @@ import { useMutation } from '@/renderer/hooks/use-mutation';
import { ViewDeleteDialog } from '@/renderer/components/databases/view-delete-dialog';
import { SmartTextInput } from '@/renderer/components/ui/smart-text-input';
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 TableViewSettingsPopover = () => {
const workspace = useWorkspace();
@@ -44,23 +47,50 @@ export const TableViewSettingsPopover = () => {
</div>
</PopoverTrigger>
<PopoverContent className="mr-4 flex w-[600px] flex-col gap-1.5 p-2">
<SmartTextInput
value={tableView.name}
onChange={(newName) => {
if (isPending) return;
if (newName === tableView.name) return;
<div className="flex flex-row items-center gap-2">
<AvatarPopover
onPick={(avatar) => {
if (isPending) return;
if (avatar === tableView.avatar) return;
mutate({
input: {
type: 'node_attribute_set',
nodeId: tableView.id,
attribute: 'name',
value: newName,
userId: workspace.userId,
},
});
}}
/>
mutate({
input: {
type: 'node_attribute_set',
nodeId: tableView.id,
attribute: 'avatar',
value: avatar,
userId: workspace.userId,
},
});
}}
>
<Button variant="outline" size="icon">
<Avatar
id={tableView.id}
name={tableView.name}
avatar={tableView.avatar}
className="h-6 w-6"
/>
</Button>
</AvatarPopover>
<SmartTextInput
value={tableView.name}
onChange={(newName) => {
if (isPending) return;
if (newName === tableView.name) return;
mutate({
input: {
type: 'node_attribute_set',
nodeId: tableView.id,
attribute: 'name',
value: newName,
userId: workspace.userId,
},
});
}}
/>
</div>
<Separator />
<div className="flex flex-col gap-2 text-sm">
<p className="my-1 font-semibold">Fields</p>

View File

@@ -62,6 +62,7 @@ export const TableView = ({ node }: TableViewProps) => {
value={{
id: node.id,
name: node.name,
avatar: node.avatar,
fields,
hideField: (id: string) => {
if (hiddenFields.includes(id)) {

View File

@@ -20,7 +20,7 @@ export const ViewTab = ({ view, isActive, onClick }: ViewTabProps) => {
onClick={() => onClick()}
onKeyDown={() => onClick()}
>
<Avatar id={view.id} name={view.name} size="small" />
<Avatar id={view.id} name={view.name} avatar={view.avatar} size="small" />
{view.name}
</div>
);

View File

@@ -4,6 +4,7 @@ import { createContext, useContext } from 'react';
interface TableViewContext {
id: string;
name: string;
avatar: string | null;
fields: FieldNode[];
hideField: (id: string) => void;
showField: (id: string) => void;

View File

@@ -11,6 +11,7 @@ export type ViewNode = TableViewNode | BoardViewNode | CalendarViewNode;
export type TableViewNode = {
id: string;
name: string;
avatar: string | null;
type: 'table_view';
hiddenFields: string[];
fieldIndexes: Record<string, string>;
@@ -24,6 +25,7 @@ export type TableViewNode = {
export type BoardViewNode = {
id: string;
name: string;
avatar: string | null;
type: 'board_view';
filters: ViewFilter[];
sorts: ViewSort[];
@@ -33,6 +35,7 @@ export type BoardViewNode = {
export type CalendarViewNode = {
id: string;
name: string;
avatar: string | null;
type: 'calendar_view';
filters: ViewFilter[];
sorts: ViewSort[];