mirror of
https://github.com/nasa/openmct.git
synced 2025-06-24 18:25:19 +00:00
Compare commits
12 Commits
master
...
inline-edi
Author | SHA1 | Date | |
---|---|---|---|
889350623a | |||
aac1f02bd6 | |||
e759761a04 | |||
490567c8e8 | |||
ede5b85c93 | |||
82f32a57f4 | |||
0dd6a4eb44 | |||
4c03a3b31d | |||
aaeffb16e3 | |||
41f6047c96 | |||
c35cdf176f | |||
05227286c4 |
@ -26,6 +26,7 @@ define([
|
||||
"./src/InspectorPaneController",
|
||||
"./src/BrowseObjectController",
|
||||
"./src/MenuArrowController",
|
||||
"./src/ObjectHeaderController",
|
||||
"./src/navigation/NavigationService",
|
||||
"./src/navigation/NavigateAction",
|
||||
"./src/navigation/OrphanNavigationHandler",
|
||||
@ -48,6 +49,7 @@ define([
|
||||
InspectorPaneController,
|
||||
BrowseObjectController,
|
||||
MenuArrowController,
|
||||
ObjectHeaderController,
|
||||
NavigationService,
|
||||
NavigateAction,
|
||||
OrphanNavigationHandler,
|
||||
@ -140,6 +142,13 @@ define([
|
||||
"$location",
|
||||
"$attrs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "ObjectHeaderController",
|
||||
"implementation": ObjectHeaderController,
|
||||
"depends": [
|
||||
"$scope"
|
||||
]
|
||||
}
|
||||
],
|
||||
"representations": [
|
||||
|
@ -20,9 +20,14 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<span class='type-icon flex-elem {{type.getCssClass()}}'></span>
|
||||
<span class="l-elem-wrapper l-flex-row flex-elem grows">
|
||||
<span class="l-elem-wrapper l-flex-row flex-elem grows" ng-controller="ObjectHeaderController as controller">
|
||||
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
|
||||
<span class='title-label flex-elem holder flex-can-shrink'>{{model.name}}</span>
|
||||
<span contenteditable="true"
|
||||
class='title-label flex-elem holder flex-can-shrink s-inline-edit'
|
||||
ng-class="{'s-status-editing': inlineEdit}"
|
||||
ng-click="controller.edit()"
|
||||
ng-blur="controller.updateName($event)"
|
||||
ng-keypress="controller.updateName($event)">{{model.name}}</span>
|
||||
<span class='t-object-alert t-alert-unsynced flex-elem holder' title='This object is not currently displaying real-time data'></span>
|
||||
<mct-representation
|
||||
key="'menu-arrow'"
|
||||
|
76
platform/commonUI/browse/src/ObjectHeaderController.js
Normal file
76
platform/commonUI/browse/src/ObjectHeaderController.js
Normal file
@ -0,0 +1,76 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Controller to provide the ability to inline edit an object name.
|
||||
*
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/browse
|
||||
*/
|
||||
function ObjectHeaderController($scope) {
|
||||
this.$scope = $scope;
|
||||
this.$scope.inlineEdit = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the blur and enter/return key press events
|
||||
* to update the object name.
|
||||
*
|
||||
* @param event the mouse event
|
||||
*/
|
||||
ObjectHeaderController.prototype.updateName = function (event) {
|
||||
if (event && (event.type === 'blur' || event.which === 13)) {
|
||||
var name = event.currentTarget.innerHTML;
|
||||
|
||||
if (name.length === 0) {
|
||||
name = "Unnamed " + this.$scope.domainObject.getCapability("type").typeDef.name;
|
||||
event.currentTarget.innerHTML = name;
|
||||
}
|
||||
|
||||
if (name !== this.$scope.domainObject.model.name) {
|
||||
this.$scope.domainObject.getCapability('mutation').mutate(function (model) {
|
||||
model.name = name;
|
||||
});
|
||||
}
|
||||
|
||||
this.$scope.inlineEdit = false;
|
||||
|
||||
if (event.which === 13) {
|
||||
event.currentTarget.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for the click event to mark the filed as inline edit.
|
||||
*/
|
||||
ObjectHeaderController.prototype.edit = function () {
|
||||
this.$scope.inlineEdit = true;
|
||||
};
|
||||
|
||||
return ObjectHeaderController;
|
||||
}
|
||||
);
|
94
platform/commonUI/browse/test/ObjectHeaderControllerSpec.js
Normal file
94
platform/commonUI/browse/test/ObjectHeaderControllerSpec.js
Normal file
@ -0,0 +1,94 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../src/ObjectHeaderController"],
|
||||
function (ObjectHeaderController) {
|
||||
|
||||
describe("The object header controller", function () {
|
||||
var mockScope,
|
||||
mockDomainObject,
|
||||
mockMutationCapability,
|
||||
mockEvent,
|
||||
mockCurrentTarget,
|
||||
controller;
|
||||
|
||||
function getModel() {
|
||||
return {
|
||||
name: 'Test name'
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]);
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "model"]);
|
||||
mockDomainObject.model = getModel();
|
||||
mockDomainObject.getCapability.andReturn(mockMutationCapability);
|
||||
|
||||
mockScope = jasmine.createSpyObj("$scope", ["name"]);
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
|
||||
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur"]);
|
||||
mockCurrentTarget.blur.andReturn({ blur: function () {} });
|
||||
|
||||
mockEvent = jasmine.createSpyObj('event', ["which"]);
|
||||
mockEvent.currentTarget = mockCurrentTarget;
|
||||
|
||||
controller = new ObjectHeaderController(mockScope);
|
||||
});
|
||||
|
||||
it("updates the model with new name", function () {
|
||||
mockScope.name = 'New name';
|
||||
controller.updateName();
|
||||
|
||||
expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it("does not update the model for blank names", function () {
|
||||
mockScope.name = "";
|
||||
controller.updateName();
|
||||
|
||||
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("updates the model on enter keypress event only", function () {
|
||||
mockScope.name = 'New name';
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
|
||||
|
||||
mockEvent.which = 13;
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockMutationCapability.mutate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blurs the field on enter key press", function () {
|
||||
mockEvent.which = 13;
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -111,7 +111,9 @@ $bubbleMaxW: 300px;
|
||||
$reqSymbolW: 15px;
|
||||
$reqSymbolM: $interiorMargin * 2;
|
||||
$reqSymbolFontSize: 0.75em;
|
||||
$inputTextP: 3px 5px;
|
||||
$inputTextPTopBtm: 3px;
|
||||
$inputTextPLeftRight: 5px;
|
||||
$inputTextP: $inputTextPTopBtm $inputTextPLeftRight;
|
||||
/*************** Wait Spinner Defaults */
|
||||
$waitSpinnerD: 32px;
|
||||
$waitSpinnerTreeD: 20px;
|
||||
|
@ -316,23 +316,25 @@
|
||||
text-shadow: $shdwItemText;
|
||||
}
|
||||
|
||||
@mixin input-base($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
|
||||
@mixin input-base() {
|
||||
@include appearance(none);
|
||||
border-radius: $controlCr;
|
||||
box-sizing: border-box;
|
||||
box-shadow: inset $shdw;
|
||||
background: $bg;
|
||||
border: none;
|
||||
color: $fg;
|
||||
outline: none;
|
||||
&:focus { outline: 0; }
|
||||
&.error {
|
||||
background-color: $colorFormFieldErrorBg;
|
||||
color: $colorFormFieldErrorFg;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg) {
|
||||
@include input-base($bg, $fg);
|
||||
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
|
||||
@include input-base();
|
||||
background: $bg;
|
||||
box-shadow: inset $shdw;
|
||||
border: none;
|
||||
color: $fg;
|
||||
outline: none;
|
||||
padding: $inputTextPTopBtm $inputTextPLeftRight;
|
||||
}
|
||||
|
||||
@mixin contextArrow() {
|
||||
@ -344,7 +346,7 @@
|
||||
}
|
||||
|
||||
@mixin nice-textarea($bg: $colorBodyBg, $fg: $colorBodyFg) {
|
||||
@include input-base($bg, $fg);
|
||||
@include nice-input($bg, $fg);
|
||||
padding: $interiorMargin;
|
||||
}
|
||||
|
||||
|
@ -243,6 +243,24 @@ input[type="number"] {
|
||||
}
|
||||
}
|
||||
|
||||
span[contenteditable].s-inline-edit {
|
||||
@include trans-prop-nice((padding), 250ms);
|
||||
@include input-base();
|
||||
border: 1px solid transparent;
|
||||
min-width: 20px;
|
||||
&:hover {
|
||||
border-color: rgba($colorBodyFg, 0.2);
|
||||
padding-left: $inputTextPLeftRight;
|
||||
padding-right: $inputTextPLeftRight;
|
||||
}
|
||||
}
|
||||
|
||||
span[contenteditable].s-inline-edit.s-status-editing {
|
||||
@include nice-input();
|
||||
vertical-align: baseline;
|
||||
padding: 0 $inputTextPLeftRight;
|
||||
}
|
||||
|
||||
.l-input-sm {
|
||||
input[type="text"],
|
||||
input[type="search"],
|
||||
|
@ -129,9 +129,6 @@
|
||||
}
|
||||
|
||||
.s-filter {
|
||||
input[type="search"] {
|
||||
@include input-base();
|
||||
}
|
||||
.clear-icon,
|
||||
.menu-icon,
|
||||
&:before {
|
||||
|
@ -20,7 +20,7 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!-- look at action-button for example -->
|
||||
<span class="t-filter l-filter s-filter"
|
||||
<span class="t-filter l-filter"
|
||||
ng-controller="GetterSetterController">
|
||||
<input type="search"
|
||||
class="t-filter-input"
|
||||
|
Reference in New Issue
Block a user