Skip to content

Commit

Permalink
feat: Provide Edit support in Sources tab for multi-source app (argop…
Browse files Browse the repository at this point in the history
…roj#17588)

Signed-off-by: Keith Chong <kykchong@redhat.com>
  • Loading branch information
keithchong committed Mar 21, 2024
1 parent 1c938e2 commit 11260d0
Show file tree
Hide file tree
Showing 10 changed files with 962 additions and 229 deletions.
@@ -0,0 +1,115 @@
import * as classNames from 'classnames';
import * as React from 'react';
import {FormApi} from 'react-form';
import { EditablePanelItem } from '../../../shared/components';
import { EditableSection } from '../../../shared/components/editable-panel/editable-section';
import { Consumer } from '../../../shared/context';
import '../../../shared/components/editable-panel/editable-panel.scss';

export interface ApplicationParametersPanelProps<T> {
floatingTitle?: string | React.ReactNode;
titleTop?: string | React.ReactNode;
titleBottom?: string | React.ReactNode;
index: number;
valuesTop?: T;
valuesBottom?: T;
validateTop?: (values: T) => any;
validateBottom?: (values: T) => any;
saveTop?: (input: T, query: {validate?: boolean}) => Promise<any>;
saveBottom?: (input: T, query: {validate?: boolean}) => Promise<any>;
itemsTop?: EditablePanelItem[];
itemsBottom?: EditablePanelItem[];
onModeSwitch?: () => any;
viewTop?: string | React.ReactNode;
viewBottom?: string | React.ReactNode;
editTop?: (formApi: FormApi) => React.ReactNode;
editBottom?: (formApi: FormApi) => React.ReactNode;
noReadonlyMode?: boolean;
collapsible?: boolean;
}

interface ApplicationParametersPanelState {
editTop: boolean;
editBottom: boolean;
savingTop: boolean;
savingBottom: boolean;
}

// Currently two editable sections, but can be modified to support N panels in general. This should be part of a white-box, editable-panel.
export class ApplicationParametersSource<T = {}> extends React.Component<ApplicationParametersPanelProps<T>, ApplicationParametersPanelState> {

constructor(props: ApplicationParametersPanelProps<T>) {
super(props);
this.state = {editTop: !!props.noReadonlyMode, editBottom: !!props.noReadonlyMode, savingTop: false, savingBottom: false};
}

public render() {
return (
<Consumer>
{ctx =>
<div className={classNames({'editable-panel--disabled': this.state.savingTop})}>
{this.props.floatingTitle && (
<div className="white-box--additional-top-space editable-panel__sticky-title">
{this.props.floatingTitle}
</div>
)}
<React.Fragment>
<EditableSection
uniqueId={'top_' + this.props.index}
title={this.props.titleTop}
view={this.props.viewTop}
values={this.props.valuesTop}
items={this.props.itemsTop}
validate={this.props.validateTop}
save={this.props.saveTop}
onModeSwitch={() => this.onModeSwitch()}
noReadonlyMode={this.props.noReadonlyMode}
edit={this.props.editTop}
collapsible={this.props.collapsible}
ctx={ctx}
isTopSection={true}
disabledState={this.state.editTop || this.state.editTop === null}
updateButtons={(editClicked) => {
this.setState({editBottom: editClicked})
}}/>
</React.Fragment>
{this.props.itemsTop && (
<React.Fragment>
<div className='row white-box__details-row'>
<p>&nbsp;</p>
</div>
<div className='white-box--no-padding editable-panel__divider'></div>
</React.Fragment>
)}
<React.Fragment>
<EditableSection
uniqueId={'bottom_' + this.props.index}
title={this.props.titleBottom}
view={this.props.viewBottom}
values={this.props.valuesBottom}
items={this.props.itemsBottom}
validate={this.props.validateBottom}
save={this.props.saveBottom}
onModeSwitch={() => this.onModeSwitch()}
noReadonlyMode={this.props.noReadonlyMode}
edit={this.props.editBottom}
collapsible={this.props.collapsible}
ctx={ctx}
isTopSection={false}
disabledState={this.state.editBottom || this.state.editBottom === null}
updateButtons={(editClicked) => {
this.setState({editTop: editClicked});
}}/>
</React.Fragment>
</div>
}
</Consumer>
);
}

private onModeSwitch() {
if (this.props.onModeSwitch) {
this.props.onModeSwitch();
}
}
}
@@ -0,0 +1,80 @@
@import 'node_modules/argo-ui/src/styles/config';
@import 'node_modules/argo-ui/src/styles/theme';

.application-parameters {
&__labels {
line-height: 28px;
display: flex;
align-items: center;
height: 100%;
flex-wrap: wrap;
padding-top: 0.5em;
}

&__label {
background-color: $argo-color-gray-5;
color: white;
border-radius: 5px;
padding: 4px;
line-height: 14px;
margin: 0.3em 0;
margin-right: 2px;
}

&__sort-icon {
cursor: pointer;
position: absolute;
font-size: 1.3em;
left: -1em;

&.fa-sort-up {
top: 10px;
}

&.fa-sort-down {
bottom: 10px;
}
}
&__remove-icon {
cursor: pointer;
position: absolute;
top: 1em;
right: 1em;
}

.argo-field {
line-height: 1.15;
}

.white-box__details p {
font-weight: 500;
@include themify($themes) {
color: themed('text-1');
}
}

.white-box__details-row .row {
padding-left: 1em;
padding-right: 1em;
}

.white-box__details-row .row .columns:last-child {
padding-left: 1em;
}

.select {
padding-bottom: 0;
}

.row.application-retry-options {
.columns.application-retry-options__item{
padding-left: 0;
padding-right: 10px;
}

.argo-form-row__error-msg {
position: static;
line-height: 1;
}
}
}

0 comments on commit 11260d0

Please sign in to comment.