Hyprland
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { Link, useLocation, useNavigate } from 'react-router';
|
||||
import { LayoutGrid, Plus, Pencil, Trash2 } from 'lucide-react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { useGlobal } from 'hooks/useGlobal';
|
||||
@@ -14,6 +15,8 @@ import {
|
||||
} from './constants';
|
||||
|
||||
export const WorkspaceListApp = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const client = useClient();
|
||||
const queryClient = useQueryClient();
|
||||
const [workspaces, setWorkspaces] = useUserState<WorkspaceDefinition[]>('workspaces', []);
|
||||
@@ -24,6 +27,8 @@ export const WorkspaceListApp = () => {
|
||||
const [, setDescription] = useGlobal<string>(NEW_WS_DESC_KEY, '');
|
||||
const [, setTemplateIdx] = useGlobal<number>(NEW_WS_TEMPLATE_KEY, 0);
|
||||
|
||||
const isWorkspacesPage = location.pathname === '/workspaces';
|
||||
|
||||
const handleEdit = (ev: React.MouseEvent, ws: WorkspaceDefinition) => {
|
||||
ev.stopPropagation();
|
||||
setSelected(null);
|
||||
@@ -39,7 +44,6 @@ export const WorkspaceListApp = () => {
|
||||
setWorkspaces((prev) => prev.filter((w) => w.id !== ws.id));
|
||||
if (selected === ws.id) setSelected(null);
|
||||
|
||||
// Clean up persisted layout
|
||||
const layoutKey = `ws-layout-${ws.id}`;
|
||||
const currentState = queryClient.getQueryData<Record<string, unknown>>(['USER_STATE']) ?? {};
|
||||
const { [layoutKey]: _, ...rest } = currentState;
|
||||
@@ -47,62 +51,77 @@ export const WorkspaceListApp = () => {
|
||||
client.patch('/user/state', { [layoutKey]: null }).catch(() => {});
|
||||
};
|
||||
|
||||
const handleClick = (ws: WorkspaceDefinition) => {
|
||||
if (isWorkspacesPage) {
|
||||
setSelected(ws.id);
|
||||
setCreating(false);
|
||||
setEditing(null);
|
||||
} else {
|
||||
navigate(`/workspaces/${ws.id}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full overflow-y-auto">
|
||||
<div className="p-3 pb-0">
|
||||
<div className="flex items-center gap-2.5 rounded-lg px-3 py-2 text-sm font-medium bg-duck-teal/15 text-duck-teal">
|
||||
<Link
|
||||
to="/workspaces"
|
||||
className="flex items-center gap-2.5 rounded-lg px-3 py-2 text-sm font-medium bg-duck-teal/15 text-duck-teal"
|
||||
>
|
||||
<LayoutGrid className="h-4 w-4" />
|
||||
Workspaces
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col gap-0.5 px-3 pt-3">
|
||||
{workspaces.map((ws) => (
|
||||
<div
|
||||
key={ws.id}
|
||||
className={`flex items-center gap-2.5 py-2 px-3 rounded-lg text-sm font-medium cursor-pointer group ${
|
||||
selected === ws.id
|
||||
isWorkspacesPage && selected === ws.id
|
||||
? 'bg-duck-teal/10 text-duck-teal'
|
||||
: 'text-duck-dark/60 hover:bg-duck-dark/5'
|
||||
}`}
|
||||
onClick={() => {
|
||||
setSelected(ws.id);
|
||||
setCreating(false);
|
||||
setEditing(null);
|
||||
}}
|
||||
onClick={() => handleClick(ws)}
|
||||
>
|
||||
<LayoutGrid className="h-4 w-4 shrink-0" />
|
||||
<span className="flex-1 text-left truncate">{ws.name}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(ev) => handleEdit(ev, ws)}
|
||||
className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-duck-teal transition-opacity cursor-pointer"
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(ev) => handleDelete(ev, ws)}
|
||||
className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-red-500 transition-opacity cursor-pointer"
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
{isWorkspacesPage && (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(ev) => handleEdit(ev, ws)}
|
||||
className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-duck-teal transition-opacity cursor-pointer"
|
||||
>
|
||||
<Pencil className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(ev) => handleDelete(ev, ws)}
|
||||
className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-red-500 transition-opacity cursor-pointer"
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{workspaces.length === 0 && (
|
||||
<p className="text-xs text-duck-dark/40 px-3 py-4 text-center">No workspaces yet</p>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSelected(null);
|
||||
setEditing(null);
|
||||
setCreating(true);
|
||||
}}
|
||||
className="flex items-center gap-2.5 py-2 px-3 rounded-lg text-sm font-medium text-duck-dark/40 hover:bg-duck-dark/5 hover:text-duck-dark transition-all cursor-pointer"
|
||||
>
|
||||
<Plus className="h-4 w-4 shrink-0" />
|
||||
<span className="flex-1 text-left">New workspace</span>
|
||||
</button>
|
||||
{isWorkspacesPage && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSelected(null);
|
||||
setEditing(null);
|
||||
setCreating(true);
|
||||
}}
|
||||
className="flex items-center gap-2.5 py-2 px-3 rounded-lg text-sm font-medium text-duck-dark/40 hover:bg-duck-dark/5 hover:text-duck-dark transition-all cursor-pointer"
|
||||
>
|
||||
<Plus className="h-4 w-4 shrink-0" />
|
||||
<span className="flex-1 text-left">New workspace</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -6,9 +6,10 @@ import { appRegistry } from './app-registry';
|
||||
|
||||
export const WorkspaceScreen = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [workspaces] = useUserState<WorkspaceDefinition[]>('workspaces', []);
|
||||
const [workspaces, , isLoaded] = useUserState<WorkspaceDefinition[]>('workspaces', []);
|
||||
const workspace = workspaces.find((ws) => ws.id === id);
|
||||
|
||||
if (!isLoaded) return null;
|
||||
if (!workspace) return <Navigate to="/workspaces" replace />;
|
||||
|
||||
return <WorkspaceScreenInner workspace={workspace} />;
|
||||
|
||||
Reference in New Issue
Block a user