Skip to content

Commit 8e83735

Browse files
committed
Add workspace project team views
1 parent 61f4e48 commit 8e83735

25 files changed

Lines changed: 1042 additions & 4 deletions

apps/web/src/components/EntryShell.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ import {
132132
type PluginShareProjectOutcome,
133133
} from '../state/projects';
134134
import { TasksView } from './TasksView';
135+
import { TeamProjectsView } from './TeamProjectsView';
135136
import {
136137
API_KEY_PLACEHOLDERS,
137138
API_PROTOCOL_TABS,
@@ -1082,13 +1083,24 @@ export function EntryShell({
10821083
) : null}
10831084
{/* Team destinations — the entry shell owns the nav frame only; each
10841085
view is provided by another lane (B = members/board, D = team
1085-
project spaces / workspace settings), rendered as a placeholder
1086-
until those land. */}
1086+
project spaces / workspace settings). */}
10871087
{view === 'drafts' ? (
1088-
<TeamSlotPlaceholder icon="file" title={t('entry.navDrafts')} />
1088+
workspaceContext ? (
1089+
<TeamProjectsView
1090+
mode="drafts"
1091+
context={workspaceContext}
1092+
onOpenProject={onOpenProject}
1093+
/>
1094+
) : null
10891095
) : null}
10901096
{view === 'all-projects' ? (
1091-
<TeamSlotPlaceholder icon="folder" title={t('entry.navAllProjects')} />
1097+
workspaceContext ? (
1098+
<TeamProjectsView
1099+
mode="all-projects"
1100+
context={workspaceContext}
1101+
onOpenProject={onOpenProject}
1102+
/>
1103+
) : null
10921104
) : null}
10931105
{view === 'members' ? (
10941106
<TeamSlotPlaceholder icon="users" title={t('entry.navMembers')} />
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
.header {
2+
display: flex;
3+
align-items: flex-start;
4+
justify-content: space-between;
5+
gap: 16px;
6+
margin-bottom: 18px;
7+
}
8+
9+
.titleBlock {
10+
display: flex;
11+
flex-direction: column;
12+
gap: 6px;
13+
min-width: 0;
14+
}
15+
16+
.meta {
17+
display: flex;
18+
flex-wrap: wrap;
19+
align-items: center;
20+
gap: 6px;
21+
color: var(--text-muted);
22+
font-size: 13px;
23+
}
24+
25+
.error {
26+
margin-bottom: 14px;
27+
padding: 10px 12px;
28+
border: 1px solid var(--red-border);
29+
border-radius: var(--radius-sm);
30+
color: var(--red);
31+
background: var(--red-bg);
32+
font-size: 13px;
33+
}
34+
35+
.empty {
36+
display: flex;
37+
align-items: center;
38+
justify-content: center;
39+
min-height: 220px;
40+
border: 1px dashed var(--border);
41+
border-radius: var(--radius-sm);
42+
color: var(--text-muted);
43+
background: var(--bg-panel);
44+
font-size: 14px;
45+
}
46+
47+
.grid {
48+
display: grid;
49+
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
50+
gap: 12px;
51+
}
52+
53+
.card {
54+
display: grid;
55+
grid-template-columns: 36px minmax(0, 1fr);
56+
gap: 12px;
57+
min-height: 150px;
58+
padding: 14px;
59+
border: 1px solid var(--border);
60+
border-radius: var(--radius-sm);
61+
background: var(--bg-panel);
62+
box-shadow: var(--shadow-xs);
63+
}
64+
65+
.iconWrap {
66+
display: inline-flex;
67+
align-items: center;
68+
justify-content: center;
69+
width: 36px;
70+
height: 36px;
71+
border-radius: var(--radius-sm);
72+
color: var(--accent);
73+
background: var(--accent-tint);
74+
}
75+
76+
.cardBody {
77+
min-width: 0;
78+
}
79+
80+
.tagRow {
81+
display: flex;
82+
flex-wrap: wrap;
83+
align-items: center;
84+
gap: 5px;
85+
min-width: 0;
86+
margin-bottom: 8px;
87+
}
88+
89+
.tag {
90+
display: inline-flex;
91+
align-items: center;
92+
max-width: 100%;
93+
padding: 1px 7px;
94+
border: 1px solid var(--border);
95+
border-radius: var(--radius-pill);
96+
color: var(--text-muted);
97+
background: var(--bg-subtle);
98+
font-size: 10.5px;
99+
font-weight: 500;
100+
line-height: 1.5;
101+
overflow: hidden;
102+
text-overflow: ellipsis;
103+
white-space: nowrap;
104+
}
105+
106+
.sharedTag {
107+
color: #1c6b55;
108+
background: rgba(28, 138, 115, 0.12);
109+
border-color: rgba(28, 138, 115, 0.28);
110+
}
111+
112+
.name {
113+
margin: 0;
114+
color: var(--text-strong, var(--text));
115+
font-size: 15px;
116+
font-weight: 600;
117+
line-height: 1.35;
118+
overflow-wrap: anywhere;
119+
}
120+
121+
.subline {
122+
display: flex;
123+
flex-wrap: wrap;
124+
align-items: center;
125+
gap: 6px;
126+
margin-top: 7px;
127+
color: var(--text-muted);
128+
font-size: 12.5px;
129+
line-height: 1.4;
130+
}
131+
132+
.actions {
133+
grid-column: 1 / -1;
134+
display: flex;
135+
flex-wrap: wrap;
136+
align-items: center;
137+
justify-content: flex-end;
138+
gap: 8px;
139+
align-self: end;
140+
}
141+
142+
@media (max-width: 640px) {
143+
.header {
144+
align-items: stretch;
145+
flex-direction: column;
146+
}
147+
148+
.grid {
149+
grid-template-columns: 1fr;
150+
}
151+
152+
.actions {
153+
justify-content: stretch;
154+
}
155+
156+
.actions > button {
157+
flex: 1 1 140px;
158+
}
159+
}

0 commit comments

Comments
 (0)