Fakultas Ilmu Komputer UI
Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ppl-fasilkom-ui
PPL Sosial
tbcare
tbcare-web
Commits
46fa99ec
Commit
46fa99ec
authored
May 30, 2021
by
Sean Zeliq Urian
Browse files
[RED] Seperate List and Tabel Component
parent
03c7e009
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/scenes/ActivityLog/components/ActivityList/index.tsx
0 → 100644
View file @
46fa99ec
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'
react
'
;
import
styled
,
{
ThemeContext
}
from
'
styled-components
'
;
import
{
Box
,
Text
,
Gap
,
Icon
,
Field
,
Button
,
Checkbox
,
}
from
'
components
'
;
import
{
AppContext
}
from
'
contexts
'
;
import
Loading
from
'
components/Loading
'
;
import
{
DateProps
}
from
'
contexts/AppContext/types
'
;
import
{
Log
}
from
'
scenes/ActivityLog/types/types
'
;
import
{
generateLogDetail
,
generateLogMessage
}
from
"
scenes/ActivityLog/utilities/utils
"
;
import
{
DEFAULT_THEME
}
from
'
scenes/ActivityLog
'
export
default
function
ActivityList
()
{
const
{
colors
}
=
useContext
(
ThemeContext
)
||
DEFAULT_THEME
;
const
{
services
}
=
useContext
(
AppContext
);
const
[
logList
,
setLogList
]
=
useState
<
Log
[]
>
([]);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
next
,
setNext
]
=
useState
(
false
);
const
[
prev
,
setPrev
]
=
useState
(
false
);
const
[
totalLog
,
setTotalLog
]
=
useState
(
0
);
const
[
isLoading
,
setIsLoading
]
=
useState
(
false
);
const
verticalLineHeight
=
(
logList
.
length
-
1
)
*
52
;
const
[
roleFilterQuery
,
setRoleFilterQuery
]
=
useState
<
String
>
(
"
Semua Peran
"
);
const
[
ignoreDateFilterQuery
,
setIgnoredateFilterQuery
]
=
useState
<
boolean
>
(
true
);
const
[
dateFilterQuery
,
setDateFilterQuery
]
=
useState
<
DateProps
>
({
start_date
:
new
Date
(),
end_date
:
new
Date
(),
});
const
VerticalLine
=
styled
.
div
`
border-left: 2px solid
${
colors
.
mediumGray
}
;
height:
${
verticalLineHeight
}
px;
position: absolute;
left: 12px;
top: 5px;
`
;
const
Circle
=
styled
.
div
`
left: 12px;
width: 24px;
height: 24px;
border-radius: 12px;
background:
${
colors
.
mediumGray
}
;
margin-right: 20px;
`
;
const
fetchLog
=
async
(
page
:
number
,
roleFilterQuery
:
String
,
dateFilterQuery
:
DateProps
,
ignoreDateFilterQuery
:
boolean
)
=>
{
let
dateOnly
=
{
start_date
:
dateFilterQuery
.
start_date
.
toISOString
().
split
(
'
T
'
)[
0
],
end_date
:
dateFilterQuery
.
end_date
.
toISOString
().
split
(
'
T
'
)[
0
]
}
setIsLoading
(
true
);
const
logResponse
=
await
services
.
main
.
getLog
(
page
,
roleFilterQuery
,
dateOnly
.
start_date
,
dateOnly
.
end_date
,
ignoreDateFilterQuery
);
let
logs
:
Log
[]
=
[];
for
(
let
log
of
logResponse
.
data
.
results
)
{
let
logObject
:
Log
=
{
timestamp
:
new
Date
(
log
.
recorded_at
),
message
:
await
generateLogMessage
(
log
,
services
),
detail
:
await
generateLogDetail
(
log
,
services
),
};
logs
.
push
(
logObject
);
}
setLogList
(
logs
);
setNext
(
logResponse
.
data
.
next
?
true
:
false
);
setPrev
(
logResponse
.
data
.
previous
?
true
:
false
);
setTotalLog
(
logResponse
.
data
.
count
);
setIsLoading
(
false
);
};
useEffect
(()
=>
{
fetchLog
(
page
,
roleFilterQuery
,
dateFilterQuery
,
ignoreDateFilterQuery
);
},
[
page
]);
return
(
<>
<
Box
width
=
"60%"
margin
=
"2em"
axis
=
{
Box
.
Axis
.
Vertical
}
>
<
Box
width
=
"30%"
axis
=
{
Box
.
Axis
.
Horizontal
}
>
<
Field
name
=
"Dari"
type
=
{
Field
.
Type
.
Date
}
value
=
{
dateFilterQuery
.
start_date
}
updateValue
=
{
(
val
)
=>
{
setDateFilterQuery
({
...
dateFilterQuery
,
start_date
:
val
});
}
}
/>
<
Gap
axis
=
{
Gap
.
Axis
.
Horizontal
}
gap
=
{
20
}
/>
<
Field
name
=
"Sampai"
type
=
{
Field
.
Type
.
Date
}
value
=
{
dateFilterQuery
.
end_date
}
updateValue
=
{
(
val
)
=>
{
setDateFilterQuery
({
...
dateFilterQuery
,
end_date
:
val
});
}
}
/>
<
Gap
axis
=
{
Gap
.
Axis
.
Horizontal
}
gap
=
{
20
}
/>
<
Box
width
=
"100%"
height
=
"75px"
crossAxis
=
"center"
>
<
Checkbox
label
=
"Abaikan rentang waktu"
isChecked
=
{
ignoreDateFilterQuery
}
updateValue
=
{
(
value
)
=>
{
setIgnoredateFilterQuery
(
value
);
}
}
/>
</
Box
>
</
Box
>
<
Gap
gap
=
{
50
}
axis
=
{
Gap
.
Axis
.
Horizontal
}
/>
<
Field
name
=
"Filter peran pembuat aktivitas"
type
=
{
Field
.
Type
.
Dropdown
}
placeholder
=
{
'
Ketikan Admin atau Kader
'
}
value
=
{
roleFilterQuery
}
values
=
{
[
{
label
:
'
Admin
'
,
value
:
'
Admin
'
},
{
label
:
'
Kader
'
,
value
:
'
Kader
'
},
{
label
:
'
Semua Peran
'
,
value
:
'
Semua Peran
'
},
]
}
updateValue
=
{
(
value
)
=>
setRoleFilterQuery
(
value
)
}
/>
<
Gap
gap
=
{
50
}
axis
=
{
Gap
.
Axis
.
Horizontal
}
/>
<
Button
id
=
"filter"
onClick
=
{
()
=>
fetchLog
(
page
,
roleFilterQuery
,
dateFilterQuery
,
ignoreDateFilterQuery
)
}
>
Terapkan Filter
</
Button
>
</
Box
>
<
Box
width
=
"100%"
axis
=
{
Box
.
Axis
.
Vertical
}
margin
=
"2em 2em"
>
{
logList
.
length
===
0
&&
isLoading
===
false
?
(
<
Box
width
=
"100%"
crossAxis
=
"center"
mainAxis
=
"center"
>
<
Text
color
=
{
colors
.
mediumGray
}
>
Belum ada aktivitas yang tercatat
</
Text
>
</
Box
>
)
:
(
<></>
)
}
<
VerticalLine
/>
{
logList
?.
map
((
log
:
Log
,
index
:
number
)
=>
{
return
(
<
Box
id
=
"list-activity"
width
=
"100%"
key
=
{
index
}
>
<
Circle
/>
<
Box
width
=
"80%"
axis
=
{
Box
.
Axis
.
Vertical
}
>
<
Text
isBold
>
{
log
.
timestamp
.
toLocaleString
(
'
id-ID
'
,
{
weekday
:
'
long
'
,
year
:
'
numeric
'
,
month
:
'
long
'
,
day
:
'
numeric
'
,
hour
:
'
numeric
'
,
minute
:
'
numeric
'
,
})
}
</
Text
>
<
Text
>
{
log
.
message
.
length
>
128
?
log
.
message
.
slice
(
0
,
125
)
+
'
...
'
:
log
.
message
}
</
Text
>
<
Gap
axis
=
{
Gap
.
Axis
.
Vertical
}
gap
=
{
12
}
></
Gap
>
</
Box
>
</
Box
>
);
})
}
</
Box
>
<
Box
width
=
"100%"
mainAxis
=
"flex-end"
>
<
Text
color
=
{
colors
.
mediumGray
}
>
{
((
page
-
1
)
*
10
+
logList
.
length
).
toString
()
+
'
dari
'
+
totalLog
}
</
Text
>
<
Gap
gap
=
{
12
}
axis
=
{
Gap
.
Axis
.
Horizontal
}
/>
<
Icon
id
=
"prev-button"
cursor
=
"pointer"
onClick
=
{
prev
?
()
=>
setPage
(
page
-
1
)
:
()
=>
{
}
}
src
=
"/assets/icons/right-paging.svg"
origin
=
"50% 50%"
height
=
"16px"
opacity
=
{
prev
?
1
:
0.5
}
transform
=
"rotateZ(180deg)"
/>
<
Gap
gap
=
{
12
}
axis
=
{
Gap
.
Axis
.
Horizontal
}
/>
<
Text
id
=
"page-number"
>
{
`
${
page
}
`
}
</
Text
>
<
Gap
gap
=
{
12
}
axis
=
{
Gap
.
Axis
.
Horizontal
}
/>
<
Icon
id
=
"next-button"
cursor
=
"pointer"
onClick
=
{
next
?
()
=>
setPage
(
page
+
1
)
:
()
=>
{
}
}
src
=
"/assets/icons/right-paging.svg"
height
=
"16px"
opacity
=
{
next
?
1
:
0.5
}
/>
</
Box
>
<
Loading
isLoading
=
{
isLoading
}
shouldSetBlackTheme
=
{
true
}
/>
</>
);
}
src/scenes/ActivityLog/components/ActivityLog/index.test.tsx
deleted
100644 → 0
View file @
03c7e009
import
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
renderer
,
{
act
}
from
'
react-test-renderer
'
;
import
ActivityLog
from
'
.
'
;
import
{
useMainService
}
from
'
services
'
;
import
{
AppContext
}
from
'
contexts
'
;
import
{
mount
}
from
'
enzyme
'
;
jest
.
mock
(
'
axios
'
);
const
mockedAxios
=
axios
as
jest
.
Mocked
<
typeof
axios
>
;
const
testProps
=
{
services
:
{
main
:
useMainService
(
'
dummyToken
'
),
},
};
it
(
'
renders correctly
'
,
()
=>
{
const
instance
=
renderer
.
create
(
<
ActivityLog
/>
);
expect
(
instance
).
toBeTruthy
();
});
describe
(
'
load logs and generate log messages correctly
'
,
()
=>
{
it
(
'
Monitoring case
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Create
"
,
model_name
:
"
Monitoring Case
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
],
investigation_case
:
{
case_subject
:
{
name
:
"
Test
"
}
}
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Investigation case
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Create
"
,
model_name
:
"
Investigation Case
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
],
case_subject
:
{
name
:
"
Test
"
}
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Case subject
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Create
"
,
model_name
:
"
Case Subject
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
],
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Create account
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
username
:
"
Test
"
,
is_admin
:
false
,
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Create
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Create account, but account deleted
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Create
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Edit account
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
username
:
"
Test
"
,
is_admin
:
false
,
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Edit
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Edit account, but account deleted
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
404
,
data
:
{
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Edit
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
it
(
'
Delete account
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
username
:
"
Test
"
,
is_admin
:
false
,
previous
:
null
,
next
:
null
,
count
:
1
,
results
:
[
{
action_type
:
"
Delete
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
});
});
it
(
'
fetch new logs and change page number when press next or previous button
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
username
:
"
Test
"
,
is_admin
:
false
,
previous
:
true
,
next
:
true
,
count
:
1
,
results
:
[
{
action_type
:
"
Delete
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
const
prevButton
=
instance
.
find
(
'
#prev-button
'
);
const
nextButton
=
instance
.
find
(
'
#next-button
'
);
let
pageNumber
=
instance
.
find
(
'
Text
'
).
findWhere
(
elem
=>
elem
.
prop
(
'
id
'
)
===
'
page-number
'
);
expect
(
pageNumber
.
text
()).
toBe
(
'
1
'
);
nextButton
.
at
(
0
).
simulate
(
'
click
'
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
prevButton
.
at
(
0
).
simulate
(
'
click
'
);
pageNumber
=
instance
.
find
(
'
Text
'
).
findWhere
(
elem
=>
elem
.
prop
(
'
id
'
)
===
'
page-number
'
);
expect
(
pageNumber
.
text
()).
toBe
(
'
1
'
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
})
it
(
'
Sort and filter are displayed and clickable
'
,
()
=>
{
mockedAxios
.
request
.
mockResolvedValue
({
status
:
200
,
data
:
{
username
:
"
Test
"
,
is_admin
:
false
,
previous
:
true
,
next
:
true
,
count
:
1
,
results
:
[
{
action_type
:
"
Delete
"
,
model_name
:
"
Account
"
,
object_id
:
"
1234
"
,
recorded_at
:
"
2020-05-31T23:03:35.854615+07:00
"
,
},
]
}
});
const
instance
=
mount
(
<
AppContext
.
Provider
value
=
{
testProps
}
>
<
ActivityLog
/>
</
AppContext
.
Provider
>
);
expect
(
mockedAxios
.
request
).
toBeCalled
();
let
categoryButton
=
instance
.
find
(
'
[data-test-id="button-Tabel"]
'
);
categoryButton
.
at
(
0
).
simulate
(
'
click
'
);
let
sortByDate
=
instance
.
find
(
"
#sortbydate
"
);
let
sortByObj
=
instance
.
find
(
"
#sortbyobj
"
);
let
filter
=
instance
.
find
(
"
#filter
"
);
sortByDate
.
simulate
(
"
click
"
);
sortByObj
.
simulate
(
"
click
"
);
filter
.
simulate
(
"
click
"
);
let
table
=
instance
.
find
(
"
Table
"
);
expect
(
table
).
toBeTruthy
();
});
\ No newline at end of file
src/scenes/ActivityLog/components/ActivityLog/index.tsx
deleted
100644 → 0
View file @
03c7e009
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'
react
'
;
import
styled
,
{
ThemeContext
}
from
'
styled-components
'
;
import
{
Box
,
Text
,
Content
,
Gap
,
Icon
,
Table
,
CategoryButton
,
Field
,
Button
}
from
'
components
'
;
import
{
AppContext
}
from
'
contexts
'
;
import
Loading
from
'
components/Loading
'
;
interface
Log
{
timestamp
:
Date
;
message
:
string
;
detail
:
LogDetail
;
}
interface
LogDetail
{
activity
:
string
;
authorRole
:
"
admin
"
|
"
kader
"
;
authorName
:
string
;
object
:
string
;
}
const
DEFAULT_THEME
=
{
colors
:
{
totallyWhite
:
'
white
'
,
mediumGray
:
'
gray
'
,
},
};
export
default
function
ActivityLog
()
{
const
{
colors
}
=
useContext
(
ThemeContext
)
||
DEFAULT_THEME
;
const
{
services
}
=
useContext
(
AppContext
);
const
[
logList
,
setLogList
]
=
useState
<
Log
[]
>
([]);
const
[
logTable
,
setLogTable
]
=
useState
<
Log
[]
>
([]);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
next
,
setNext
]
=
useState
(
false
);
const
[
prev
,
setPrev
]
=
useState
(
false
);
const
[
totalLog
,
setTotalLog
]
=
useState
(
0
);
const
[
isLoading
,
setIsLoading
]
=
useState
(
true
);
const
verticalLineHeight
=
((
logList
.
length
-
1
)
*
52
);