Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Website
Commits
4af2df33
Commit
4af2df33
authored
Jan 24, 2019
by
Matija Obreza
Browse files
Merge branch '190-more-kpi-runs' into 'master'
More KPI runs Closes
#190
See merge request genesys-pgr/genesys-ui!190
parents
51d4f2d7
98f46013
Changes
9
Hide whitespace changes
Inline
Side-by-side
locales/en/translations.json
View file @
4af2df33
...
...
@@ -1457,7 +1457,9 @@
"runFrom"
:
"Run from "
,
"runs"
:
"Runs"
,
"execute"
:
"Execute"
,
"title"
:
"Execution details"
"title"
:
"Execution details"
,
"loadMore"
:
"Load more"
,
"nothingToLoad"
:
"No runs match entered date"
},
"parameterDialog"
:
{
"button"
:
"Add parameter"
,
...
...
@@ -1472,7 +1474,8 @@
"NumericListDimension"
:
"NumericListDimension"
,
"StringListDimension"
:
"StringListDimension"
},
"showRun"
:
"Show run info"
"showRun"
:
"Show run info"
,
"executionRunsLoaded"
:
"Execution runs loaded successfully"
}
}
,
"list"
:
{
...
...
src/kpi/actions/admin.ts
View file @
4af2df33
// actions
import
navigateTo
from
'
actions/navigation
'
;
import
{
showSnackbar
}
from
'
actions/snackbar
'
;
// constants
import
{
...
...
@@ -7,6 +8,7 @@ import {
ADMIN_RECEIVE_PARAM
,
ADMIN_RECEIVE_DIMS
,
ADMIN_RECEIVE_EXECS
,
ADMIN_RECEIVE_EXEC
,
ADMIN_RECEIVE_EXEC_LASTRUN
,
ADMIN_RECEIVE_DIM
,
ADMIN_RECEIVE_EXEC_RUNS
,
ADMIN_APPEND_EXEC_RUNS
,
ADMIN_RECEIVE_EXEC_DET
,
ADMIN_REMOVE_DIM
,
ADMIN_REMOVE_PARAM
,
}
from
'
kpi/constants
'
;
...
...
@@ -72,6 +74,26 @@ const receiveExecutionRun = (executionRun: ExecutionRun): IReducerAction => ({
type
:
ADMIN_RECEIVE_EXEC_LASTRUN
,
payload
:
executionRun
,
});
const
receiveExecutionRuns
=
(
runs
:
Page
<
ExecutionRun
>
):
IReducerAction
=>
({
type
:
ADMIN_RECEIVE_EXEC_RUNS
,
payload
:
{
runs
},
});
const
appendExecutionRuns
=
(
runs
:
Page
<
ExecutionRun
>
):
IReducerAction
=>
({
type
:
ADMIN_APPEND_EXEC_RUNS
,
payload
:
{
runs
},
});
export
const
loadMoreExecutionRuns
=
(
executionName
:
string
,
page
:
number
)
=>
(
dispatch
)
=>
{
return
KpiService
.
executionRuns
(
executionName
,
{
page
,
size
:
10
})
.
then
((
runs
)
=>
{
if
(
runs
.
number
===
0
)
{
dispatch
(
receiveExecutionRuns
(
runs
));
}
else
{
dispatch
(
appendExecutionRuns
(
runs
));
}
dispatch
(
showSnackbar
(
'
kpi.common.executionRunsLoaded
'
));
});
};
export
const
listDimensions
=
(
page
:
IPageRequest
)
=>
(
dispatch
)
=>
{
KpiService
.
listDimensions
(
page
).
then
((
data
)
=>
{
dispatch
(
receiveDimensions
(
ensureDimensionType
(
data
)));
...
...
src/kpi/constants.ts
View file @
4af2df33
...
...
@@ -17,6 +17,8 @@ export const ADMIN_RECEIVE_EXEC = 'kpi/admin/RECEIVE_EXEC';
export
const
ADMIN_REMOVE_EXEC
=
'
kpi/admin/REMOVE_EXEC
'
;
export
const
ADMIN_RECEIVE_EXEC_DET
=
'
kpi/admin/RECEIVE_EXEC_DET
'
;
export
const
ADMIN_RECEIVE_EXEC_LASTRUN
=
'
kpi/admin/RECEIVE_LASTRUN
'
;
export
const
ADMIN_RECEIVE_EXEC_RUNS
=
'
kpi/admin/RECEIVE_EXEC_RUNS
'
;
export
const
ADMIN_APPEND_EXEC_RUNS
=
'
kpi/admin/APPEND_EXEC_RUNS
'
;
export
const
ADMIN_RECEIVE_PARAMS
=
'
kpi/admin/RECEIVE_PARAMS
'
;
export
const
ADMIN_RECEIVE_PARAM
=
'
kpi/admin/RECEIVE_PARAM
'
;
...
...
src/kpi/reducers/admin.ts
View file @
4af2df33
import
update
from
'
immutability-helper
'
;
import
{
IReducerAction
}
from
'
model/common.model
'
;
import
{
IReducerAction
}
from
'
model/common.model
'
;
import
{
ADMIN_APPEND_EXEC_RUNS
,
ADMIN_RECEIVE_DIM
,
ADMIN_RECEIVE_DIMS
,
ADMIN_RECEIVE_EXEC
,
ADMIN_RECEIVE_EXEC_DET
,
ADMIN_RECEIVE_EXEC_LASTRUN
,
ADMIN_RECEIVE_EXEC_RUNS
,
ADMIN_RECEIVE_EXECS
,
ADMIN_RECEIVE_PARAM
,
ADMIN_RECEIVE_PARAMS
,
...
...
@@ -122,6 +124,31 @@ export default function admin(state = INITIAL_STATE, action: IReducerAction) {
exec
:
{
details
:
{
lastRun
:
{
$set
:
action
.
payload
}
}
},
});
}
case
ADMIN_RECEIVE_EXEC_RUNS
:
{
const
{
runs
}
=
action
.
payload
;
return
update
(
state
,
{
exec
:
{
details
:
{
runs
:
{
$set
:
runs
},
},
},
});
}
case
ADMIN_APPEND_EXEC_RUNS
:
{
const
{
runs
}
=
action
.
payload
;
return
update
(
state
,
{
exec
:
{
details
:
{
runs
:
{
content
:
{
$push
:
runs
.
content
},
number
:
{
$set
:
runs
.
number
},
last
:
{
$set
:
runs
.
last
},
first
:
{
$set
:
runs
.
first
},
},
},
},
});
}
case
ADMIN_RECEIVE_DIMS
:
{
return
update
(
state
,
{
dim
:
{
page
:
{
$set
:
action
.
payload
}
},
...
...
src/kpi/translations.json
View file @
4af2df33
...
...
@@ -86,7 +86,9 @@
"runFrom"
:
"Run from "
,
"runs"
:
"Runs"
,
"execute"
:
"Execute"
,
"title"
:
"Execution details"
"title"
:
"Execution details"
,
"loadMore"
:
"Load more"
,
"nothingToLoad"
:
"No runs match entered date"
},
"parameterDialog"
:
{
"button"
:
"Add parameter"
,
...
...
@@ -101,6 +103,7 @@
"NumericListDimension"
:
"NumericListDimension"
,
"StringListDimension"
:
"StringListDimension"
},
"showRun"
:
"Show run info"
"showRun"
:
"Show"
,
"executionRunsLoaded"
:
"Execution runs loaded successfully"
}
}
\ No newline at end of file
src/kpi/ui/admin/ExecutionDisplay.tsx
View file @
4af2df33
...
...
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import
{
bindActionCreators
}
from
'
redux
'
;
import
{
translate
}
from
'
react-i18next
'
;
// Actions
import
{
deleteExecution
,
executeExecution
,
getExecution
,
listDimensions
,
listParameters
}
from
'
kpi/actions/admin
'
;
import
{
deleteExecution
,
executeExecution
,
getExecution
,
listDimensions
,
listParameters
,
loadMoreExecutionRuns
}
from
'
kpi/actions/admin
'
;
import
{
showSnackbar
}
from
'
actions/snackbar
'
;
// Models
import
ExecutionDetails
from
'
model/kpi/ExecutionDetails
'
;
...
...
@@ -23,14 +23,33 @@ import Button from '@material-ui/core/Button';
import
RunTable
from
'
./c/RunTable
'
;
import
ExecutionDialog
from
'
./ExecutionDialog
'
;
import
FileCopyIcon
from
'
@material-ui/icons/FileCopy
'
;
import
DateInput
from
'
./c/DateInput
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
// import { parse } from 'query-string';
/*tslint:disable*/
const
styles
=
(
theme
)
=>
({
runInfoHeaderActions
:
{
height
:
'
24px
'
,
display
:
'
flex
'
as
'
flex
'
,
'
& > div
'
:
{
display
:
'
initial
'
as
'
initial
'
,
},
},
loadMoreButton
:
{
display
:
'
flex
'
as
'
flex
'
,
justifyContent
:
'
center
'
as
'
center
'
,
},
});
/*tslint:enable*/
interface
IExecutionProps
extends
React
.
ClassAttributes
<
any
>
{
classes
:
any
;
t
?:
any
;
shortName
:
string
;
loadMoreExecutionRuns
:
(
name
:
string
,
page
:
number
)
=>
void
;
executionDetails
:
ExecutionDetails
;
getExecution
:
any
;
executeExecution
:
any
;
...
...
@@ -107,6 +126,20 @@ class ExecutionDisplay extends React.Component<IExecutionProps, any> {
}
}
private
loadRunInfoByDate
=
(
date
:
string
)
=>
{
const
{
shortName
,
t
,
showSnackbar
}
=
this
.
props
;
if
(
shortName
)
{
KpiService
.
executionRunByDate
(
shortName
,
date
).
then
((
run
)
=>
{
if
(
!
run
)
{
showSnackbar
(
t
(
'
kpi.admin.p.executionDisplay.nothingToLoad
'
));
}
else
{
this
.
setState
({
currentRun
:
run
});
}
});
}
}
public
componentWillReceiveProps
(
nextProps
)
{
const
{
shortName
,
executionDetails
,
getExecution
}
=
nextProps
;
if
(
!
executionDetails
||
!
executionDetails
.
execution
||
executionDetails
.
execution
.
name
!==
shortName
)
{
...
...
@@ -115,12 +148,19 @@ class ExecutionDisplay extends React.Component<IExecutionProps, any> {
}
}
private
loadMoreExecutionRuns
=
()
=>
{
const
{
shortName
,
executionDetails
,
loadMoreExecutionRuns
}
=
this
.
props
;
if
(
shortName
&&
executionDetails
&&
executionDetails
.
runs
)
{
loadMoreExecutionRuns
(
shortName
,
executionDetails
.
runs
.
number
+
1
);
}
}
public
render
()
{
const
{
t
,
shortName
,
executionDetails
}
=
this
.
props
;
const
{
t
,
classes
,
shortName
,
executionDetails
}
=
this
.
props
;
const
stillLoading
=
!
executionDetails
||
!
executionDetails
.
execution
||
executionDetails
.
execution
.
name
!==
shortName
;
const
execution
=
executionDetails
===
null
?
null
:
executionDetails
.
execution
;
const
runs
=
executionDetails
===
null
?
null
:
executionDetails
.
runs
;
const
runs
=
executionDetails
===
null
||
!
executionDetails
.
runs
?
null
:
executionDetails
.
runs
.
content
;
const
lastRun
=
executionDetails
===
null
?
null
:
executionDetails
.
lastRun
;
const
{
currentRun
}
=
this
.
state
;
...
...
@@ -182,10 +222,13 @@ class ExecutionDisplay extends React.Component<IExecutionProps, any> {
<
Grid
item
sm
=
{
12
}
md
=
{
6
}
>
<
PageSection
title
=
{
currentRun
===
null
?
t
(
'
kpi.admin.p.executionDisplay.lastRun
'
)
:
<
span
>
{
t
(
'
kpi.admin.p.executionDisplay.runFrom
'
)
}
<
PrettyDate
value
=
{
currentRun
.
timestamp
}
/></
span
>
}
action
=
{
<
Button
id
=
"copyBtn"
onClick
=
{
this
.
copyRunTable
}
>
{
t
(
'
common:action.copyToClipboard
'
)
}
<
FileCopyIcon
fontSize
=
"small"
/>
</
Button
>
<
span
className
=
{
classes
.
runInfoHeaderActions
}
>
{
(
currentRun
||
lastRun
)
&&
<
DateInput
initialValue
=
{
currentRun
?
currentRun
.
timestamp
:
lastRun
.
timestamp
}
onSubmit
=
{
this
.
loadRunInfoByDate
}
/>
}
<
Button
id
=
"copyBtn"
onClick
=
{
this
.
copyRunTable
}
>
{
t
(
'
common:action.copyToClipboard
'
)
}
<
FileCopyIcon
fontSize
=
"small"
/>
</
Button
>
</
span
>
}
>
<
RunTable
execution
=
{
execution
}
runInfo
=
{
currentRun
||
lastRun
}
/>
...
...
@@ -200,6 +243,13 @@ class ExecutionDisplay extends React.Component<IExecutionProps, any> {
<
a
onClick
=
{
()
=>
this
.
loadRunInfo
(
runInfo
)
}
>
{
t
(
'
kpi.common.showRun
'
)
}
</
a
>
</
PropertiesItem
>
))
}
<
PropertiesItem
>
{
!
executionDetails
.
runs
.
last
&&
<
a
onClick
=
{
this
.
loadMoreExecutionRuns
}
className
=
{
classes
.
loadMoreButton
}
>
{
t
(
'
kpi.admin.p.executionDisplay.loadMore
'
)
}
</
a
>
}
</
PropertiesItem
>
</
Properties
>
</
PageSection
>
}
...
...
@@ -218,10 +268,11 @@ const mapStateToProps = (state, ownProps) => ({
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
getExecution
,
loadMoreExecutionRuns
,
executeExecution
,
deleteExecution
,
showSnackbar
,
},
dispatch
);
export
default
connect
(
mapStateToProps
,
mapDispatchToProps
)((
translate
()(
ExecutionDisplay
)));
export
default
connect
(
mapStateToProps
,
mapDispatchToProps
)(
withStyles
(
styles
)(
(
translate
()(
ExecutionDisplay
)))
)
;
src/kpi/ui/admin/c/DateInput.tsx
0 → 100644
View file @
4af2df33
import
*
as
React
from
'
react
'
;
import
TextField
from
'
@material-ui/core/TextField
'
;
class
DateInput
extends
React
.
Component
<
any
>
{
public
state
=
{
internalDate
:
''
,
};
private
toDateString
=
(
date
:
any
)
=>
{
if
(
!
date
||
date
===
''
)
{
return
''
;
}
const
valueDate
=
date
.
getTime
?
date
:
new
Date
(
date
);
let
y
=
valueDate
.
getFullYear
().
toString
();
let
m
=
(
valueDate
.
getMonth
()
+
1
).
toString
();
let
d
=
valueDate
.
getDate
().
toString
();
d
=
d
.
length
===
1
?
(
`0
${
d
}
`
)
:
d
;
m
=
m
.
length
===
1
?
(
`0
${
m
}
`
)
:
m
;
y
=
y
.
length
===
1
?
(
`000
${
y
}
`
)
:
y
.
length
===
2
?
(
`00
${
y
}
`
)
:
y
.
length
===
3
?
(
`0
${
y
}
`
)
:
y
;
return
`
${
y
}
-
${
m
}
-
${
d
}
`
;
}
public
componentWillMount
():
void
{
const
{
initialValue
}
=
this
.
props
;
this
.
setState
({
internalDate
:
initialValue
});
}
public
componentWillReceiveProps
(
nextProps
):
void
{
const
{
initialValue
}
=
nextProps
;
const
{
initialValue
:
oldValue
}
=
this
.
props
;
if
(
oldValue
!==
initialValue
)
{
this
.
setState
({
internalDate
:
initialValue
});
}
}
public
render
()
{
return
(
<
TextField
type
=
"date"
onKeyPress
=
{
this
.
handleTextFieldType
}
value
=
{
this
.
toDateString
(
this
.
state
.
internalDate
)
}
onChange
=
{
this
.
onInputChange
}
InputLabelProps
=
{
{
shrink
:
true
}
}
/>
);
}
private
onInputChange
=
(
event
)
=>
{
this
.
setState
({
internalDate
:
event
.
target
.
value
});
}
private
handleTextFieldType
=
(
ev
)
=>
{
if
(
ev
.
key
===
'
Enter
'
)
{
this
.
handleSubmit
();
ev
.
preventDefault
();
}
}
private
handleSubmit
=
()
=>
{
const
{
onSubmit
}
=
this
.
props
;
const
{
internalDate
}
=
this
.
state
;
if
(
internalDate
&&
onSubmit
)
{
onSubmit
(
internalDate
);
}
}
}
export
default
DateInput
;
src/model/kpi/ExecutionDetails.ts
View file @
4af2df33
import
Execution
from
'
model/kpi/Execution
'
;
import
ExecutionRun
from
'
model/kpi/ExecutionRun
'
;
import
Page
from
'
model/Page
'
;
/*
* Defined in Swagger as '#/definitions/ExecutionDetails'
*/
class
ExecutionDetails
{
public
execution
:
Execution
;
public
runs
:
ExecutionRun
[]
;
public
runs
:
Page
<
ExecutionRun
>
;
public
lastRun
:
ExecutionRun
;
}
...
...
src/service/genesys/KpiService.ts
View file @
4af2df33
...
...
@@ -18,6 +18,7 @@ const URL_LIST_EXECUTION = `/api/v1/kpi/executions`;
const
URL_SAVE_EXECUTION
=
`/api/v1/kpi/executions/save`
;
const
URL_EXECUTION_DETAILS
=
UrlTemplate
.
parse
(
`/api/v1/kpi/executions/{name}`
);
const
URL_DELETE_EXECUTION
=
UrlTemplate
.
parse
(
`/api/v1/kpi/executions/{name}`
);
const
URL_EXECUTION_RUN_BY_DATE
=
UrlTemplate
.
parse
(
`/api/v1/kpi/executions/{name}/run`
);
const
URL_RUN_EXECUTION
=
UrlTemplate
.
parse
(
`/api/v1/kpi/executions/{name}/execute`
);
const
URL_EXECUTION_RUNS
=
UrlTemplate
.
parse
(
`/api/v1/kpi/executions/{name}/runs`
);
const
URL_EXECUTION_RUN
=
UrlTemplate
.
parse
(
`/api/v1/kpi/executions/{name}/runs/{runId}`
);
...
...
@@ -108,6 +109,28 @@ class KpiService {
}).
then
(({
data
})
=>
data
as
Dimension
<
object
>
);
}
/**
* executionRunByDate at /api/v1/kpi/executions/{name}/run
*
* @param name name
* @param date date
*/
public
static
executionRunByDate
(
name
:
string
,
date
:
string
):
Promise
<
ExecutionRun
>
{
const
qs
=
QueryString
.
stringify
({
date
:
date
||
undefined
,
},
{});
const
apiUrl
=
URL_EXECUTION_RUN_BY_DATE
.
expand
({
name
})
+
(
qs
?
`?
${
qs
}
`
:
''
);
// console.log(`Fetching from ${apiUrl}`);
const
content
=
{
/* No content in request body */
};
return
axiosBackend
.
request
({
url
:
apiUrl
,
method
:
'
GET
'
,
...
content
,
}).
then
(({
data
})
=>
data
as
ExecutionRun
);
}
/**
* listExecutions at /api/v1/kpi/executions
*
...
...
@@ -210,7 +233,7 @@ class KpiService {
* @param name name
* @param page undefined
*/
public
static
executionRuns
(
name
:
string
,
page
?:
IPageRequest
):
Promise
<
ExecutionRun
[]
>
{
public
static
executionRuns
(
name
:
string
,
page
?:
IPageRequest
):
Promise
<
Page
<
ExecutionRun
>
>
{
const
qs
=
QueryString
.
stringify
({
p
:
page
.
page
||
undefined
,
...
...
@@ -226,7 +249,7 @@ class KpiService {
url
:
apiUrl
,
method
:
'
GET
'
,
...
content
,
}).
then
(({
data
})
=>
data
as
ExecutionRun
[]
);
}).
then
(({
data
})
=>
data
as
Page
<
ExecutionRun
>
);
}
/**
...
...
Write
Preview
Supports
Markdown
0%
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!
Cancel
Please
register
or
sign in
to comment