Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Entwicklungsportal - ARCHIVED
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
FIT-Connect
Entwicklungsportal - ARCHIVED
Commits
b7b6fd34
Commit
b7b6fd34
authored
2 years ago
by
Mark Kane
Browse files
Options
Downloads
Patches
Plain Diff
planning#401
: implement filter logic
parent
8376d2ea
No related branches found
Branches containing commit
No related tags found
1 merge request
!7
planning#401: add resource filters
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
lib/contentful/index.ts
+1
-0
1 addition, 0 deletions
lib/contentful/index.ts
pages/suites/index.tsx
+113
-86
113 additions, 86 deletions
pages/suites/index.tsx
tsconfig.json
+1
-0
1 addition, 0 deletions
tsconfig.json
with
115 additions
and
86 deletions
lib/contentful/index.ts
+
1
−
0
View file @
b7b6fd34
...
...
@@ -22,6 +22,7 @@ export type ServiceType = {
contactInformation
:
object
status
:
string
documentationURL
:
string
tags
?:
any
[]
sourcecodeURL
?:
string
tosURL
?:
string
description
:
object
...
...
This diff is collapsed.
Click to expand it.
pages/suites/index.tsx
+
113
−
86
View file @
b7b6fd34
import
React
,
{
useEffect
,
useState
}
from
"
react
"
;
import
{
useRouter
}
from
'
next/router
'
import
Link
from
'
next/link
'
import
{
fetchServices
}
from
'
@/lib/contentful
'
import
{
fetchServices
,
ServiceType
}
from
'
@/lib/contentful
'
import
{
documentToHtmlString
}
from
'
@contentful/rich-text-html-renderer
'
import
{
IconArrowBigRight
,
IconSearch
}
from
'
@tabler/icons
'
export
default
function
({
services
})
{
const
router
=
useRouter
()
const
filters
=
[
{
label
:
'
Art des Dienstes
'
,
...
...
@@ -12,62 +14,19 @@ export default function ({ services }) {
options
:
[{
label
:
'
Plattformen
'
,
id
:
'
platform
'
,
value
:
'
platform
'
,
},{
label
:
'
Basisdienste
'
,
id
:
''
,
value
:
''
,
id
:
'
base
'
,
value
:
'
base
'
,
},{
label
:
'
Software
'
,
id
:
''
,
value
:
''
,
id
:
'
software
'
,
value
:
'
software
'
,
},{
label
:
'
APIs
'
,
id
:
''
,
value
:
''
,
}]
},
{
label
:
'
Use Cases
'
,
id
:
'
use-case
'
,
options
:
[{
label
:
'
Bezahlsystem
'
,
id
:
'
platform
'
,
},{
label
:
'
Übertragungssystem
'
,
id
:
''
,
value
:
''
,
},{
label
:
'
Referenzarchitektur
'
,
id
:
''
,
value
:
''
,
}]
},
{
label
:
'
Region
'
,
id
:
'
region
'
,
options
:
[{
label
:
'
Niedersachsen
'
,
id
:
'
platform
'
,
},{
label
:
'
Baden-Württemberg
'
,
id
:
''
,
value
:
''
,
},{
label
:
'
Bayern
'
,
id
:
''
,
value
:
''
,
},{
label
:
'
Thüringen
'
,
id
:
''
,
value
:
''
,
},{
label
:
'
Hessen
'
,
id
:
''
,
value
:
''
,
},{
label
:
'
Nordrhein-Westfalen
'
,
id
:
''
,
value
:
''
,
id
:
'
api
'
,
value
:
'
api
'
,
}]
},
{
...
...
@@ -76,19 +35,95 @@ export default function ({ services }) {
options
:
[{
label
:
'
Produktiv
'
,
id
:
'
production
'
,
value
:
'
production
'
,
},{
label
:
'
Beta
'
,
id
:
''
,
value
:
''
,
id
:
'
beta
'
,
value
:
'
beta
'
,
},{
label
:
'
In Entwicklung
'
,
id
:
''
,
value
:
''
,
id
:
'
development
'
,
value
:
'
development
'
,
}]
}
]
const
defaultFilters
:
any
=
{
type
:
[],
status
:
[],
}
const
[
activeFilters
,
setActiveFilters
]
=
useState
(
defaultFilters
)
const
[
filteredServices
,
setFilteredServices
]
=
useState
(
services
)
useEffect
(()
=>
{
// filter param change, update filter and filter servicves
if
(
router
.
query
.
filter
)
{
setActiveFilters
(
paramsToFilter
(
router
.
query
.
filter
))
}
else
{
setActiveFilters
(
defaultFilters
)
}
setFilteredServices
(
filterServices
())
},
[
router
.
query
.
filter
])
function
filterToParams
()
{
const
res
=
[]
Object
.
keys
(
activeFilters
).
forEach
(
f
=>
{
if
(
activeFilters
[
f
].
length
>
0
)
{
activeFilters
[
f
].
forEach
(
i
=>
res
.
push
(
i
))
}
})
return
[...
new
Set
(
res
)].
join
(
'
&
'
)
}
function
paramsToFilter
(
str
)
{
if
(
!
str
)
return
defaultFilters
const
filters
=
str
.
split
(
'
&
'
)
filters
.
forEach
(
f
=>
{
const
filter
=
f
.
split
(
'
:
'
)[
0
]
if
(
activeFilters
[
filter
].
indexOf
(
f
)
<
0
)
{
activeFilters
[
filter
].
push
(
f
)
}
})
return
activeFilters
}
function
filterServices
()
{
return
services
.
filter
((
s
:
ServiceType
)
=>
{
const
tags
:
string
[]
=
s
.
tags
?
s
.
tags
.
map
(
o
=>
o
.
fields
.
name
)
:
[]
const
groups
:
any
=
{}
let
match
=
true
tags
.
forEach
(
tag
=>
{
const
t
=
tag
.
split
(
'
:
'
)
if
(
!
groups
[
t
[
0
]])
groups
[
t
[
0
]]
=
[]
groups
[
t
[
0
]].
push
(
tag
)
})
Object
.
keys
(
activeFilters
).
forEach
(
f
=>
{
if
(
activeFilters
[
f
].
length
>
0
)
{
if
(
activeFilters
[
f
].
length
===
0
)
return
if
(
!
groups
[
f
])
return
match
=
false
groups
[
f
].
forEach
(
item
=>
{
if
(
item
.
startsWith
(
f
+
'
:
'
)
&&
!
activeFilters
[
f
].
includes
(
item
))
{
match
=
false
}
})
}
})
return
match
})
}
function
handleFilters
(
event
)
{
const
filter
=
event
.
target
.
id
.
split
(
'
-
'
)[
0
]
if
(
event
.
target
.
checked
)
{
activeFilters
[
filter
].
push
(
event
.
target
.
value
)
}
else
if
(
activeFilters
[
filter
].
indexOf
(
event
.
target
.
value
)
>=
0
)
{
activeFilters
[
filter
].
splice
(
activeFilters
[
filter
].
indexOf
(
event
.
target
.
value
),
1
)
}
// we always track filters in query params, param change will trigger filtering
router
.
push
(
`?filter=
${
encodeURIComponent
(
filterToParams
())}
`
,
undefined
,
{
shallow
:
true
})
}
return
(
<
div
className
=
"py-10"
>
...
...
@@ -100,11 +135,11 @@ export default function ({ services }) {
>
<
h1
>
<
span
className
=
"mt-1 block text-4xl tracking-tight font-extrabold sm:text-5xl xl:text-7xl"
>
<
span
className
=
"block text-gray-900"
>
Verfügbare Plattformen
&
Basisdienste
</
span
>
<
span
className
=
"block text-gray-900"
>
Verfügbare Plattformen
&
amp;
Basisdienste
</
span
>
</
span
>
</
h1
>
</
header
>
<
div
className
=
"hidden lg:block lg:col-span-3 xl:col-span-2"
>
<
form
name
=
"filters"
className
=
"hidden lg:block lg:col-span-3 xl:col-span-2"
>
<
nav
aria-label
=
"Sidebar"
className
=
"sticky top-4 divide-y divide-gray-300"
...
...
@@ -122,27 +157,29 @@ export default function ({ services }) {
aria-labelledby
=
{
`
${
filter
.
id
}
-headline`
}
>
{
filter
.
options
.
map
((
option
)
=>
(
<
div
key
=
{
option
.
value
}
className
=
"flex items-center"
>
<
input
id
=
{
`
${
filter
.
id
}
-
${
option
.
id
}
`
}
name
=
{
`
${
filter
.
id
}
[]`
}
defaultValue
=
{
option
.
value
}
type
=
"checkbox"
className
=
"h-4 w-4 border-gray-300 rounded text-indigo-600 focus:ring-indigo-500"
/>
<
label
htmlFor
=
{
`
${
filter
.
id
}
-
${
option
.
id
}
`
}
className
=
"ml-3 text-sm text-gray-500"
>
{
option
.
label
}
</
label
>
</
div
>
<
div
key
=
{
option
.
value
}
className
=
"flex items-center"
>
<
input
onClick
=
{
handleFilters
}
id
=
{
`
${
filter
.
id
}
-
${
option
.
id
}
`
}
name
=
{
`
${
filter
.
id
}
[]`
}
defaultValue
=
{
`
${
filter
.
id
}
:
${
option
.
id
}
`
}
defaultChecked
=
{
router
.
query
.
filter
?
router
.
query
.
filter
.
includes
(
`
${
filter
.
id
}
:
${
option
.
id
}
`
)
:
false
}
type
=
"checkbox"
className
=
"h-4 w-4 border-gray-300 rounded text-indigo-600 focus:ring-indigo-500"
/>
<
label
htmlFor
=
{
`
${
filter
.
id
}
-
${
option
.
id
}
`
}
className
=
"ml-3 text-sm text-gray-500"
>
{
option
.
label
}
</
label
>
</
div
>
))
}
</
div
>
</
div
>
))
}
</
nav
>
</
div
>
</
form
>
<
main
className
=
"lg:col-span-9 xl:col-span-9"
>
{
/*
<div className="px-4 sm:px-0">
...
...
@@ -171,9 +208,9 @@ export default function ({ services }) {
<
div
className
=
"mt-4"
>
<
h1
className
=
"sr-only"
>
Gelistete Services
</
h1
>
<
ul
role
=
"list"
className
=
"space-y-4"
>
{
s
ervices
.
map
((
service
,
key
)
=>
(
{
filteredS
ervices
.
map
((
service
,
key
)
=>
(
<
li
key
=
{
key
}
key
=
{
service
.
slug
}
className
=
"bg-white px-4 py-6 shadow sm:p-6 sm:rounded-lg"
>
<
div
aria-labelledby
=
{
'
service-
'
+
key
}
>
...
...
@@ -251,13 +288,3 @@ export async function getStaticProps(context) {
}
}
/*
<a
key={community.name}
href={community.href}
className="group flex items-center px-3 py-2 text-sm font-medium text-gray-600 rounded-md hover:text-gray-900 hover:bg-gray-50"
>
<span className="truncate">{community.name}</span>
</a>
*/
This diff is collapsed.
Click to expand it.
tsconfig.json
+
1
−
0
View file @
b7b6fd34
...
...
@@ -4,6 +4,7 @@
"lib"
:
[
"dom"
,
"dom.iterable"
,
"esnext"
],
"allowJs"
:
true
,
"skipLibCheck"
:
true
,
"downlevelIteration"
:
true
,
"strict"
:
false
,
"forceConsistentCasingInFileNames"
:
true
,
"noEmit"
:
true
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment