Compare commits

...

12 Commits

Author SHA1 Message Date
889350623a [Front-end] min-width added to .s-inline-edit
Fixes #1679
2017-09-07 16:01:52 -07:00
aac1f02bd6 [Front-end] Styling for contenteditable span
Fixes #1679
WIP: refactor input-base and nice-input mixins;
styling for span[contenteditable].s-status-editing in _controls.scss;
removed s-filter class;
TODO: figure out baseline text shift on click
2017-09-07 15:54:32 -07:00
e759761a04 Merge branch 'inline-edit-issue-1679' of https://github.com/nasa/openmct into inline-edit-issue-1679-styling 2017-09-07 14:27:11 -07:00
490567c8e8 [Front-end] Add span contenteditable to input styling
Fixes #1679
2017-09-07 14:26:57 -07:00
ede5b85c93 Changed input to a span with conteneditable flag on. 2017-09-07 14:06:57 -07:00
82f32a57f4 Merge remote-tracking branch 'refs/remotes/origin/inline-edit-issue-1679' into inline-edit-issue-1679 2017-09-06 11:18:42 -07:00
0dd6a4eb44 Fixed a lint error. 2017-09-06 10:40:16 -07:00
4c03a3b31d Fixed checkstyle errors 2017-09-06 10:40:16 -07:00
aaeffb16e3 Added tests. Also, added a check to mutate the name if it's different than the model. 2017-09-06 10:40:16 -07:00
41f6047c96 Changed the title-label span to an input to support inline edit and implemented a controller to handle updaing the name. 2017-09-06 10:40:16 -07:00
c35cdf176f Added tests. Also, added a check to mutate the name if it's different than the model. 2017-09-05 14:00:29 -07:00
05227286c4 Changed the title-label span to an input to support inline edit and implemented a controller to handle updaing the name. 2017-08-29 15:05:40 -07:00
9 changed files with 219 additions and 16 deletions

View File

@ -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": [

View File

@ -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'"

View 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;
}
);

View 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();
});
});
}
);

View File

@ -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;

View File

@ -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;
}

View File

@ -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"],

View File

@ -129,9 +129,6 @@
}
.s-filter {
input[type="search"] {
@include input-base();
}
.clear-icon,
.menu-icon,
&:before {

View File

@ -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"