Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PXP-8520 Feat/paymodels #900

Merged
merged 16 commits into from
Nov 3, 2021
6 changes: 5 additions & 1 deletion src/Workspace/Workspace.less
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ div.workspace--fullpage {
width: 100%;
}

.workspace__pay-model {
margin: 20px 0 10px 0;
}

.workspace__options {
padding: 20px 20px;
padding: 0 20px 20px 20px;
display: flex;
flex-flow: wrap;
}
Expand Down
80 changes: 77 additions & 3 deletions src/Workspace/index.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import parse from 'html-react-parser';
import Button from '@gen3/ui-component/dist/components/Button';
import { datadogRum } from '@datadog/browser-rum';
import {
Alert, Popconfirm, Steps, message,
Popconfirm, Steps, Collapse, Row, Col, Statistic, Alert, message,
} from 'antd';
import { datadogRum } from '@datadog/browser-rum';

import {
workspaceUrl,
Expand All @@ -14,6 +14,7 @@ import {
workspaceLaunchUrl,
workspaceTerminateUrl,
workspaceStatusUrl,
workspacePayModelUrl,
workspacePageTitle,
workspacePageDescription,
} from '../localconf';
Expand All @@ -33,6 +34,8 @@ import sessionMonitor from '../SessionMonitor';
import workspaceSessionMonitor from './WorkspaceSessionMonitor';

const { Step } = Steps;
const { Panel } = Collapse;

class Workspace extends React.Component {
constructor(props) {
super(props);
Expand All @@ -42,10 +45,12 @@ class Workspace extends React.Component {
workspaceStatus: null,
workspaceLaunchStepsConfig: null,
interval: null,
payModelInterval: null,
workspaceID: null,
defaultWorkspace: false,
workspaceIsFullpage: false,
externalLoginOptions: [],
payModel: {},
};
this.workspaceStates = [
'Not Found',
Expand Down Expand Up @@ -76,6 +81,9 @@ class Workspace extends React.Component {
if (this.state.interval) {
clearInterval(this.state.interval);
}
if (this.state.payModelInterval) {
clearInterval(this.state.payModelInterval);
}
}

oniframeLoad = (e) => {
Expand Down Expand Up @@ -143,6 +151,20 @@ class Workspace extends React.Component {
return workspaceStatus;
}

getWorkspacePayModels = async () => fetchWithCreds({
path: `${workspacePayModelUrl}`,
method: 'GET',
}).then(
({ status, data }) => {
// check if is valid pay model data
// older hatchery will also return 200 for /paymodels with workspace options in it
if (status === 200 && data.aws_account_id) {
return data;
}
return {};
},
).catch(() => 'Error');

getIcon = (workspace) => {
if (this.regIcon(workspace, 'R Studio') || this.regIcon(workspace, 'RStudio')) {
return rStudioIcon;
Expand Down Expand Up @@ -301,6 +323,12 @@ class Workspace extends React.Component {
connected = () => {
this.getWorkspaceOptions();
this.getExternalLoginOptions();
this.getWorkspacePayModels().then((data) => {
this.checkWorkspacePayModel();
this.setState({
payModel: data,
});
});
if (!this.state.defaultWorkspace) {
this.getWorkspaceStatus().then((data) => {
if (data.status === 'Launching' || data.status === 'Terminating' || data.status === 'Stopped') {
Expand Down Expand Up @@ -350,6 +378,23 @@ class Workspace extends React.Component {
}
}

checkWorkspacePayModel = async () => {
if (this.state.payModelInterval) {
clearInterval(this.state.payModelInterval);
}
try {
const payModelInterval = setInterval(async () => {
const data = await this.getWorkspacePayModels();
this.setState({
payModel: data,
});
}, 30000);
this.setState({ payModelInterval });
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkWorkspacePayModel doesn't really need to be a periodical job for now

but it will be needed once we really stores and fetches the value of cost from DB

} catch (e) {
console.log('Error checking workspace status:', e);
}
}

handleTerminateButtonClick = () => {
// exit full page
this.setState({ workspaceIsFullpage: false });
Expand Down Expand Up @@ -405,10 +450,39 @@ class Workspace extends React.Component {
// NOTE both the containing element and the iframe have class '.workspace',
// although no styles should be shared between them. The reason for this
// is for backwards compatibility with Jenkins integration tests that select by classname.
const showExternalLoginsHintBanner = this.state.externalLoginOptions.length > 0
&& this.state.externalLoginOptions.some((option) => !option.refresh_token_expiration);
return (
<div
className={`workspace ${this.state.workspaceIsFullpage ? 'workspace--fullpage' : ''}`}
>
{
(Object.keys(this.state.payModel).length > 0) ? (
<Collapse className='workspace__pay-model' onClick={(event) => event.stopPropagation()}>
<Panel header='User Pay Model Information' key='1'>
<Row gutter={{
xs: 8, sm: 16, md: 24, lg: 32,
}}
>
<Col className='gutter-row' span={8}>
<Statistic title='Pay Model Name' value={this.state.payModel.name || 'N/A'} />
</Col>
<Col className='gutter-row' span={8}>
<Statistic title='AWS Account ID' groupSeparator='' value={this.state.payModel.aws_account_id || 'N/A'} />
</Col>
<Col className='gutter-row' span={8}>
<Statistic title='AWS Account Region' value={this.state.payModel.region || 'N/A'} />
</Col>
{/* Total Charges column will be added back later */}
{/* <Col className='gutter-row' span={6}>
<Statistic title='Total Charges (USD)' value={this.state.payModel.cost || 'N/A'} precision={2} />
</Col> */}
</Row>
</Panel>
</Collapse>
)
: null
}
{
this.state.workspaceStatus === 'Running'
? (
Expand Down Expand Up @@ -502,7 +576,7 @@ class Workspace extends React.Component {
</div>
)
: null}
{this.state.externalLoginOptions.length > 0
{showExternalLoginsHintBanner
? (
<Alert
description={
Expand Down
6 changes: 3 additions & 3 deletions src/img/icons/bar-chart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/localconf.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ function buildConfig(opts) {
const workspaceErrorUrl = '/no-workspace-access/';
const workspaceOptionsUrl = `${workspaceUrl}options`;
const workspaceStatusUrl = `${workspaceUrl}status`;
const workspacePayModelUrl = `${workspaceUrl}paymodels`;
const workspaceTerminateUrl = `${workspaceUrl}terminate`;
const workspaceLaunchUrl = `${workspaceUrl}launch`;
const datasetUrl = `${hostname}api/search/datasets`;
Expand Down Expand Up @@ -449,6 +450,7 @@ function buildConfig(opts) {
workspaceErrorUrl,
workspaceOptionsUrl,
workspaceStatusUrl,
workspacePayModelUrl,
workspaceLaunchUrl,
workspaceTerminateUrl,
homepageChartNodes: components.index.homepageChartNodes,
Expand Down