Spaces:
Running
Running
Gowrisankar Cursor commited on
Commit ·
0eed800
1
Parent(s): e35edc8
Fix Manage table column spread using fixed layout + colgroup
Browse filesThe first column had width:100% which pushed Active People/Projects
to the far right. Use table-layout:fixed with explicit col widths
(42% name, 26% per stat, 56px actions) so columns distribute like
Runn.io across the full table width.
Co-authored-by: Cursor <cursoragent@cursor.com>
frontend/src/pages/manage/HubSection.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
| 12 |
useTeams,
|
| 13 |
useUsers,
|
| 14 |
} from "../../hooks/usePortalData";
|
| 15 |
-
import { ManagePageHeader, ManageToolbar } from "./_shared";
|
| 16 |
|
| 17 |
interface HubEntry {
|
| 18 |
key: string;
|
|
@@ -61,6 +61,7 @@ export function HubSection() {
|
|
| 61 |
<ManageToolbar onSearchChange={setSearch} search={search} />
|
| 62 |
|
| 63 |
<table className="data-table runn-table">
|
|
|
|
| 64 |
<thead>
|
| 65 |
<tr>
|
| 66 |
<th>Name</th>
|
|
|
|
| 12 |
useTeams,
|
| 13 |
useUsers,
|
| 14 |
} from "../../hooks/usePortalData";
|
| 15 |
+
import { ManagePageHeader, ManageToolbar, RunnHubColgroup } from "./_shared";
|
| 16 |
|
| 17 |
interface HubEntry {
|
| 18 |
key: string;
|
|
|
|
| 61 |
<ManageToolbar onSearchChange={setSearch} search={search} />
|
| 62 |
|
| 63 |
<table className="data-table runn-table">
|
| 64 |
+
<RunnHubColgroup />
|
| 65 |
<thead>
|
| 66 |
<tr>
|
| 67 |
<th>Name</th>
|
frontend/src/pages/manage/RolesSection.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { Modal } from "../../components/ui/Modal";
|
|
| 9 |
import { toastFromError, useToast } from "../../components/ui/Toast";
|
| 10 |
import { useRoles } from "../../hooks/usePortalData";
|
| 11 |
import type { Role } from "../../types";
|
| 12 |
-
import { ManagePageHeader, ManageToolbar, RowMenu } from "./_shared";
|
| 13 |
|
| 14 |
export function RolesSection() {
|
| 15 |
const queryClient = useQueryClient();
|
|
@@ -79,6 +79,7 @@ export function RolesSection() {
|
|
| 79 |
<EmptyState title="No roles yet" description="Create a role to start assigning team members." />
|
| 80 |
) : (
|
| 81 |
<table className="data-table runn-table">
|
|
|
|
| 82 |
<thead>
|
| 83 |
<tr>
|
| 84 |
<th>Name</th>
|
|
|
|
| 9 |
import { toastFromError, useToast } from "../../components/ui/Toast";
|
| 10 |
import { useRoles } from "../../hooks/usePortalData";
|
| 11 |
import type { Role } from "../../types";
|
| 12 |
+
import { ManagePageHeader, ManageToolbar, RunnEntityColgroup, RowMenu } from "./_shared";
|
| 13 |
|
| 14 |
export function RolesSection() {
|
| 15 |
const queryClient = useQueryClient();
|
|
|
|
| 79 |
<EmptyState title="No roles yet" description="Create a role to start assigning team members." />
|
| 80 |
) : (
|
| 81 |
<table className="data-table runn-table">
|
| 82 |
+
<RunnEntityColgroup />
|
| 83 |
<thead>
|
| 84 |
<tr>
|
| 85 |
<th>Name</th>
|
frontend/src/pages/manage/TagsSection.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { Modal } from "../../components/ui/Modal";
|
|
| 9 |
import { toastFromError, useToast } from "../../components/ui/Toast";
|
| 10 |
import { useTags } from "../../hooks/usePortalData";
|
| 11 |
import type { Tag } from "../../types";
|
| 12 |
-
import { ManagePageHeader, ManageToolbar, RowMenu } from "./_shared";
|
| 13 |
|
| 14 |
const TAG_PALETTE = ["#7c3aed", "#0ea5e9", "#16a34a", "#f97316", "#dc2626", "#facc15", "#0f766e", "#a855f7"];
|
| 15 |
|
|
@@ -82,6 +82,7 @@ export function TagsSection() {
|
|
| 82 |
<EmptyState title="No tags yet" description="Create your first tag and apply it to people or projects." />
|
| 83 |
) : (
|
| 84 |
<table className="data-table runn-table">
|
|
|
|
| 85 |
<thead>
|
| 86 |
<tr>
|
| 87 |
<th>Name</th>
|
|
|
|
| 9 |
import { toastFromError, useToast } from "../../components/ui/Toast";
|
| 10 |
import { useTags } from "../../hooks/usePortalData";
|
| 11 |
import type { Tag } from "../../types";
|
| 12 |
+
import { ManagePageHeader, ManageToolbar, RunnEntityColgroup, RowMenu } from "./_shared";
|
| 13 |
|
| 14 |
const TAG_PALETTE = ["#7c3aed", "#0ea5e9", "#16a34a", "#f97316", "#dc2626", "#facc15", "#0f766e", "#a855f7"];
|
| 15 |
|
|
|
|
| 82 |
<EmptyState title="No tags yet" description="Create your first tag and apply it to people or projects." />
|
| 83 |
) : (
|
| 84 |
<table className="data-table runn-table">
|
| 85 |
+
<RunnEntityColgroup />
|
| 86 |
<thead>
|
| 87 |
<tr>
|
| 88 |
<th>Name</th>
|
frontend/src/pages/manage/TeamsSection.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { Modal } from "../../components/ui/Modal";
|
|
| 9 |
import { toastFromError, useToast } from "../../components/ui/Toast";
|
| 10 |
import { useTeams } from "../../hooks/usePortalData";
|
| 11 |
import type { Team } from "../../types";
|
| 12 |
-
import { ManagePageHeader, ManageToolbar, RowMenu } from "./_shared";
|
| 13 |
|
| 14 |
export function TeamsSection() {
|
| 15 |
const queryClient = useQueryClient();
|
|
@@ -79,6 +79,7 @@ export function TeamsSection() {
|
|
| 79 |
<EmptyState title="No teams yet" description="Create a team to group people by department or function." />
|
| 80 |
) : (
|
| 81 |
<table className="data-table runn-table">
|
|
|
|
| 82 |
<thead>
|
| 83 |
<tr>
|
| 84 |
<th>Name</th>
|
|
|
|
| 9 |
import { toastFromError, useToast } from "../../components/ui/Toast";
|
| 10 |
import { useTeams } from "../../hooks/usePortalData";
|
| 11 |
import type { Team } from "../../types";
|
| 12 |
+
import { ManagePageHeader, ManageToolbar, RunnEntityColgroup, RowMenu } from "./_shared";
|
| 13 |
|
| 14 |
export function TeamsSection() {
|
| 15 |
const queryClient = useQueryClient();
|
|
|
|
| 79 |
<EmptyState title="No teams yet" description="Create a team to group people by department or function." />
|
| 80 |
) : (
|
| 81 |
<table className="data-table runn-table">
|
| 82 |
+
<RunnEntityColgroup />
|
| 83 |
<thead>
|
| 84 |
<tr>
|
| 85 |
<th>Name</th>
|
frontend/src/pages/manage/_shared.tsx
CHANGED
|
@@ -9,6 +9,29 @@ export interface RowMenuItem {
|
|
| 9 |
danger?: boolean;
|
| 10 |
}
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
export function RowMenu({ items }: { items: RowMenuItem[] }) {
|
| 13 |
const [open, setOpen] = useState(false);
|
| 14 |
const [position, setPosition] = useState<{ top: number; left: number } | null>(null);
|
|
|
|
| 9 |
danger?: boolean;
|
| 10 |
}
|
| 11 |
|
| 12 |
+
/** Name + two stat columns + actions — matches Runn Teams/Roles/Tags tables */
|
| 13 |
+
export function RunnEntityColgroup() {
|
| 14 |
+
return (
|
| 15 |
+
<colgroup>
|
| 16 |
+
<col className="runn-col-name" />
|
| 17 |
+
<col className="runn-col-stat" />
|
| 18 |
+
<col className="runn-col-stat" />
|
| 19 |
+
<col className="runn-col-actions" />
|
| 20 |
+
</colgroup>
|
| 21 |
+
);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
/** Name + count + actions — Manage hub table */
|
| 25 |
+
export function RunnHubColgroup() {
|
| 26 |
+
return (
|
| 27 |
+
<colgroup>
|
| 28 |
+
<col className="runn-col-name" />
|
| 29 |
+
<col className="runn-col-stat" />
|
| 30 |
+
<col className="runn-col-actions" />
|
| 31 |
+
</colgroup>
|
| 32 |
+
);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
export function RowMenu({ items }: { items: RowMenuItem[] }) {
|
| 36 |
const [open, setOpen] = useState(false);
|
| 37 |
const [position, setPosition] = useState<{ top: number; left: number } | null>(null);
|
frontend/src/styles.css
CHANGED
|
@@ -1786,13 +1786,27 @@ th {
|
|
| 1786 |
|
| 1787 |
.runn-table {
|
| 1788 |
border-radius: 0;
|
| 1789 |
-
table-layout:
|
| 1790 |
width: 100%;
|
| 1791 |
}
|
| 1792 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1793 |
.runn-table th,
|
| 1794 |
.runn-table td {
|
|
|
|
| 1795 |
padding: 14px 18px;
|
|
|
|
| 1796 |
vertical-align: middle;
|
| 1797 |
}
|
| 1798 |
|
|
@@ -1805,19 +1819,10 @@ th {
|
|
| 1805 |
background: rgba(124, 58, 237, 0.04);
|
| 1806 |
}
|
| 1807 |
|
| 1808 |
-
/* First column (Name) is the biggest but doesn't swallow every pixel */
|
| 1809 |
-
.runn-table th:first-child,
|
| 1810 |
-
.runn-table td:first-child {
|
| 1811 |
-
width: 100%;
|
| 1812 |
-
}
|
| 1813 |
-
|
| 1814 |
-
/* Count columns: wide and left-aligned so the value sits directly under the header text */
|
| 1815 |
.runn-table th.num,
|
| 1816 |
.runn-table td.num {
|
| 1817 |
-
min-width: 240px;
|
| 1818 |
text-align: left;
|
| 1819 |
white-space: nowrap;
|
| 1820 |
-
width: 240px;
|
| 1821 |
}
|
| 1822 |
|
| 1823 |
.runn-table th.num {
|
|
|
|
| 1786 |
|
| 1787 |
.runn-table {
|
| 1788 |
border-radius: 0;
|
| 1789 |
+
table-layout: fixed;
|
| 1790 |
width: 100%;
|
| 1791 |
}
|
| 1792 |
|
| 1793 |
+
.runn-table col.runn-col-name {
|
| 1794 |
+
width: 42%;
|
| 1795 |
+
}
|
| 1796 |
+
|
| 1797 |
+
.runn-table col.runn-col-stat {
|
| 1798 |
+
width: 26%;
|
| 1799 |
+
}
|
| 1800 |
+
|
| 1801 |
+
.runn-table col.runn-col-actions {
|
| 1802 |
+
width: 56px;
|
| 1803 |
+
}
|
| 1804 |
+
|
| 1805 |
.runn-table th,
|
| 1806 |
.runn-table td {
|
| 1807 |
+
overflow: hidden;
|
| 1808 |
padding: 14px 18px;
|
| 1809 |
+
text-overflow: ellipsis;
|
| 1810 |
vertical-align: middle;
|
| 1811 |
}
|
| 1812 |
|
|
|
|
| 1819 |
background: rgba(124, 58, 237, 0.04);
|
| 1820 |
}
|
| 1821 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1822 |
.runn-table th.num,
|
| 1823 |
.runn-table td.num {
|
|
|
|
| 1824 |
text-align: left;
|
| 1825 |
white-space: nowrap;
|
|
|
|
| 1826 |
}
|
| 1827 |
|
| 1828 |
.runn-table th.num {
|