Skip to content

Commit 93f0f51

Browse files
committed
Merge branch 'master' into renovate/lumino-widgets-2.x
2 parents 36ab8b0 + ab43773 commit 93f0f51

27 files changed

+1424
-311
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module.exports = {
3737
objects: 'only-multiline',
3838
imports: 'only-multiline',
3939
exports: 'only-multiline',
40-
functions: 'never',
40+
functions: 'only-multiline',
4141
},
4242
],
4343
'template-curly-spacing': [

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ Renovate Bot[bot] <[email protected]>
2121
github-actions[bot] <[email protected]> <41898282+github-actions[bot]@users.noreply.github.com>
2222
2323
Aaron Cole <[email protected]>
24+
Jamie Allen <[email protected]> JAllen42 <[email protected]>

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ log file subscription.
3131
[#1187](https://github.com/cylc/cylc-ui/pull/1187) - Improved the workflow
3232
filtering menu in the sidebar.
3333

34+
[#1254](https://github.com/cylc/cylc-ui/pull/1254) - Add analysis view:
35+
A new view that displays task timing statistics
36+
3437
### Fixes
3538

3639
[#1249](https://github.com/cylc/cylc-ui/pull/1249) - Fix tasks not loading

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ below.
5757
- Carol Barno
5858
- Giuliano Serrao
5959
- Aaron Cole
60+
- Jamie Allen
6061
<!-- end-shortlog -->
6162

6263
(All contributors are identifiable with email addresses in the git version

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"dependencies": {
2424
"@apollo/client": "^3.5.8",
2525
"@hpcc-js/wasm": "^2.8.0",
26-
"@lumino/default-theme": "^0.22.0",
26+
"@lumino/default-theme": "^2.0.0",
2727
"@lumino/widgets": "^2.0.0",
2828
"@unhead/vue": "^1.1.17",
2929
"axios": "^1.0.0",
@@ -50,7 +50,7 @@
5050
"@cypress/code-coverage": "^3.9.12",
5151
"@mdi/js": "^7.0.0",
5252
"@vitejs/plugin-vue": "^4.0.0",
53-
"@vitest/coverage-istanbul": "^0.31.0",
53+
"@vitest/coverage-istanbul": "^0.32.0",
5454
"@vue/test-utils": "^2.0.0",
5555
"bufferutil": "^4.0.6",
5656
"concurrently": "^8.0.0",
@@ -74,7 +74,7 @@
7474
"json-server": "^0.17.0",
7575
"nodemon": "^2.0.19",
7676
"nyc": "^15.1.0",
77-
"sass": "~1.62.0",
77+
"sass": "~1.63.0",
7878
"sinon": "^15.0.0",
7979
"standard": "^17.0.0",
8080
"subscriptions-transport-ws": "^0.11.0",
@@ -83,7 +83,7 @@
8383
"vite-plugin-eslint": "^1.8.1",
8484
"vite-plugin-istanbul": "^4.0.1",
8585
"vite-plugin-vuetify": "^1.0.2",
86-
"vitest": "^0.31.0"
86+
"vitest": "^0.32.0"
8787
},
8888
"bugs": {
8989
"url": "https://github.com/cylc/cylc-ui/issues"
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<!--
2+
Copyright (C) NIWA & British Crown (Met Office) & Contributors.
3+
4+
This program is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
This program is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
-->
17+
18+
<template>
19+
<v-row
20+
no-gutters
21+
class="c-table flex-grow-1 position-relative"
22+
>
23+
<v-col
24+
cols="12"
25+
class="mh-100 position-relative"
26+
>
27+
<v-container
28+
fluid
29+
class="pa-0"
30+
>
31+
<v-data-table
32+
:headers="shownHeaders"
33+
:items="tasks"
34+
:sort-by="sortBy"
35+
density="compact"
36+
v-model:items-per-page="itemsPerPage"
37+
>
38+
<!-- Use custom format for values in columns that have a specified formatter: -->
39+
<!-- Used to make durations human readable -->
40+
<!-- Durations of 0 will be undefined unless allowZeros is true -->
41+
<template
42+
v-for="header in shownHeaders"
43+
v-slot:[`item.${header.key}`]="{ item }"
44+
>
45+
{{ formatCell(item, header) }}
46+
</template>
47+
<template v-slot:bottom>
48+
<v-data-table-footer :itemsPerPageOptions="$options.itemsPerPageOptions" />
49+
</template>
50+
</v-data-table>
51+
</v-container>
52+
</v-col>
53+
</v-row>
54+
</template>
55+
56+
<script>
57+
import { formatDuration } from '@/utils/tasks'
58+
59+
export default {
60+
name: 'AnalysisTableComponent',
61+
62+
props: {
63+
tasks: {
64+
type: Array,
65+
required: true
66+
},
67+
timingOption: {
68+
type: String,
69+
required: true
70+
}
71+
},
72+
73+
data () {
74+
return {
75+
itemsPerPage: 50,
76+
sortBy: [
77+
{ key: 'name', order: 'asc' }
78+
],
79+
headers: [
80+
{
81+
title: 'Task',
82+
key: 'name'
83+
},
84+
{
85+
title: 'Platform',
86+
key: 'platform'
87+
},
88+
{
89+
title: 'Count',
90+
key: 'count'
91+
}
92+
]
93+
}
94+
},
95+
96+
computed: {
97+
shownHeaders () {
98+
let times
99+
if (this.timingOption === 'totalTimes') {
100+
times = 'Total'
101+
} else if (this.timingOption === 'runTimes') {
102+
times = 'Run'
103+
} else if (this.timingOption === 'queueTimes') {
104+
times = 'Queue'
105+
} else {
106+
return this.headers
107+
}
108+
const timingHeaders = [
109+
{
110+
title: `Mean T-${times}`,
111+
key: `mean${times}Time`,
112+
formatter: formatDuration,
113+
allowZeros: false
114+
},
115+
{
116+
title: `Std Dev T-${times}`,
117+
key: `stdDev${times}Time`,
118+
formatter: formatDuration,
119+
allowZeros: true
120+
},
121+
{
122+
title: `Min T-${times}`,
123+
key: `min${times}Time`,
124+
formatter: formatDuration,
125+
allowZeros: false
126+
},
127+
{
128+
title: `Q1 T-${times}`,
129+
key: `${times.toLowerCase()}Quartiles.0`,
130+
formatter: formatDuration,
131+
allowZeros: false
132+
},
133+
{
134+
title: `Median T-${times}`,
135+
key: `${times.toLowerCase()}Quartiles.1`,
136+
formatter: formatDuration,
137+
allowZeros: false
138+
},
139+
{
140+
title: `Q3 T-${times}`,
141+
key: `${times.toLowerCase()}Quartiles.2`,
142+
formatter: formatDuration,
143+
allowZeros: false
144+
},
145+
{
146+
title: `Max T-${times}`,
147+
key: `max${times}Time`,
148+
formatter: formatDuration,
149+
allowZeros: false
150+
}
151+
]
152+
return this.headers.concat(timingHeaders)
153+
}
154+
},
155+
156+
methods: {
157+
formatCell (item, header) {
158+
const arrayMatch = header.key.match(/^(.+)\.(\d+)$/)
159+
const key = arrayMatch?.[1] ?? header.key
160+
let value = item.value[key]
161+
if (arrayMatch) {
162+
const index = arrayMatch[2]
163+
value = value[index]
164+
}
165+
if (header.formatter) {
166+
return header.formatter(value, header.allowZeros)
167+
}
168+
return value
169+
}
170+
},
171+
172+
itemsPerPageOptions: [
173+
{ value: 10, title: '10' },
174+
{ value: 20, title: '20' },
175+
{ value: 50, title: '50' },
176+
{ value: 100, title: '100' },
177+
{ value: 200, title: '200' },
178+
{ value: -1, title: 'All' }
179+
],
180+
}
181+
</script>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
/**
19+
* Function to determine if a task should be displayed given a certain filter
20+
* Checks the name includes a search string and if the platform is equal to
21+
* that chosen
22+
*
23+
* @export
24+
* @param {object} task - The task to evaluate
25+
* @param {object} tasksFilter - The filter to apply to the task
26+
* @return {boolean} Boolean determining if task should be displayed
27+
*/
28+
export function matchTask (task, tasksFilter) {
29+
let ret = true
30+
if (tasksFilter.name?.trim()) {
31+
ret &&= task.name.includes(tasksFilter.name)
32+
}
33+
if (tasksFilter.platformOption.trim?.()) {
34+
ret &&= task.platform === tasksFilter.platformOption
35+
}
36+
return ret
37+
}
38+
39+
/**
40+
* Function to find the unique platforms in an array of tasks
41+
*
42+
* @export
43+
* @param {array} tasks - The tasks to search for unique platforms
44+
* @return {array} - An array of unique platform objects
45+
*/
46+
export function platformOptions (tasks) {
47+
const platformOptions = [{ value: -1, title: 'All' }]
48+
const platforms = []
49+
for (const task of tasks) {
50+
if (!platforms.includes(task.platform)) {
51+
platforms.push(task.platform)
52+
platformOptions.push({ value: task.platform, title: task.platform })
53+
}
54+
}
55+
return platformOptions
56+
}

0 commit comments

Comments
 (0)