1
1
import { makeStyles } from "@material-ui/core/styles"
2
- import { TemplateExample } from "api/typesGenerated"
3
2
import { AlertBanner } from "components/AlertBanner/AlertBanner"
4
3
import { Maybe } from "components/Conditionals/Maybe"
5
4
import { Loader } from "components/Loader/Loader"
@@ -12,39 +11,26 @@ import {
12
11
import { Stack } from "components/Stack/Stack"
13
12
import { FC } from "react"
14
13
import { useTranslation } from "react-i18next"
15
- import { Link } from "react-router-dom"
14
+ import { Link , useSearchParams } from "react-router-dom"
15
+ import { combineClasses } from "util/combineClasses"
16
16
import { StarterTemplatesContext } from "xServices/starterTemplates/starterTemplatesXService"
17
17
18
- const getTagLabel = ( tag : string ) => {
18
+ const getTagLabel = ( tag : string , t : ( key : string ) => string ) => {
19
19
const labelByTag : Record < string , string > = {
20
- digitalocean : "Digital Ocean" ,
21
- aws : "AWS" ,
22
- google : "Google Cloud" ,
20
+ all : t ( "tags.all" ) ,
21
+ digitalocean : t ( "tags.digitalocean" ) ,
22
+ aws : t ( "tags.aws" ) ,
23
+ google : t ( "tags.google" ) ,
23
24
}
24
-
25
25
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- this can be undefined
26
26
return labelByTag [ tag ] ?? tag
27
27
}
28
28
29
- const getTemplatesByTag = ( starterTemplates : TemplateExample [ ] | undefined ) => {
30
- if ( ! starterTemplates ) {
31
- return
32
- }
33
-
34
- const tags : Record < string , TemplateExample [ ] > = { }
35
- starterTemplates . forEach ( ( template ) => {
36
- template . tags . forEach ( ( tag ) => {
37
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- this can be undefined
38
- if ( tags [ tag ] ) {
39
- tags [ tag ] . push ( template )
40
- } else {
41
- tags [ tag ] = [ template ]
42
- }
43
- } )
44
- } )
45
- return tags
29
+ const selectTags = ( { starterTemplatesByTag } : StarterTemplatesContext ) => {
30
+ return starterTemplatesByTag
31
+ ? Object . keys ( starterTemplatesByTag ) . sort ( ( a , b ) => a . localeCompare ( b ) )
32
+ : undefined
46
33
}
47
-
48
34
export interface StarterTemplatesPageViewProps {
49
35
context : StarterTemplatesContext
50
36
}
@@ -53,10 +39,13 @@ export const StarterTemplatesPageView: FC<StarterTemplatesPageViewProps> = ({
53
39
context,
54
40
} ) => {
55
41
const { t } = useTranslation ( "starterTemplatesPage" )
42
+ const [ urlParams ] = useSearchParams ( )
56
43
const styles = useStyles ( )
57
- const templatesByTag = getTemplatesByTag ( context . starterTemplates )
58
- const tags = templatesByTag
59
- ? Object . keys ( templatesByTag ) . sort ( ( a , b ) => a . localeCompare ( b ) )
44
+ const { starterTemplatesByTag } = context
45
+ const tags = selectTags ( context )
46
+ const activeTag = urlParams . get ( "tag" ) ?? "all"
47
+ const visibleTemplates = starterTemplatesByTag
48
+ ? starterTemplatesByTag [ activeTag ]
60
49
: undefined
61
50
62
51
return (
@@ -70,28 +59,32 @@ export const StarterTemplatesPageView: FC<StarterTemplatesPageViewProps> = ({
70
59
< AlertBanner error = { context . error } severity = "error" />
71
60
</ Maybe >
72
61
73
- < Maybe condition = { Boolean ( ! context . starterTemplates ) } >
62
+ < Maybe condition = { Boolean ( ! starterTemplatesByTag ) } >
74
63
< Loader />
75
64
</ Maybe >
76
65
77
66
< Stack direction = "row" spacing = { 4 } >
78
- { templatesByTag && tags && (
67
+ { starterTemplatesByTag && tags && (
79
68
< Stack className = { styles . filter } >
80
- < span className = { styles . filterCaption } > Filter</ span >
81
- < Link to = "" className = { styles . tagLink } >
82
- All templates ({ context . starterTemplates ?. length } )
83
- </ Link >
69
+ < span className = { styles . filterCaption } > { t ( "filterCaption" ) } </ span >
84
70
{ tags . map ( ( tag ) => (
85
- < Link key = { tag } to = { `?tag=${ tag } ` } className = { styles . tagLink } >
86
- { getTagLabel ( tag ) } ({ templatesByTag [ tag ] . length } )
71
+ < Link
72
+ key = { tag }
73
+ to = { `?tag=${ tag } ` }
74
+ className = { combineClasses ( {
75
+ [ styles . tagLink ] : true ,
76
+ [ styles . tagLinkActive ] : tag === activeTag ,
77
+ } ) }
78
+ >
79
+ { getTagLabel ( tag , t ) } ({ starterTemplatesByTag [ tag ] . length } )
87
80
</ Link >
88
81
) ) }
89
82
</ Stack >
90
83
) }
91
84
92
85
< div className = { styles . templates } >
93
- { context . starterTemplates &&
94
- context . starterTemplates . map ( ( example ) => (
86
+ { visibleTemplates &&
87
+ visibleTemplates . map ( ( example ) => (
95
88
< Link
96
89
to = { example . id }
97
90
className = { styles . template }
@@ -117,6 +110,7 @@ export const StarterTemplatesPageView: FC<StarterTemplatesPageViewProps> = ({
117
110
const useStyles = makeStyles ( ( theme ) => ( {
118
111
filter : {
119
112
width : theme . spacing ( 26 ) ,
113
+ flexShrink : 0 ,
120
114
} ,
121
115
122
116
filterCaption : {
@@ -138,10 +132,17 @@ const useStyles = makeStyles((theme) => ({
138
132
} ,
139
133
} ,
140
134
135
+ tagLinkActive : {
136
+ color : theme . palette . text . primary ,
137
+ fontWeight : 600 ,
138
+ } ,
139
+
141
140
templates : {
141
+ flex : "1" ,
142
142
display : "grid" ,
143
143
gridTemplateColumns : "repeat(2, minmax(0, 1fr))" ,
144
144
gap : theme . spacing ( 2 ) ,
145
+ gridAutoRows : "min-content" ,
145
146
} ,
146
147
147
148
template : {
@@ -152,6 +153,7 @@ const useStyles = makeStyles((theme) => ({
152
153
color : "inherit" ,
153
154
display : "flex" ,
154
155
alignItems : "center" ,
156
+ height : "fit-content" ,
155
157
156
158
"&:hover" : {
157
159
backgroundColor : theme . palette . background . paperLight ,
0 commit comments