Skip to content
This repository has been archived by the owner on Jun 6, 2024. It is now read-only.

Commit

Permalink
Binyli/job submit (#2867)
Browse files Browse the repository at this point in the history
The init version of job submission.
This version contains:
most widgets for Job submission

The features not finished:
css styles
Data  widgets
Call job submission api to finish to submit job
  • Loading branch information
Binyang2014 authored Jun 5, 2019
1 parent de73f65 commit 9b2f3de
Show file tree
Hide file tree
Showing 32 changed files with 1,916 additions and 355 deletions.
1 change: 1 addition & 0 deletions src/webportal/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = {
"src/app/components/**/*.js",
"src/app/home/**/*.js",
"src/app/user/fabric/**/*.js",
"src/plugins/job-submission/**/*.js",
],
"parser": "babel-eslint"
}
Expand Down
1 change: 1 addition & 0 deletions src/webportal/config/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const config = (env, argv) => ({
'k8s': './src/app/cluster-view/k8s/k8s.component.js',
'docs': './src/app/job/job-docs/job-docs.component.js',
'plugin': './src/app/plugin/plugin.component.js',
'plugins/jobsubmission': './src/plugins/job-submission',
},
output: {
path: helpers.root('dist'),
Expand Down
3 changes: 3 additions & 0 deletions src/webportal/config/webportal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

server-port: 9286
plugins:
- title: JobSubmission
uri: /scripts/plugins/jobsubmission.bundle.js
4 changes: 3 additions & 1 deletion src/webportal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"@babel/core": "^7.4.3",
"@babel/preset-env": "^7.4.3",
"@babel/preset-react": "^7.0.0",
"@uifabric/fluent-theme": "^0.16.9",
"@uifabric/merge-styles": "^6.17.4",
"@webcomponents/custom-elements": "^1.2.1",
"admin-lte": "~2.4.2",
"app-root-path": "~2.0.1",
Expand Down Expand Up @@ -74,7 +76,7 @@
"monaco-editor": "~0.16.1",
"monaco-editor-webpack-plugin": "^1.7.0",
"morgan": "~1.9.0",
"node-sass": "~4.7.2",
"node-sass": "^4.12.0",
"office-ui-fabric-react": "^6.143.0",
"papaparse": "^4.6.3",
"postcss-import": "^12.0.1",
Expand Down
94 changes: 94 additions & 0 deletions src/webportal/src/plugins/job-submission/components/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import React from 'react';
import {Fabric, Stack, DefaultButton, PrimaryButton} from 'office-ui-fabric-react';
import {TabForm} from './TabForm';
import {initializeIcons} from '@uifabric/icons';
import {TabFormContent} from './TabFormContent';
import {JobTaskRole} from '../models/jobTaskRole';
import {JobInformation} from './JobInformation';
import {Parameter} from './Parameter';
import {getFormClassNames} from './formStyle';
import {initTheme} from '../../../app/components/theme';

initTheme();
initializeIcons();

export class App extends React.Component {
constructor(props) {
super(props);

const items = [{headerText: 'Task role 1', content: new JobTaskRole({})}];
this.state = {
items: items,
};
}

_onRenderTabContent(keyName, content, defaultOnContentChange) {
return (
<TabFormContent key={keyName} defaultValue={content} onContentChange={defaultOnContentChange}/>
);
}

render() {
const {items} = this.state;
const formLayout = getFormClassNames().formLayout;
const topForm = getFormClassNames().topForm;

return (
<Fabric>
<Stack className={formLayout}>
<Stack horizontal gap='l2'>
<Stack styles={{root: {width: '70%'}}} gap='l2'>
<Stack className={topForm}>
<JobInformation />
</Stack>
<Stack className={topForm} gap='l1'>
<Stack>
<TabForm defaultItems={items}
headerTextPrefix='Task Role'
createContentFunc={() => new JobTaskRole({})}
onRenderTabContent={this._onRenderTabContent.bind(this)}
onItemsChange={(items)=>this.setState({items: items})}/>
</Stack>
<Stack horizontal gap='s1' horizontalAlign='center'>
<PrimaryButton>Submit</PrimaryButton>
<DefaultButton>Edit YAML</DefaultButton>
<DefaultButton>Export</DefaultButton>
</Stack>
</Stack>
</Stack>
<Stack styles={{root: {width: '30%'}}}>
<Stack className={topForm}>
<Parameter/>
</Stack>
</Stack>
</Stack>
</Stack>
</Fabric>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import React, {useState} from 'react';
import {getId, Label, Stack, Text, Icon} from 'office-ui-fabric-react';
import {FormSection} from './FormPage';
import {getFormPageSytle, getFormBasicSectionStyle} from './formStyle';
import PropTypes from 'prop-types';

const formPageStyle = getFormPageSytle();

export const BasicSection = (props) => {
const {sectionLabel, sectionOptional, children} = props;
const textFieldId = getId('textField');
const basicSectionStyle = getFormBasicSectionStyle(sectionOptional);

const [isSectionOn, setSectionOn] = useState(false);
const [iconName, setIconName] = useState('CaretSolidRight');
const onOpenItem = () => {
if (isSectionOn) {
setIconName('CaretSolidRight');
} else {
setIconName('CaretDown8');
}
setSectionOn(!isSectionOn);
};

return (
<FormSection>
<Stack styles={formPageStyle.formFirstColumn}>
<Stack horizontal gap='s2'>
<Icon iconName={iconName} styles={basicSectionStyle.icon} onClick={onOpenItem}/>
<Label htmlFor={textFieldId} styles={basicSectionStyle.label}>{sectionLabel}</Label>
{ sectionOptional && <Text styles={basicSectionStyle.optionalText}>Optional</Text>}
</Stack>
</Stack>
<Stack styles={formPageStyle.formSecondColunm}>
<Stack gap='m'>
{(!sectionOptional || isSectionOn) && children}
</Stack>
</Stack>
</FormSection>
);
};

BasicSection.propTypes = {
sectionLabel: PropTypes.string.isRequired,
children: PropTypes.node,
sectionOptional: PropTypes.bool,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import React, {useState} from 'react';
import {Stack} from 'office-ui-fabric-react';
import PropTypes from 'prop-types';
import {BasicSection} from './BasicSection';
import {Completion} from '../models/completion';
import {CSpinButton} from './CustomizedComponents';

export const CompletionSection= (props) => {
const {onChange, defaultValue} = props;
const [value, setValue] = useState(defaultValue);
const {minFailedInstances, minSuceedInstances} = value;

const _onChange = (keyName, newValue) => {
const completion = new Completion(value);
completion[keyName] = newValue;
if (onChange !== undefined) {
onChange(completion);
}
setValue(completion);
};

return (
<BasicSection sectionLabel={'Completion'} sectionOptional>
<Stack horizontal gap='s1'>
<CSpinButton label={'Min Failed Instances'}
value={minFailedInstances}
onChange={(v) => _onChange('minFailedInstances', v)}/>
</Stack>
<Stack horizontal gap='s1'>
<CSpinButton label={'Min Succeed Instances'}
value={minSuceedInstances}
onChange={(v) => _onChange('minSuceedInstances', v)}/>
</Stack>
</BasicSection>
);
};

CompletionSection.propTypes = {
defaultValue: PropTypes.instanceOf(Completion).isRequired,
onChange: PropTypes.func,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import React, {useState} from 'react';
import {getTheme, Toggle, Stack} from 'office-ui-fabric-react';
import PropTypes from 'prop-types';
import {BasicSection} from './BasicSection';
import {ContainerSize} from '../models/containerSize';
import {CSpinButton} from './CustomizedComponents';

const {spacing} = getTheme();

export const ContainerSizeSection = (props) => {
const {defaultValue, onChange, isContainerSizeEnabled, onEnable} = props;
const [value, setValue] = useState(defaultValue);
const {cpu, memoryMB, gpu, shmMB} = value;

const _onChange = (keyName, newValue) => {
const containerSize = new ContainerSize(value);
containerSize[keyName] = newValue;
if (onChange !== undefined) {
onChange(containerSize);
}
setValue(containerSize);
};

const _onEnable = (_, checked) => {
if (onEnable === undefined) {
return;
}
onEnable(checked);
};

return (
<BasicSection sectionLabel={'ContainerSize'}>
<Stack horizontal>
<CSpinButton label={'GPU count'}
value={gpu}
onChange={(value)=>_onChange('gpu', value)}/>
<Toggle checked={isContainerSizeEnabled}
label='Custom'
inlineLabel={true}
styles={{label: {order: -1, marginRight: spacing.s2}}}
onChange={_onEnable}/>
</Stack>
<CSpinButton label={'CPU count'}
disabled={!isContainerSizeEnabled}
value={cpu}
onChange={(value)=>_onChange('cpu', value)}/>
<CSpinButton label={'Memory (MB)'}
disabled={!isContainerSizeEnabled}
value={memoryMB}
onChange={(value)=>_onChange('memoryMB', value)}/>
<CSpinButton label={'Shared memory (MB)'}
value={shmMB}
disabled={!isContainerSizeEnabled}
onChange={(value)=>_onChange('shmMB', value)}/>
</BasicSection>
);
};

ContainerSizeSection.propTypes = {
defaultValue: PropTypes.instanceOf(ContainerSize).isRequired,
onChange: PropTypes.func,
isContainerSizeEnabled: PropTypes.bool,
onEnable: PropTypes.func,
};
Loading

0 comments on commit 9b2f3de

Please sign in to comment.