@@ -71,81 +71,132 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
71
71
? templatesByOrg [ activeOrg ]
72
72
: undefined ;
73
73
74
- return (
75
- < Margins >
76
- < PageHeader
77
- actions = {
78
- canCreateTemplates && < CreateTemplateButton onNavigate = { navigate } />
79
- }
80
- >
81
- < PageHeaderTitle >
82
- < Stack spacing = { 1 } direction = "row" alignItems = "center" >
83
- Templates
84
- < TemplateHelpTooltip />
85
- </ Stack >
86
- </ PageHeaderTitle >
87
- { ! isEmpty && (
88
- < PageHeaderSubtitle >
89
- Select a template to create a workspace.
90
- </ PageHeaderSubtitle >
91
- ) }
92
- </ PageHeader >
74
+ const headerActionElem = canCreateTemplates && (
75
+ < div
76
+ css = { ( theme ) => ( {
77
+ display : "flex" ,
93
78
94
- { Boolean ( error ) && (
95
- < ErrorAlert error = { error } css = { { marginBottom : 32 } } />
96
- ) }
79
+ // we have special breakpoint behavior for the primary template CTA
80
+ // so it always aligns with the cards in the gallery view
81
+ // (as long as we have cards)
82
+ ...( isEmpty
83
+ ? { }
84
+ : {
85
+ [ theme . breakpoints . down ( 1280 ) ] : {
86
+ marginLeft : "unset" ,
87
+ position : "relative" ,
88
+ right : 95 ,
89
+ } ,
90
+ } ) ,
97
91
98
- { Boolean ( ! templatesByOrg ) && < Loader /> }
92
+ [ theme . breakpoints . down ( 1024 ) ] : {
93
+ position : "static" ,
94
+ marginLeft : "initial" ,
95
+ width : "100%" ,
96
+ } ,
97
+ } ) }
98
+ >
99
+ < CreateTemplateButton onNavigate = { navigate } />
100
+ </ div >
101
+ ) ;
99
102
100
- < Stack direction = "row" spacing = { 4 } alignItems = "flex-start" >
101
- { templatesByOrg && Object . keys ( templatesByOrg ) . length > 2 && (
102
- < Stack
103
- css = { { width : 208 , flexShrink : 0 , position : "sticky" , top : 48 } }
104
- >
105
- < span css = { styles . filterCaption } > ORGANIZATION</ span >
106
- { Object . entries ( templatesByOrg ) . map ( ( org ) => (
107
- < Link
108
- key = { org [ 0 ] }
109
- to = { `?org=${ org [ 0 ] } ` }
110
- css = { [
111
- styles . tagLink ,
112
- org [ 0 ] === activeOrg && styles . tagLinkActive ,
113
- ] }
114
- >
115
- { org [ 0 ] === "all" ? "all" : org [ 1 ] [ 0 ] . organization_display_name } { " " }
116
- ({ org [ 1 ] . length } )
117
- </ Link >
118
- ) ) }
119
- </ Stack >
103
+ return (
104
+ < Margins >
105
+ < div css = { { display : "flex" , flexDirection : "column" , width : "100%" } } >
106
+ < PageHeader
107
+ css = { { display : "flex" , width : "100%" } }
108
+ actions = { headerActionElem }
109
+ >
110
+ < PageHeaderTitle >
111
+ < Stack spacing = { 1 } direction = "row" alignItems = "center" >
112
+ Templates
113
+ < TemplateHelpTooltip />
114
+ </ Stack >
115
+ </ PageHeaderTitle >
116
+ { ! isEmpty && (
117
+ < PageHeaderSubtitle >
118
+ Select a template to create a workspace.
119
+ </ PageHeaderSubtitle >
120
+ ) }
121
+ </ PageHeader >
122
+
123
+ { Boolean ( error ) && (
124
+ < ErrorAlert error = { error } css = { { marginBottom : 32 } } />
120
125
) }
121
126
127
+ { Boolean ( ! templatesByOrg ) && < Loader /> }
128
+
122
129
< div
123
130
css = { {
124
131
display : "flex" ,
125
- flexWrap : "wrap" ,
126
- gap : 32 ,
127
- height : "max-content" ,
132
+ flexDirection : "row" ,
133
+ justifyContent :
134
+ visibleTemplates && visibleTemplates . length > 2
135
+ ? "space-between"
136
+ : "flex-start" ,
137
+ width : "100%" ,
128
138
} }
129
139
>
130
- { isEmpty ? (
131
- < EmptyTemplates
132
- canCreateTemplates = { canCreateTemplates }
133
- examples = { examples ?? [ ] }
134
- />
135
- ) : (
136
- visibleTemplates &&
137
- visibleTemplates . map ( ( template ) => (
138
- < TemplateCard
139
- css = { ( theme ) => ( {
140
- backgroundColor : theme . palette . background . paper ,
141
- } ) }
142
- template = { template }
143
- key = { template . id }
144
- />
145
- ) )
146
- ) }
140
+ < div css = { { display : "flex" } } >
141
+ { templatesByOrg && Object . keys ( templatesByOrg ) . length > 2 && (
142
+ < Stack
143
+ css = { { width : 208 , flexShrink : 0 , position : "sticky" , top : 48 } }
144
+ >
145
+ < span css = { styles . filterCaption } > ORGANIZATION</ span >
146
+ { Object . entries ( templatesByOrg ) . map ( ( org ) => (
147
+ < Link
148
+ key = { org [ 0 ] }
149
+ to = { `?org=${ org [ 0 ] } ` }
150
+ css = { [
151
+ styles . tagLink ,
152
+ org [ 0 ] === activeOrg && styles . tagLinkActive ,
153
+ ] }
154
+ >
155
+ { org [ 0 ] === "all"
156
+ ? "all"
157
+ : org [ 1 ] [ 0 ] . organization_display_name } { " " }
158
+ ({ org [ 1 ] . length } )
159
+ </ Link >
160
+ ) ) }
161
+ </ Stack >
162
+ ) }
163
+ </ div >
164
+
165
+ < div css = { { display : "flex" } } >
166
+ < div
167
+ css = { ( theme ) => ( {
168
+ display : "flex" ,
169
+ justifyContent : "space-between" ,
170
+ flexWrap : "wrap" ,
171
+ gap : 32 ,
172
+ height : "max-content" ,
173
+
174
+ [ theme . breakpoints . down ( 1280 ) ] : {
175
+ justifyContent : "flex-start" ,
176
+ } ,
177
+ } ) }
178
+ >
179
+ { isEmpty ? (
180
+ < EmptyTemplates
181
+ canCreateTemplates = { canCreateTemplates }
182
+ examples = { examples ?? [ ] }
183
+ />
184
+ ) : (
185
+ visibleTemplates &&
186
+ visibleTemplates . map ( ( template ) => (
187
+ < TemplateCard
188
+ css = { ( theme ) => ( {
189
+ backgroundColor : theme . palette . background . paper ,
190
+ } ) }
191
+ template = { template }
192
+ key = { template . id }
193
+ />
194
+ ) )
195
+ ) }
196
+ </ div >
197
+ </ div >
147
198
</ div >
148
- </ Stack >
199
+ </ div >
149
200
</ Margins >
150
201
) ;
151
202
} ;
0 commit comments