mirror of https://github.com/portainer/portainer
EE-3694 update UI of docker/custom template (#7345)
parent
090268d7b6
commit
6d3a33635d
|
@ -1,6 +1,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<por-switch-field
|
<por-switch-field
|
||||||
|
label-class="'col-sm-2'"
|
||||||
checked="$ctrl.model.RepositoryAuthentication"
|
checked="$ctrl.model.RepositoryAuthentication"
|
||||||
label="'Authentication'"
|
label="'Authentication'"
|
||||||
name="'authSwitch'"
|
name="'authSwitch'"
|
||||||
|
@ -9,7 +10,7 @@
|
||||||
></por-switch-field>
|
></por-switch-field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="small" style="margin: 5px 0 15px 0" ng-if="$ctrl.model.RepositoryAuthentication && $ctrl.showAuthExplanation">
|
<div class="small mt-1 mb-3" ng-if="$ctrl.model.RepositoryAuthentication && $ctrl.showAuthExplanation">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
<span class="text-muted">Enabling authentication will store the credentials and it is advisable to use a git service account</span>
|
<span class="text-muted">Enabling authentication will store the credentials and it is advisable to use a git service account</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div ng-if="!$ctrl.state.fromStack">
|
<div ng-if="!$ctrl.state.fromStack">
|
||||||
<div class="col-sm-12 form-section-title"> Build method </div>
|
<div class="col-sm-12 form-section-title"> Build method </div>
|
||||||
<div class="form-group"></div>
|
<div class="form-group"></div>
|
||||||
<div class="form-group" style="margin-bottom: 0">
|
<div class="form-group mb-0">
|
||||||
<div class="boxselector_wrapper">
|
<div class="boxselector_wrapper">
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="method_editor" ng-model="$ctrl.state.Method" value="editor" ng-change="$ctrl.onChangeMethod()" />
|
<input type="radio" id="method_editor" ng-model="$ctrl.state.Method" value="editor" ng-change="$ctrl.onChangeMethod()" />
|
||||||
|
@ -53,27 +53,23 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- !build-method -->
|
<!-- !build-method -->
|
||||||
<!-- web-editor -->
|
<!-- web-editor -->
|
||||||
<div ng-show="$ctrl.state.Method === 'editor'">
|
<web-editor-form
|
||||||
<div class="col-sm-12 form-section-title"> Web editor </div>
|
ng-if="$ctrl.state.Method === 'editor'"
|
||||||
<div class="form-group">
|
identifier="custom-template-creation-editor"
|
||||||
<span class="col-sm-12 text-muted small">
|
value="$ctrl.formValues.FileContent"
|
||||||
|
on-change="($ctrl.editorUpdate)"
|
||||||
|
ng-required="true"
|
||||||
|
yml="true"
|
||||||
|
placeholder="# Define or paste the content of your docker compose file here"
|
||||||
|
>
|
||||||
|
<editor-description>
|
||||||
|
<span class="col-sm-12 text-muted">
|
||||||
You can get more information about Compose file format in the
|
You can get more information about Compose file format in the
|
||||||
<a href="https://docs.docker.com/compose/compose-file/" target="_blank"> official documentation </a>
|
<a href="https://docs.docker.com/compose/compose-file/" target="_blank"> official documentation </a>
|
||||||
.
|
.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</editor-description>
|
||||||
<div class="form-group">
|
</web-editor-form>
|
||||||
<div class="col-sm-12">
|
|
||||||
<code-editor
|
|
||||||
identifier="custom-template-creation-editor"
|
|
||||||
placeholder="# Define or paste the content of your docker compose file here"
|
|
||||||
yml="true"
|
|
||||||
value="$ctrl.formValues.FileContent"
|
|
||||||
on-change="($ctrl.editorUpdate)"
|
|
||||||
></code-editor>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- !web-editor -->
|
<!-- !web-editor -->
|
||||||
<!-- upload -->
|
<!-- upload -->
|
||||||
<div ng-show="$ctrl.state.Method === 'upload'">
|
<div ng-show="$ctrl.state.Method === 'upload'">
|
||||||
|
@ -84,9 +80,11 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button type="button" class="btn btn-sm btn-primary" ngf-select ng-model="$ctrl.formValues.File"> Select file </button>
|
<button type="button" class="btn btn-sm btn-primary" ngf-select ng-model="$ctrl.formValues.File"> Select file </button>
|
||||||
<span style="margin-left: 5px">
|
<span class="space-left">
|
||||||
{{ $ctrl.formValues.File.name }}
|
{{ $ctrl.formValues.File.name }}
|
||||||
<i class="fa fa-times red-icon" ng-if="!$ctrl.formValues.File" aria-hidden="true"></i>
|
<span ng-if="$ctrl.formValues.File">
|
||||||
|
<pr-icon icon="'x'" feather="true" mode="'danger'"></pr-icon>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,7 +96,7 @@
|
||||||
<div class="form-group" ng-if="!$ctrl.state.isTemplateValid">
|
<div class="form-group" ng-if="!$ctrl.state.isTemplateValid">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="small text-warning">
|
<div class="small text-warning">
|
||||||
<i class="fa fa-exclamation-triangle space-right" aria-hidden="true"></i>
|
<pr-icon icon="'alert-triangle'" feather="true" class-name="space-right"></pr-icon>
|
||||||
Template is invalid.
|
Template is invalid.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -133,7 +131,7 @@
|
||||||
<span ng-hide="$ctrl.state.actionInProgress">Create custom template</span>
|
<span ng-hide="$ctrl.state.actionInProgress">Create custom template</span>
|
||||||
<span ng-show="$ctrl.state.actionInProgress">Creation in progress...</span>
|
<span ng-show="$ctrl.state.actionInProgress">Creation in progress...</span>
|
||||||
</button>
|
</button>
|
||||||
<span class="text-danger" ng-if="$ctrl.state.formValidationError" style="margin-left: 5px">
|
<span class="text-danger space-left" ng-if="$ctrl.state.formValidationError">
|
||||||
{{ $ctrl.state.formValidationError }}
|
{{ $ctrl.state.formValidationError }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -171,8 +171,7 @@ class CreateCustomTemplateViewController {
|
||||||
return this.CustomTemplateService.createCustomTemplateFromGitRepository(this.formValues);
|
return this.CustomTemplateService.createCustomTemplateFromGitRepository(this.formValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
editorUpdate(cm) {
|
editorUpdate(value) {
|
||||||
const value = cm.getValue();
|
|
||||||
this.formValues.FileContent = value;
|
this.formValues.FileContent = value;
|
||||||
this.state.isEditorDirty = true;
|
this.state.isEditorDirty = true;
|
||||||
this.parseTemplate(value);
|
this.parseTemplate(value);
|
||||||
|
|
|
@ -20,37 +20,33 @@
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<a class="small interactive" ng-show="!$ctrl.state.showAdvancedOptions" ng-click="$ctrl.state.showAdvancedOptions = true;">
|
<a class="small interactive vertical-center" ng-show="!$ctrl.state.showAdvancedOptions" ng-click="$ctrl.state.showAdvancedOptions = true;">
|
||||||
<i class="fa fa-plus space-right" aria-hidden="true"></i> Customize stack
|
<pr-icon icon="'plus'" class-name="space-right" feather="true"></pr-icon> Customize stack
|
||||||
</a>
|
</a>
|
||||||
<a class="small interactive" ng-show="$ctrl.state.showAdvancedOptions" ng-click="$ctrl.state.showAdvancedOptions = false;">
|
<a class="small interactive vertical-center" ng-show="$ctrl.state.showAdvancedOptions" ng-click="$ctrl.state.showAdvancedOptions = false;">
|
||||||
<i class="fa fa-minus space-right" aria-hidden="true"></i> Hide custom stack
|
<pr-icon icon="'minus'" class-name="space-right" feather="true"></pr-icon> Hide custom stack
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="$ctrl.state.showAdvancedOptions">
|
|
||||||
<!-- web-editor -->
|
<!-- web-editor -->
|
||||||
<div class="col-sm-12 form-section-title"> Web editor </div>
|
<web-editor-form
|
||||||
<div class="form-group">
|
ng-if="$ctrl.state.showAdvancedOptions"
|
||||||
<span class="col-sm-12 text-muted small">
|
identifier="custom-template-creation-editor"
|
||||||
|
value="$ctrl.formValues.FileContent"
|
||||||
|
on-change="($ctrl.editorUpdate)"
|
||||||
|
ng-required="true"
|
||||||
|
yml="true"
|
||||||
|
placeholder="# Define or paste the content of your docker compose file here"
|
||||||
|
>
|
||||||
|
<editor-description>
|
||||||
|
<span class="col-sm-12 text-muted">
|
||||||
You can get more information about Compose file format in the
|
You can get more information about Compose file format in the
|
||||||
<a href="https://docs.docker.com/compose/compose-file/" target="_blank"> official documentation </a>
|
<a href="https://docs.docker.com/compose/compose-file/" target="_blank"> official documentation </a>
|
||||||
.
|
.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</editor-description>
|
||||||
<div class="form-group">
|
</web-editor-form>
|
||||||
<div class="col-sm-12">
|
|
||||||
<code-editor
|
|
||||||
identifier="custom-template-creation-editor"
|
|
||||||
placeholder="# Define or paste the content of your docker compose file here"
|
|
||||||
yml="true"
|
|
||||||
value="$ctrl.formValues.fileContent"
|
|
||||||
on-change="($ctrl.editorUpdate)"
|
|
||||||
></code-editor>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- !web-editor -->
|
<!-- !web-editor -->
|
||||||
</div>
|
|
||||||
</advanced-form>
|
</advanced-form>
|
||||||
</stack-from-template-form>
|
</stack-from-template-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -259,8 +259,8 @@ class CustomTemplatesViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editorUpdate(cm) {
|
editorUpdate(value) {
|
||||||
this.formValues.fileContent = cm.getValue();
|
this.formValues.fileContent = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
isDeployable(endpoint, templateType) {
|
isDeployable(endpoint, templateType) {
|
||||||
|
|
|
@ -8,31 +8,28 @@
|
||||||
<custom-template-common-fields form-values="$ctrl.formValues" show-platform-field="true" show-type-field="true"></custom-template-common-fields>
|
<custom-template-common-fields form-values="$ctrl.formValues" show-platform-field="true" show-type-field="true"></custom-template-common-fields>
|
||||||
|
|
||||||
<!-- web-editor -->
|
<!-- web-editor -->
|
||||||
<div class="col-sm-12 form-section-title"> Web editor </div>
|
<web-editor-form
|
||||||
<div class="form-group">
|
identifier="custom-template-creation-editor"
|
||||||
<span class="col-sm-12 text-muted small">
|
value="$ctrl.formValues.FileContent"
|
||||||
|
on-change="($ctrl.editorUpdate)"
|
||||||
|
ng-required="true"
|
||||||
|
yml="true"
|
||||||
|
placeholder="# Define or paste the content of your docker compose file here"
|
||||||
|
>
|
||||||
|
<editor-description>
|
||||||
|
<span class="col-sm-12 text-muted">
|
||||||
You can get more information about Compose file format in the
|
You can get more information about Compose file format in the
|
||||||
<a href="https://docs.docker.com/compose/compose-file/" target="_blank"> official documentation </a>
|
<a href="https://docs.docker.com/compose/compose-file/" target="_blank"> official documentation </a>
|
||||||
.
|
.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</editor-description>
|
||||||
<div class="form-group">
|
</web-editor-form>
|
||||||
<div class="col-sm-12">
|
|
||||||
<code-editor
|
|
||||||
identifier="custom-template-creation-editor"
|
|
||||||
placeholder="# Define or paste the content of your docker compose file here"
|
|
||||||
yml="true"
|
|
||||||
value="$ctrl.formValues.FileContent"
|
|
||||||
on-change="($ctrl.editorUpdate)"
|
|
||||||
></code-editor>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- !web-editor -->
|
<!-- !web-editor -->
|
||||||
|
|
||||||
<div class="form-group" ng-if="!$ctrl.state.isTemplateValid">
|
<div class="form-group" ng-if="!$ctrl.state.isTemplateValid">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="small text-warning">
|
<div class="small text-warning">
|
||||||
<i class="fa fa-exclamation-triangle space-right" aria-hidden="true"></i>
|
<pr-icon icon="'alert-triangle'" feather="true" class-name="space-right"></pr-icon>
|
||||||
Template is invalid.
|
Template is invalid.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,7 +61,7 @@
|
||||||
<span ng-hide="$ctrl.actionInProgress">Update the template</span>
|
<span ng-hide="$ctrl.actionInProgress">Update the template</span>
|
||||||
<span ng-show="$ctrl.actionInProgress">Update in progress...</span>
|
<span ng-show="$ctrl.actionInProgress">Update in progress...</span>
|
||||||
</button>
|
</button>
|
||||||
<span class="text-danger" ng-if="$ctrl.state.formValidationError" style="margin-left: 5px">
|
<span class="text-danger space-left" ng-if="$ctrl.state.formValidationError">
|
||||||
{{ $ctrl.state.formValidationError }}
|
{{ $ctrl.state.formValidationError }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -120,8 +120,7 @@ class EditCustomTemplateViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editorUpdate(cm) {
|
editorUpdate(value) {
|
||||||
const value = cm.getValue();
|
|
||||||
if (this.formValues.FileContent.replace(/(\r\n|\n|\r)/gm, '') !== value.replace(/(\r\n|\n|\r)/gm, '')) {
|
if (this.formValues.FileContent.replace(/(\r\n|\n|\r)/gm, '') !== value.replace(/(\r\n|\n|\r)/gm, '')) {
|
||||||
this.formValues.FileContent = value;
|
this.formValues.FileContent = value;
|
||||||
this.parseTemplate(value);
|
this.parseTemplate(value);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
import { Icon } from '@/react/components/Icon';
|
||||||
|
|
||||||
import styles from './AddButton.module.css';
|
import styles from './AddButton.module.css';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
@ -17,13 +19,15 @@ export function AddButton({ label, onClick, className, disabled }: Props) {
|
||||||
'label',
|
'label',
|
||||||
'label-default',
|
'label-default',
|
||||||
'interactive',
|
'interactive',
|
||||||
|
'vertical-center',
|
||||||
styles.addButton
|
styles.addButton
|
||||||
)}
|
)}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<i className="fa fa-plus-circle space-right" aria-hidden="true" /> {label}
|
<Icon icon="plus" feather className="space-right" />
|
||||||
|
{label}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import clsx from 'clsx';
|
||||||
import { FormikErrors } from 'formik';
|
import { FormikErrors } from 'formik';
|
||||||
|
|
||||||
import { AddButton, Button } from '@@/buttons';
|
import { AddButton, Button } from '@@/buttons';
|
||||||
|
import { Icon } from '@@/Icon';
|
||||||
import { Tooltip } from '@@/Tip/Tooltip';
|
import { Tooltip } from '@@/Tip/Tooltip';
|
||||||
import { TextTip } from '@@/Tip/TextTip';
|
import { TextTip } from '@@/Tip/TextTip';
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ export function InputList<T = DefaultType>({
|
||||||
disabled={disabled || index === 0}
|
disabled={disabled || index === 0}
|
||||||
onClick={() => handleMoveUp(index)}
|
onClick={() => handleMoveUp(index)}
|
||||||
>
|
>
|
||||||
<i className="fa fa-arrow-up" aria-hidden="true" />
|
<Icon icon="arrow-up" feather />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -139,7 +140,7 @@ export function InputList<T = DefaultType>({
|
||||||
disabled={disabled || index === value.length - 1}
|
disabled={disabled || index === value.length - 1}
|
||||||
onClick={() => handleMoveDown(index)}
|
onClick={() => handleMoveDown(index)}
|
||||||
>
|
>
|
||||||
<i className="fa fa-arrow-down" aria-hidden="true" />
|
<Icon icon="arrow-down" feather />
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Reference in New Issue