mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-18 03:30:39 +09:00
Merge public-gh/master into paperclip-company-import-export
This commit is contained in:
commit
2a7c44d314
33 changed files with 987 additions and 81 deletions
|
|
@ -10,6 +10,7 @@ import { heartbeatsApi } from "../api/heartbeats";
|
|||
import { assetsApi } from "../api/assets";
|
||||
import { usePanel } from "../context/PanelContext";
|
||||
import { useCompany } from "../context/CompanyContext";
|
||||
import { useToast } from "../context/ToastContext";
|
||||
import { useBreadcrumbs } from "../context/BreadcrumbContext";
|
||||
import { queryKeys } from "../lib/queryKeys";
|
||||
import { ProjectProperties, type ProjectConfigFieldKey, type ProjectFieldSaveState } from "../components/ProjectProperties";
|
||||
|
|
@ -210,6 +211,7 @@ export function ProjectDetail() {
|
|||
const { companies, selectedCompanyId, setSelectedCompanyId } = useCompany();
|
||||
const { closePanel } = usePanel();
|
||||
const { setBreadcrumbs } = useBreadcrumbs();
|
||||
const { pushToast } = useToast();
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
|
@ -284,10 +286,14 @@ export function ProjectDetail() {
|
|||
{ archivedAt: archived ? new Date().toISOString() : null },
|
||||
resolvedCompanyId ?? lookupCompanyId,
|
||||
),
|
||||
onSuccess: (_, archived) => {
|
||||
onSuccess: (updatedProject, archived) => {
|
||||
invalidateProject();
|
||||
const name = updatedProject?.name ?? project?.name ?? "Project";
|
||||
if (archived) {
|
||||
navigate("/projects");
|
||||
pushToast({ title: `"${name}" has been archived`, tone: "success" });
|
||||
navigate("/dashboard");
|
||||
} else {
|
||||
pushToast({ title: `"${name}" has been unarchived`, tone: "success" });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
@ -443,8 +449,24 @@ export function ProjectDetail() {
|
|||
return <Navigate to={`/projects/${canonicalProjectRef}/issues`} replace />;
|
||||
}
|
||||
|
||||
// Redirect bare /projects/:id to /projects/:id/issues
|
||||
// Redirect bare /projects/:id to cached tab or default /issues
|
||||
if (routeProjectRef && activeTab === null) {
|
||||
let cachedTab: string | null = null;
|
||||
if (project?.id) {
|
||||
try { cachedTab = localStorage.getItem(`paperclip:project-tab:${project.id}`); } catch {}
|
||||
}
|
||||
if (cachedTab === "overview") {
|
||||
return <Navigate to={`/projects/${canonicalProjectRef}/overview`} replace />;
|
||||
}
|
||||
if (cachedTab === "configuration") {
|
||||
return <Navigate to={`/projects/${canonicalProjectRef}/configuration`} replace />;
|
||||
}
|
||||
if (cachedTab === "budget") {
|
||||
return <Navigate to={`/projects/${canonicalProjectRef}/budget`} replace />;
|
||||
}
|
||||
if (isProjectPluginTab(cachedTab)) {
|
||||
return <Navigate to={`/projects/${canonicalProjectRef}?tab=${encodeURIComponent(cachedTab)}`} replace />;
|
||||
}
|
||||
return <Navigate to={`/projects/${canonicalProjectRef}/issues`} replace />;
|
||||
}
|
||||
|
||||
|
|
@ -453,6 +475,10 @@ export function ProjectDetail() {
|
|||
if (!project) return null;
|
||||
|
||||
const handleTabChange = (tab: ProjectTab) => {
|
||||
// Cache the active tab per project
|
||||
if (project?.id) {
|
||||
try { localStorage.setItem(`paperclip:project-tab:${project.id}`, tab); } catch {}
|
||||
}
|
||||
if (isProjectPluginTab(tab)) {
|
||||
navigate(`/projects/${canonicalProjectRef}?tab=${encodeURIComponent(tab)}`);
|
||||
return;
|
||||
|
|
@ -527,8 +553,8 @@ export function ProjectDetail() {
|
|||
<Tabs value={activeTab ?? "list"} onValueChange={(value) => handleTabChange(value as ProjectTab)}>
|
||||
<PageTabBar
|
||||
items={[
|
||||
{ value: "list", label: "Issues" },
|
||||
{ value: "overview", label: "Overview" },
|
||||
{ value: "list", label: "List" },
|
||||
{ value: "configuration", label: "Configuration" },
|
||||
{ value: "budget", label: "Budget" },
|
||||
...pluginTabItems.map((item) => ({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue