Merge public-gh/master into paperclip-company-import-export
This commit is contained in:
@@ -285,7 +285,7 @@ export function OrgChart() {
|
||||
</div>
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="w-full h-[calc(100vh-7rem)] overflow-hidden relative bg-muted/20 border border-border rounded-lg"
|
||||
className="w-full h-[calc(100dvh-6rem)] overflow-hidden relative bg-muted/20 border border-border rounded-lg"
|
||||
style={{ cursor: dragging ? "grabbing" : "grab" }}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
|
||||
@@ -274,6 +274,21 @@ export function ProjectDetail() {
|
||||
onSuccess: invalidateProject,
|
||||
});
|
||||
|
||||
const archiveProject = useMutation({
|
||||
mutationFn: (archived: boolean) =>
|
||||
projectsApi.update(
|
||||
projectLookupRef,
|
||||
{ archivedAt: archived ? new Date().toISOString() : null },
|
||||
resolvedCompanyId ?? lookupCompanyId,
|
||||
),
|
||||
onSuccess: (_, archived) => {
|
||||
invalidateProject();
|
||||
if (archived) {
|
||||
navigate("/projects");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const uploadImage = useMutation({
|
||||
mutationFn: async (file: File) => {
|
||||
if (!resolvedCompanyId) throw new Error("No company selected");
|
||||
@@ -476,6 +491,8 @@ export function ProjectDetail() {
|
||||
onUpdate={(data) => updateProject.mutate(data)}
|
||||
onFieldUpdate={updateProjectField}
|
||||
getFieldSaveState={(field) => fieldSaveStates[field] ?? "idle"}
|
||||
onArchive={(archived) => archiveProject.mutate(archived)}
|
||||
archivePending={archiveProject.isPending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { projectsApi } from "../api/projects";
|
||||
import { useCompany } from "../context/CompanyContext";
|
||||
@@ -22,11 +22,15 @@ export function Projects() {
|
||||
setBreadcrumbs([{ label: "Projects" }]);
|
||||
}, [setBreadcrumbs]);
|
||||
|
||||
const { data: projects, isLoading, error } = useQuery({
|
||||
const { data: allProjects, isLoading, error } = useQuery({
|
||||
queryKey: queryKeys.projects.list(selectedCompanyId!),
|
||||
queryFn: () => projectsApi.list(selectedCompanyId!),
|
||||
enabled: !!selectedCompanyId,
|
||||
});
|
||||
const projects = useMemo(
|
||||
() => (allProjects ?? []).filter((p) => !p.archivedAt),
|
||||
[allProjects],
|
||||
);
|
||||
|
||||
if (!selectedCompanyId) {
|
||||
return <EmptyState icon={Hexagon} message="Select a company to view projects." />;
|
||||
@@ -47,7 +51,7 @@ export function Projects() {
|
||||
|
||||
{error && <p className="text-sm text-destructive">{error.message}</p>}
|
||||
|
||||
{projects && projects.length === 0 && (
|
||||
{!isLoading && projects.length === 0 && (
|
||||
<EmptyState
|
||||
icon={Hexagon}
|
||||
message="No projects yet."
|
||||
@@ -56,7 +60,7 @@ export function Projects() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{projects && projects.length > 0 && (
|
||||
{projects.length > 0 && (
|
||||
<div className="border border-border">
|
||||
{projects.map((project) => (
|
||||
<EntityRow
|
||||
|
||||
Reference in New Issue
Block a user