Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
goSDN
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
danet
goSDN
Merge requests
!1204
(ui): Add custom scroll bar
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
(ui): Add custom scroll bar
ui-add-scroll-devices
into
ui-integration
Overview
0
Commits
8
Pipelines
2
Changes
16
Merged
Matthias Feyll
requested to merge
ui-add-scroll-devices
into
ui-integration
1 month ago
Overview
0
Commits
8
Pipelines
2
Changes
16
Expand
0
0
Merge request reports
Compare
ui-integration
version 2
9e5eea06
1 month ago
version 1
9e5eea06
1 month ago
ui-integration (base)
and
latest version
latest version
19c8bf6d
8 commits,
1 month ago
version 2
9e5eea06
7 commits,
1 month ago
version 1
9e5eea06
82 commits,
1 month ago
16 files
+
574
−
387
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
16
Search (e.g. *.vue) (Ctrl+P)
react-ui/src/components/devices/view/boxes/devices.box.view.tsx
0 → 100755
+
142
−
0
Options
import
{
useDeviceBoxViewModel
}
from
'
@component/devices/view_model/device.box.viewmodel
'
import
{
faPlus
}
from
'
@fortawesome/free-solid-svg-icons
'
import
{
FontAwesomeIcon
}
from
'
@fortawesome/react-fontawesome
'
import
{
insertMarkTags
}
from
'
@helper/text
'
import
{
Scrollbar
}
from
'
@shared/components/scrollbar/Scrollbar.view
'
import
DOMPurify
from
'
dompurify
'
import
{
RefObject
,
useCallback
}
from
'
react
'
import
{
Button
,
Col
,
Form
,
OverlayTrigger
,
Row
,
Tooltip
}
from
'
react-bootstrap
'
import
{
useTranslation
}
from
'
react-i18next
'
import
{
Device
}
from
'
../../reducer/device.reducer
'
import
AddDeviceModal
from
'
../subcomponent/modal.view
'
export
const
DeviceList
=
({
searchRef
}:
{
searchRef
:
RefObject
<
HTMLInputElement
>
})
=>
{
const
{
t
}
=
useTranslation
(
'
common
'
)
const
{
filteredDevices
,
handleItemClick
,
selectedDevice
,
pnds
,
addModal
,
openAddModal
,
closeModal
,
searchValue
,
handleSearch
,
}
=
useDeviceBoxViewModel
(
searchRef
)
const
cropUUID
=
(
uuid
:
string
):
string
=>
{
return
uuid
.
substring
(
0
,
3
)
+
'
...
'
+
uuid
.
substring
(
uuid
.
length
-
3
,
uuid
.
length
)
}
const
renderDeviceItem
=
useCallback
(
(
device
:
Device
)
=>
{
const
user
=
pnds
.
find
(
pnd
=>
pnd
.
id
===
device
.
pid
)
const
username
=
user
?.
name
||
''
const
deviceId
=
device
.
id
!
const
croppedId
=
cropUUID
(
deviceId
)
const
devicename
=
device
.
name
||
''
const
isSelected
=
selectedDevice
?.
device
.
id
===
deviceId
return
(
<
div
key
=
{
deviceId
}
className
=
{
`border-bottom border-primary p-2 transitions
${
isSelected
&&
'
bg-gradient-fade py-2
'
}
${
!
isSelected
&&
'
text-disabled disabled-hover
'
}
`
}
onClick
=
{
()
=>
handleItemClick
(
device
)
}
>
<
Row
className
=
"align-items-center clickable"
>
<
Col
xs
=
{
12
}
sm
=
{
5
}
>
<
span
dangerouslySetInnerHTML
=
{
{
__html
:
searchValue
?
insertMarkTags
(
devicename
,
searchValue
)
:
DOMPurify
.
sanitize
(
devicename
),
}
}
/>
</
Col
>
<
Col
xs
=
{
12
}
sm
=
{
3
}
>
<
OverlayTrigger
overlay
=
{
<
Tooltip
id
=
{
deviceId
}
>
{
deviceId
}
</
Tooltip
>
}
>
<
span
className
=
"text-gray-500"
dangerouslySetInnerHTML
=
{
{
__html
:
searchValue
?
insertMarkTags
(
croppedId
,
searchValue
)
:
DOMPurify
.
sanitize
(
croppedId
),
}
}
/>
</
OverlayTrigger
>
</
Col
>
<
Col
xs
=
{
12
}
sm
=
{
4
}
>
<
span
className
=
"text-gray-500"
dangerouslySetInnerHTML
=
{
{
__html
:
searchValue
?
insertMarkTags
(
username
,
searchValue
)
:
DOMPurify
.
sanitize
(
username
),
}
}
/>
</
Col
>
</
Row
>
</
div
>
)
},
[
selectedDevice
,
pnds
,
handleItemClick
,
searchValue
],
)
return
(
<
div
className
=
"d-flex flex-column h-100"
>
{
/* Fixed top section */
}
<
div
className
=
"flex-shrink-0"
>
<
Row
className
=
"mb-3 align-items-center"
>
<
Col
xs
=
{
12
}
md
=
{
6
}
lg
=
{
8
}
>
<
Form
.
Group
controlId
=
"device.search"
>
<
Form
.
Control
type
=
"text"
placeholder
=
{
t
(
'
device.search.placeholder
'
)
}
ref
=
{
searchRef
}
value
=
{
searchValue
}
onChange
=
{
e
=>
handleSearch
(
e
.
target
.
value
)
}
/>
</
Form
.
Group
>
</
Col
>
<
Col
xs
=
{
12
}
md
=
{
6
}
lg
=
{
4
}
className
=
"mt-3 mt-md-0 text-md-end"
>
<
Button
variant
=
"primary::button"
className
=
"btn-primary-button"
onClick
=
{
openAddModal
}
>
<
FontAwesomeIcon
icon
=
{
faPlus
}
className
=
"me-2"
/>
{
t
(
'
device.add_device_button
'
)
}
</
Button
>
<
AddDeviceModal
show
=
{
addModal
}
onHide
=
{
closeModal
}
/>
</
Col
>
</
Row
>
</
div
>
{
/* Scrollable list section */
}
<
Scrollbar
className
=
"flex-grow-1 overflow-y-auto overflow-x-hidden"
scrollX
=
{
false
}
>
<
div
className
=
"rounded border border-primary"
>
{
/* Fixed header */
}
<
div
className
=
"sticky-top bg-white border-bottom border-primary"
>
<
Row
className
=
"px-2 py-2 mx-0"
>
<
Col
xs
=
{
12
}
sm
=
{
5
}
>
<
span
className
=
"font-medium"
>
{
t
(
'
device.table.header.name
'
)
}
</
span
>
</
Col
>
<
Col
xs
=
{
12
}
sm
=
{
3
}
>
<
span
className
=
"font-medium"
>
{
t
(
'
device.table.header.uuid
'
)
}
</
span
>
</
Col
>
<
Col
xs
=
{
12
}
sm
=
{
4
}
>
<
span
className
=
"font-medium"
>
{
t
(
'
device.table.header.user
'
)
}
</
span
>
</
Col
>
</
Row
>
</
div
>
{
/* Scrollable content */
}
<
div
className
=
"device-list-content"
>
{
filteredDevices
.
map
(
renderDeviceItem
)
}
</
div
>
</
div
>
</
Scrollbar
>
</
div
>
)
}
Loading