Skip to content

Commit d0ffb89

Browse files
Merge pull request #114 from NessieCanCode/rename-summary-and-details-tabs-and-add-year-in-review
feat: add annual review view and rename navigation tabs
2 parents 55c0ab1 + fe96051 commit d0ffb89

File tree

1 file changed

+66
-15
lines changed

1 file changed

+66
-15
lines changed

src/slurmcostmanager.js

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,35 @@ function getBillingPeriod(ref = new Date()) {
3434
};
3535
}
3636

37-
function useBillingData(month) {
37+
function getYearPeriod(year = new Date().getFullYear()) {
38+
const today = new Date();
39+
const end =
40+
year === today.getFullYear()
41+
? new Date(Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()))
42+
: new Date(Date.UTC(year, 11, 31));
43+
const start = new Date(Date.UTC(year, 0, 1));
44+
return {
45+
start: start.toISOString().slice(0, 10),
46+
end: end.toISOString().slice(0, 10)
47+
};
48+
}
49+
50+
function useBillingData(period) {
3851
const [data, setData] = useState(null);
3952
const [error, setError] = useState(null);
4053

4154
const load = useCallback(async () => {
4255
try {
4356
let json;
4457
if (window.cockpit && window.cockpit.spawn) {
45-
const { start, end } = getBillingPeriod(month);
58+
let start, end;
59+
if (typeof period === 'string') {
60+
({ start, end } = getBillingPeriod(period));
61+
} else if (period && period.start && period.end) {
62+
({ start, end } = period);
63+
} else {
64+
({ start, end } = getBillingPeriod());
65+
}
4666
const args = [
4767
'python3',
4868
`${PLUGIN_BASE}/slurmdb.py`,
@@ -66,7 +86,7 @@ function useBillingData(month) {
6686
console.error(e);
6787
setError(e.message || String(e));
6888
}
69-
}, [month]);
89+
}, [period]);
7090

7191
useEffect(() => {
7292
load();
@@ -761,13 +781,17 @@ function Details({
761781
React.createElement(
762782
'div',
763783
{ className: 'filter-bar' },
764-
React.createElement(
765-
'select',
766-
{ value: month, onChange: e => onMonthChange(e.target.value) },
767-
monthOptions.map(m =>
768-
React.createElement('option', { key: m, value: m }, m)
769-
)
770-
),
784+
monthOptions.length > 0 &&
785+
React.createElement(
786+
'select',
787+
{
788+
value: month,
789+
onChange: e => onMonthChange && onMonthChange(e.target.value)
790+
},
791+
monthOptions.map(m =>
792+
React.createElement('option', { key: m, value: m }, m)
793+
)
794+
),
771795
['Partition', 'Account', 'User'].map(name => {
772796
const opts =
773797
name === 'Partition' ? partitions : name === 'Account' ? accounts : users;
@@ -1112,14 +1136,16 @@ function Rates({ onRatesUpdated }) {
11121136
}
11131137

11141138
function App() {
1115-
const [view, setView] = useState('summary');
1139+
const [view, setView] = useState('year');
11161140
const now = new Date();
11171141
const defaultMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(
11181142
2,
11191143
'0'
11201144
)}`;
11211145
const [month, setMonth] = useState(defaultMonth);
1122-
const { data, error, reload } = useBillingData(month);
1146+
const yearPeriod = getYearPeriod(now.getFullYear());
1147+
const period = view === 'year' ? yearPeriod : month;
1148+
const { data, error, reload } = useBillingData(period);
11231149
const [showErrorDetails, setShowErrorDetails] = useState(false);
11241150
const monthOptions = Array.from(
11251151
{ length: now.getMonth() + 1 },
@@ -1132,20 +1158,25 @@ function App() {
11321158
React.createElement(
11331159
'nav',
11341160
null,
1161+
React.createElement(
1162+
'button',
1163+
{ onClick: () => setView('year') },
1164+
'Fiscal Year Overview'
1165+
),
11351166
React.createElement(
11361167
'button',
11371168
{ onClick: () => setView('summary') },
1138-
'Summary'
1169+
'Monthly Summary Reports'
11391170
),
11401171
React.createElement(
11411172
'button',
11421173
{ onClick: () => setView('details') },
1143-
'Details'
1174+
'Detailed Transactions'
11441175
),
11451176
React.createElement(
11461177
'button',
11471178
{ onClick: () => setView('settings') },
1148-
'Settings'
1179+
'Administration'
11491180
)
11501181
),
11511182
view === 'summary' &&
@@ -1190,6 +1221,26 @@ function App() {
11901221
showErrorDetails &&
11911222
React.createElement('pre', { className: 'error-details' }, error)
11921223
),
1224+
data &&
1225+
view === 'year' &&
1226+
React.createElement(
1227+
React.Fragment,
1228+
null,
1229+
React.createElement(Summary, {
1230+
summary: data.summary,
1231+
details: data.details,
1232+
daily: data.daily,
1233+
monthly: data.monthly
1234+
}),
1235+
React.createElement(Details, {
1236+
details: data.details,
1237+
daily: data.daily,
1238+
partitions: data.partitions,
1239+
accounts: data.accounts,
1240+
users: data.users,
1241+
monthOptions: []
1242+
})
1243+
),
11931244
data &&
11941245
view === 'summary' &&
11951246
React.createElement(Summary, {

0 commit comments

Comments
 (0)