Skip to content

Commit

Permalink
Changed column order in status view and improved UI of approval dialog (
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusoe authored Aug 5, 2020
1 parent f12f338 commit 91b3d80
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import PromotionApprovalDialog from './dialogs/PromotionApprovalDialog';
import axios from '../../../lib/axios-api';
import PromotionConflictDialog from './dialogs/PromotionConflictDialog';
import _ from 'lodash';
import { ProgressSpinner } from 'primereact/progressspinner';

/**
* The view for displaying existing promotion files including their modifications.
Expand Down Expand Up @@ -123,11 +124,15 @@ const PromotionView = () => {
.selection-information {
display: flex;
flex-grow: 1;
flex-direction: column;
height: 100%;
align-items: center;
justify-content: center;
color: #bbb;
}
.selection-information > span {
margin-bottom: 1rem;
}
`}
</style>

Expand Down Expand Up @@ -182,6 +187,13 @@ const PromotionView = () => {
)}
</div>
</>
) : isLoading ? (
<>
<div className="selection-information">
<span>Loading promotion files...</span>
<ProgressSpinner />
</div>
</>
) : (
<>
<div className="selection-information">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,93 +1,104 @@
import React from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { Dialog } from 'primereact/dialog';
import { Button } from 'primereact/button';
import { ProgressBar } from 'primereact/progressbar';
import { InputText } from 'primereact/inputtext';
import _ from 'lodash';

/**
* Dialog for showing the currently approved files before promoting them.
*/
class PromotionApprovalDialog extends React.Component {
state = {
/** The promotion message to be send to the backend. */
promotionMessage: '',
};
input = React.createRef();
render() {
const { visible, onHide, isLoading, approvedFiles = [] } = this.props;
const { promotionMessage } = this.state;
const footer = (
<div>
<Button label="Promote" onClick={this.promote} disabled={isLoading || !promotionMessage} />
<Button label="Cancel" className="p-button-secondary" onClick={onHide} disabled={isLoading} />
</div>
);

return (
<>
<style jsx>
{`
.list li {
font-family: monospace;
}
const PromotionApprovalDialog = ({ visible, onHide, onPromote, isLoading, approvedFiles = [] }) => {
// state variables
const [message, setMessage] = useState('');

.content :global(.p-progressbar) {
height: 0.5rem;
}
`}
</style>
// ref variables
const messageInput = useRef(null);

<Dialog
header="Promote Configurations"
focusOnShow={false}
visible={visible}
style={{ width: '50vw' }}
modal={true}
onHide={onHide}
footer={footer}
>
<div className="content">
<span>The following files have been approved and will be promoted:</span>
<ul className="list">
{approvedFiles.map((file) => (
<li key={file}>{file}</li>
))}
</ul>
// derived variables
const isValidMessage = !_.isEmpty(message);

{isLoading && <ProgressBar mode="indeterminate" />}
</div>
<InputText
ref={this.input}
style={{ width: '100%' }}
placeholder="Describe change..."
onKeyPress={this.onKeyPress}
value={promotionMessage}
onChange={(e) => this.setState({ promotionMessage: e.target.value })}
/>
</Dialog>
</>
);
}

componentDidUpdate(prevProps) {
if (!prevProps.visible && this.props.visible) {
/**Timeout is needed for .focus() to be triggered correctly. */
setTimeout(() => {
this.input.current.element.focus();
}, 0);
this.setState({ promotionMessage: '' });
// clear message when dialog gets visible
useEffect(() => {
if (visible) {
setMessage('');
}
}
}, [visible]);

// invoke the promotion
const promote = () => onPromote(message);

onKeyPress = (e) => {
if (e.key === 'Enter' && !this.props.isLoading && this.state.promotionMessage) {
this.promote();
// promote when enter is pressed
const onKeyPress = (event) => {
if (event.key === 'Enter' && !isLoading && isValidMessage) {
promote();
}
};

promote = () => {
this.props.onPromote(this.state.promotionMessage);
// set the focus to the input field after the dialog is shown
const onShow = () => {
messageInput.current.element.focus();
};
}

const footer = (
<div>
<Button label="Promote" onClick={promote} disabled={isLoading || !isValidMessage} />
<Button label="Cancel" className="p-button-secondary" onClick={onHide} disabled={isLoading} />
</div>
);

return (
<>
<style jsx>
{`
.list li {
font-family: monospace;
}
.content :global(.p-progressbar) {
height: 0.5rem;
}
.content :global(.message-input) {
width: 100%;
margin: 0.5rem 0 1rem;
}
`}
</style>

<Dialog
header="Promote Configurations"
focusOnShow={false}
visible={visible}
style={{ width: '50vw' }}
modal={true}
onHide={onHide}
onShow={onShow}
footer={footer}
>
<div className="content">
<span>The following files have been approved and will be promoted:</span>
<ul className="list">
{approvedFiles.map((file) => (
<li key={file}>{file}</li>
))}
</ul>

<span>Please add a message to describe the configuration promotion:</span>

<InputText
ref={messageInput}
className="message-input"
placeholder="Promotion message..."
onKeyPress={onKeyPress}
value={message}
onChange={(e) => setMessage(e.target.value)}
disabled={isLoading}
/>

{isLoading && <ProgressBar mode="indeterminate" />}
</div>
</Dialog>
</>
);
};

export default PromotionApprovalDialog;
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ class StatusTable extends React.Component {
sortable
style={{ width: '175px' }}
/>
<Column header="Agent Mapping" field="mappingFilter" body={this.agentMappingTemplate} sortable />
<Column header="Source Branch" field="sourceBranch" body={this.sourceBranchTemplate} style={{ width: '150px' }} sortable />
<Column header="Agent Mapping" field="mappingFilter" body={this.agentMappingTemplate} sortable />
<Column header="Last Fetch" field="lastConfigFetch" body={this.lastFetchTemplate} sortable style={{ width: '200px' }} />
</DataTable>

Expand Down

0 comments on commit 91b3d80

Please sign in to comment.