提交 a511969a 编写于 作者: P Piotr Bryk

Merge pull request #163 from bryk/move-namespace-select

Move namespace select to deploy from settings
...@@ -33,26 +33,14 @@ limitations under the License. ...@@ -33,26 +33,14 @@ limitations under the License.
<div ng-switch="ctrl.selection"> <div ng-switch="ctrl.selection">
<deploy-from-settings ng-switch-when="Settings" <deploy-from-settings ng-switch-when="Settings"
name="ctrl.name" name="ctrl.name"
namespace="ctrl.namespace" namespaces="ctrl.namespaces"
detail="ctrl.detail"> detail="ctrl.detail">
</deploy-from-settings> </deploy-from-settings>
<deploy-from-file ng-switch-when="File" <deploy-from-file ng-switch-when="File"
name="ctrl.name" name="ctrl.name"
namespace="ctrl.namespace"
detail="ctrl.detail"> detail="ctrl.detail">
</deploy-from-file> </deploy-from-file>
</div> </div>
<md-input-container class="md-block">
<label>Namespace</label>
<md-select ng-model="ctrl.namespace" required>
<md-option ng-repeat="namespace in ctrl.namespaces" ng-value="namespace">
{{namespace}}
</md-option>
<md-option ng-click="ctrl.handleNamespaceDialog($event)">
Create a new namespace...
</md-option>
</md-select>
</md-input-container>
<md-button class="md-raised md-primary" type="submit" ng-disabled="ctrl.isDeployDisabled()"> <md-button class="md-raised md-primary" type="submit" ng-disabled="ctrl.isDeployDisabled()">
Deploy Deploy
</md-button> </md-button>
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
import {stateName as zerostate} from 'zerostate/zerostate_state'; import {stateName as zerostate} from 'zerostate/zerostate_state';
import showNamespaceDialog from 'deploy/createnamespace_dialog';
/** /**
* Controller for the deploy view. * Controller for the deploy view.
...@@ -25,11 +24,10 @@ export default class DeployController { ...@@ -25,11 +24,10 @@ export default class DeployController {
* @param {!angular.$resource} $resource * @param {!angular.$resource} $resource
* @param {!angular.$log} $log * @param {!angular.$log} $log
* @param {!ui.router.$state} $state * @param {!ui.router.$state} $state
* @param {!md.$dialog} $mdDialog
* @param {!backendApi.NamespaceList} namespaces * @param {!backendApi.NamespaceList} namespaces
* @ngInject * @ngInject
*/ */
constructor($resource, $log, $state, $mdDialog, namespaces) { constructor($resource, $log, $state, namespaces) {
/** @export {!angular.FormController} Initialized from the template */ /** @export {!angular.FormController} Initialized from the template */
this.deployForm; this.deployForm;
...@@ -38,15 +36,26 @@ export default class DeployController { ...@@ -38,15 +36,26 @@ export default class DeployController {
/** /**
* List of available namespaces. * List of available namespaces.
* TODO(bryk): Move this to deploy from settings directive. E.g., use activate method when
* switching to Angular 1.5.
* @export {!Array<string>} * @export {!Array<string>}
*/ */
this.namespaces = namespaces.namespaces; this.namespaces = namespaces.namespaces;
/** /**
* Currently chosen namespace. * Contains the selected directive's controller which has its own deploy logic
* @export {(string|undefined)} *
* Initialized from the template.
* @export {{deploy:function()}|undefined}
*/
this.detail;
/**
* Child directive selection model. The list of possible values is in template. This value
* represents the default selection.
* @export {string}
*/ */
this.namespace = this.namespaces.length > 0 ? this.namespaces[0] : undefined; this.selection = "Settings";
/** @private {!angular.$resource} */ /** @private {!angular.$resource} */
this.resource_ = $resource; this.resource_ = $resource;
...@@ -57,25 +66,8 @@ export default class DeployController { ...@@ -57,25 +66,8 @@ export default class DeployController {
/** @private {!ui.router.$state} */ /** @private {!ui.router.$state} */
this.state_ = $state; this.state_ = $state;
/** @private {!md.$dialog} */
this.mdDialog_ = $mdDialog;
/** @private {boolean} */ /** @private {boolean} */
this.isDeployInProgress_ = false; this.isDeployInProgress_ = false;
/**
* Contains the selected directive's controller which has its own deploy logic
*
* @export {{deploy:function()}}
*/
this.detail = {deploy: function() {}};
/**
* Child directive selection model. The list of possible values is in template. This value
* represents the default selection.
* @export {string}
*/
this.selection = "Settings";
} }
/** /**
...@@ -87,37 +79,14 @@ export default class DeployController { ...@@ -87,37 +79,14 @@ export default class DeployController {
this.detail.deploy().finally(() => { this.isDeployInProgress_ = false; }); this.detail.deploy().finally(() => { this.isDeployInProgress_ = false; });
} }
/**
* Displays new namespace creation dialog.
* @param {!angular.Scope.Event} event
* @export
*/
handleNamespaceDialog(event) {
showNamespaceDialog(this.mdDialog_, event, this.namespaces)
.then(
/**
* Handles namespace dialog result. If namespace was created successfully then it
* will be selected, otherwise first namespace will be selected.
*
* @param {string|undefined} answer
*/
(answer) => {
if (answer) {
this.namespace = answer;
this.namespaces = this.namespaces.concat(answer);
} else {
this.namespace = this.namespaces[0];
}
},
() => { this.namespace = this.namespaces[0]; });
}
/** /**
* Returns true when the deploy action should be enabled. * Returns true when the deploy action should be enabled.
* @return {boolean} * @return {boolean}
* @export * @export
*/ */
isDeployDisabled() { return this.isDeployInProgress_ || this.deployForm.$invalid; } isDeployDisabled() {
return this.isDeployInProgress_ || this.deployForm.$invalid || !this.detail;
}
/** /**
* Cancels the deployment form. * Cancels the deployment form.
......
...@@ -19,7 +19,6 @@ export default function deployFromFileDirective() { ...@@ -19,7 +19,6 @@ export default function deployFromFileDirective() {
scope: {}, scope: {},
bindToController: { bindToController: {
'name': '=', 'name': '=',
'namespace': '=',
'detail': '=', 'detail': '=',
}, },
controller: DeployFromFileController, controller: DeployFromFileController,
......
...@@ -15,47 +15,58 @@ limitations under the License. ...@@ -15,47 +15,58 @@ limitations under the License.
--> -->
<md-input-container class="md-block"> <md-input-container class="md-block">
<label>Container image</label> <label>Container image</label>
<input ng-model="ctrl.containerImage" required> <input ng-model="ctrl.containerImage" required>
</md-input-container> </md-input-container>
<md-input-container class="md-block"> <md-input-container class="md-block">
<label>Number of pods</label> <label>Number of pods</label>
<input ng-model="ctrl.replicas" type="number" required min="1"> <input ng-model="ctrl.replicas" type="number" required min="1">
</md-input-container> </md-input-container>
<div layout="row" ng-repeat="portMapping in ctrl.portMappings"> <div layout="row" ng-repeat="portMapping in ctrl.portMappings">
<md-input-container flex> <md-input-container flex>
<label>Port</label> <label>Port</label>
<input ng-model="portMapping.port" type="number" min="0"> <input ng-model="portMapping.port" type="number" min="0">
</md-input-container> </md-input-container>
<md-input-container flex> <md-input-container flex>
<label>Target port</label> <label>Target port</label>
<input ng-model="portMapping.targetPort" type="number" min="0"> <input ng-model="portMapping.targetPort" type="number" min="0">
</md-input-container> </md-input-container>
<md-input-container flex="none"> <md-input-container flex="none">
<label>Protocol</label> <label>Protocol</label>
<md-select ng-model="portMapping.protocol" required> <md-select ng-model="portMapping.protocol" required>
<md-option ng-repeat="protocol in ctrl.protocols" ng-value="protocol"> <md-option ng-repeat="protocol in ctrl.protocols" ng-value="protocol">
{{protocol}} {{protocol}}
</md-option> </md-option>
</md-select> </md-select>
</md-input-container> </md-input-container>
</div> </div>
<md-switch ng-model="ctrl.isExternal" class="md-primary"> <md-switch ng-model="ctrl.isExternal" class="md-primary">
Expose service externally Expose service externally
</md-switch> </md-switch>
<md-input-container> <md-input-container>
<label>Description (optional)</label> <label>Description (optional)</label>
<textarea ng-model="ctrl.description"></textarea> <textarea ng-model="ctrl.description"></textarea>
</md-input-container> </md-input-container>
<div> <div>
<div>Labels (optional)</div> <div>Labels (optional)</div>
<div layout="column"> <div layout="column">
<div layout="row"> <div layout="row">
<p flex>Key</p> <p flex>Key</p>
<p flex>Value</p> <p flex>Value</p>
</div>
<div ng-repeat="label in ctrl.labels">
<kd-label layout="row" flex label="label" labels="ctrl.labels"></kd-label>
</div>
</div> </div>
<div ng-repeat="label in ctrl.labels">
<kd-label layout="row" flex label="label" labels="ctrl.labels"></kd-label>
</div>
</div>
</div> </div>
<md-input-container class="md-block">
<label>Namespace</label>
<md-select ng-model="ctrl.namespace" required>
<md-option ng-repeat="namespace in ctrl.namespaces" ng-value="namespace">
{{namespace}}
</md-option>
<md-option ng-click="ctrl.handleNamespaceDialog($event)">
Create a new namespace...
</md-option>
</md-select>
</md-input-container>
...@@ -12,12 +12,13 @@ ...@@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import showNamespaceDialog from './createnamespace_dialog';
import DeployLabel from './deploylabel'; import DeployLabel from './deploylabel';
import {stateName as replicasetliststate} from 'replicasetlist/replicasetlist_state'; import {stateName as replicasetliststate} from 'replicasetlist/replicasetlist_state';
// Label keys for predefined labels // Label keys for predefined labels
export const APP_LABEL_KEY = 'app'; const APP_LABEL_KEY = 'app';
export const VERSION_LABEL_KEY = 'version'; const VERSION_LABEL_KEY = 'version';
/** /**
* Controller for the deploy from settings directive. * Controller for the deploy from settings directive.
...@@ -30,9 +31,10 @@ export default class DeployFromSettingsController { ...@@ -30,9 +31,10 @@ export default class DeployFromSettingsController {
* @param {!ui.router.$state} $state * @param {!ui.router.$state} $state
* @param {!angular.$resource} $resource * @param {!angular.$resource} $resource
* @param {!angular.$q} $q * @param {!angular.$q} $q
* @param {!md.$dialog} $mdDialog
* @ngInject * @ngInject
*/ */
constructor($log, $state, $resource, $q) { constructor($log, $state, $resource, $q, $mdDialog) {
/** /**
* It initializes the scope output parameter * It initializes the scope output parameter
* *
...@@ -40,18 +42,6 @@ export default class DeployFromSettingsController { ...@@ -40,18 +42,6 @@ export default class DeployFromSettingsController {
*/ */
this.detail = this; this.detail = this;
/** @private {!angular.$q} */
this.q_ = $q;
/** @private {!angular.$resource} */
this.resource_ = $resource;
/** @private {!angular.$log} */
this.log_ = $log;
/** @private {!ui.router.$state} */
this.state_ = $state;
/** @export {string} */ /** @export {string} */
this.containerImage = ''; this.containerImage = '';
...@@ -80,13 +70,42 @@ export default class DeployFromSettingsController { ...@@ -80,13 +70,42 @@ export default class DeployFromSettingsController {
new DeployLabel(VERSION_LABEL_KEY, '', false, this.getContainerImageVersion_.bind(this)), new DeployLabel(VERSION_LABEL_KEY, '', false, this.getContainerImageVersion_.bind(this)),
new DeployLabel(), new DeployLabel(),
]; ];
/**
* List of available namespaces.
*
* Initialized from the scope.
* @export {!Array<string>}
*/
this.namespaces;
/**
* Currently chosen namespace.
* @export {(string|undefined)}
*/
this.namespace = this.namespaces.length > 0 ? this.namespaces[0] : undefined;
/** @private {!angular.$q} */
this.q_ = $q;
/** @private {!angular.$resource} */
this.resource_ = $resource;
/** @private {!angular.$log} */
this.log_ = $log;
/** @private {!ui.router.$state} */
this.state_ = $state;
/** @private {!md.$dialog} */
this.mdDialog_ = $mdDialog;
} }
/** /**
* Deploys the application based on the state of the controller. * Deploys the application based on the state of the controller.
* *
* @export
* @return {angular.$q.Promise} * @return {angular.$q.Promise}
* @export
*/ */
deploy() { deploy() {
// TODO(bryk): Validate input data before sending to the server. // TODO(bryk): Validate input data before sending to the server.
...@@ -120,6 +139,32 @@ export default class DeployFromSettingsController { ...@@ -120,6 +139,32 @@ export default class DeployFromSettingsController {
return defer.promise; return defer.promise;
} }
/**
* Displays new namespace creation dialog.
*
* @param {!angular.Scope.Event} event
* @export
*/
handleNamespaceDialog(event) {
showNamespaceDialog(this.mdDialog_, event, this.namespaces)
.then(
/**
* Handles namespace dialog result. If namespace was created successfully then it
* will be selected, otherwise first namespace will be selected.
*
* @param {string|undefined} answer
*/
(answer) => {
if (answer) {
this.namespace = answer;
this.namespaces = this.namespaces.concat(answer);
} else {
this.namespace = this.namespaces[0];
}
},
() => { this.namespace = this.namespaces[0]; });
}
/** /**
* Converts array of DeployLabel to array of backend api label * Converts array of DeployLabel to array of backend api label
* @param {!Array<!DeployLabel>} labels * @param {!Array<!DeployLabel>} labels
......
...@@ -23,7 +23,7 @@ export default function deployFromSettingsDirective() { ...@@ -23,7 +23,7 @@ export default function deployFromSettingsDirective() {
scope: {}, scope: {},
bindToController: { bindToController: {
'name': '=', 'name': '=',
'namespace': '=', 'namespaces': '=',
'detail': '=', 'detail': '=',
}, },
controller: DeployFromSettingsController, controller: DeployFromSettingsController,
......
...@@ -26,12 +26,13 @@ export default class UploadController { ...@@ -26,12 +26,13 @@ export default class UploadController {
/** /**
* Browse file function which is defined by the clients. * Browse file function which is defined by the clients.
* *
* @private {Function} */ * Initialized from the registerBrowseFileFunction method.
this.browseFileFunc_ = function() {}; * @private {(function())|undefined} */
this.browseFileFunc_;
} }
/** /**
* @param {Function} func * @param {function()} func
* @export * @export
*/ */
registerBrowseFileFunction(func) { registerBrowseFileFunction(func) {
...@@ -47,5 +48,9 @@ export default class UploadController { ...@@ -47,5 +48,9 @@ export default class UploadController {
* *
* @export * @export
*/ */
browseFile() { this.browseFileFunc_(); } browseFile() {
if (this.browseFileFunc_) {
this.browseFileFunc_();
}
}
} }
...@@ -28,10 +28,10 @@ describe('Deploy controller', () => { ...@@ -28,10 +28,10 @@ describe('Deploy controller', () => {
beforeEach(() => { beforeEach(() => {
angular.mock.module(deployModule.name); angular.mock.module(deployModule.name);
angular.mock.inject(($resource, $log, $state, $mdDialog, $q) => { angular.mock.inject(($controller, $state) => {
state = $state; state = $state;
ctrl = new DeployController($resource, $log, state, $mdDialog, {namespaces: []}); ctrl = $controller(DeployController, {namespaces: []});
settingsCtrl = new DeployFromSettingController($log, $state, $resource, $q); settingsCtrl = $controller(DeployFromSettingController, {}, {namespaces: []});
}); });
// prepare and mock // prepare and mock
......
...@@ -22,8 +22,8 @@ describe('DeployFromSettings controller', () => { ...@@ -22,8 +22,8 @@ describe('DeployFromSettings controller', () => {
beforeEach(() => { beforeEach(() => {
angular.mock.module(deployModule.name); angular.mock.module(deployModule.name);
angular.mock.inject(($log, $state, $resource, $q) => { angular.mock.inject(($controller) => {
ctrl = new DeployFromSettingController($log, $state, $resource, $q); ctrl = $controller(DeployFromSettingController, {}, {namespaces: []});
}); });
}); });
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
import DeployLabelController from 'deploy/deploylabel_controller'; import DeployLabelController from 'deploy/deploylabel_controller';
import DeployLabel from 'deploy/deploylabel'; import DeployLabel from 'deploy/deploylabel';
describe('DeployFromSettings controller', () => { describe('DeployLabel controller', () => {
let ctrl; let ctrl;
let labelForm; let labelForm;
......
...@@ -18,7 +18,7 @@ describe('Zero state view', () => { ...@@ -18,7 +18,7 @@ describe('Zero state view', () => {
let page; let page;
beforeEach(() => { beforeEach(() => {
browser.get('/index.html'); browser.get('/index.html/#zerostate');
page = new PageObject(); page = new PageObject();
}); });
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册