mirror of
https://github.com/nasa/openmct.git
synced 2024-12-19 05:07:52 +00:00
Merge remote-tracking branch 'origin/api-tutorials' into open1094
Conflicts: index.html tutorials/todo/todo.js
This commit is contained in:
commit
382dde300a
@ -35,8 +35,8 @@
|
|||||||
'./example/imagery/bundle',
|
'./example/imagery/bundle',
|
||||||
'./example/eventGenerator/bundle',
|
'./example/eventGenerator/bundle',
|
||||||
'./example/generator/bundle'
|
'./example/generator/bundle'
|
||||||
], function (TodoPlugin) {
|
], function (todoPlugin) {
|
||||||
mct.install(TodoPlugin);
|
mct.install(todoPlugin);
|
||||||
mct.run();
|
mct.run();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
25
src/MCT.js
25
src/MCT.js
@ -4,7 +4,6 @@ define([
|
|||||||
'uuid',
|
'uuid',
|
||||||
'./api/api',
|
'./api/api',
|
||||||
'text!./adapter/templates/edit-object-replacement.html',
|
'text!./adapter/templates/edit-object-replacement.html',
|
||||||
'./ui/Dialog',
|
|
||||||
'./Selection',
|
'./Selection',
|
||||||
'./api/objects/object-utils'
|
'./api/objects/object-utils'
|
||||||
], function (
|
], function (
|
||||||
@ -13,13 +12,21 @@ define([
|
|||||||
uuid,
|
uuid,
|
||||||
api,
|
api,
|
||||||
editObjectTemplate,
|
editObjectTemplate,
|
||||||
Dialog,
|
|
||||||
Selection,
|
Selection,
|
||||||
objectUtils
|
objectUtils
|
||||||
) {
|
) {
|
||||||
function MCT() {
|
function MCT() {
|
||||||
EventEmitter.call(this);
|
EventEmitter.call(this);
|
||||||
this.legacyBundle = { extensions: {} };
|
this.legacyBundle = { extensions: {
|
||||||
|
services: [
|
||||||
|
{
|
||||||
|
key: "mct",
|
||||||
|
implementation: function () {
|
||||||
|
return this;
|
||||||
|
}.bind(this)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} };
|
||||||
|
|
||||||
this.selection = new Selection();
|
this.selection = new Selection();
|
||||||
this.on('navigation', this.selection.clear.bind(this.selection));
|
this.on('navigation', this.selection.clear.bind(this.selection));
|
||||||
@ -94,13 +101,6 @@ define([
|
|||||||
region: region,
|
region: region,
|
||||||
key: viewKey
|
key: viewKey
|
||||||
});
|
});
|
||||||
|
|
||||||
this.legacyExtension('services', {
|
|
||||||
key: 'PublicAPI',
|
|
||||||
implementation: function () {
|
|
||||||
return this;
|
|
||||||
}.bind(this)
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MCT.prototype.type = function (key, type) {
|
MCT.prototype.type = function (key, type) {
|
||||||
@ -117,10 +117,6 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
MCT.prototype.dialog = function (view, title) {
|
|
||||||
return new Dialog(view, title).show();
|
|
||||||
};
|
|
||||||
|
|
||||||
MCT.prototype.start = function () {
|
MCT.prototype.start = function () {
|
||||||
this.legacyExtension('runs', {
|
this.legacyExtension('runs', {
|
||||||
depends: ['navigationService'],
|
depends: ['navigationService'],
|
||||||
@ -147,6 +143,7 @@ define([
|
|||||||
|
|
||||||
MCT.prototype.regions = {
|
MCT.prototype.regions = {
|
||||||
main: "MAIN",
|
main: "MAIN",
|
||||||
|
properties: "PROPERTIES",
|
||||||
toolbar: "TOOLBAR"
|
toolbar: "TOOLBAR"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
44
src/adapter/actions/ActionDialogDecorator.js
Normal file
44
src/adapter/actions/ActionDialogDecorator.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
define([
|
||||||
|
'../../api/objects/object-utils'
|
||||||
|
], function (objectUtils) {
|
||||||
|
function ActionDialogDecorator(mct, newViews, actionService) {
|
||||||
|
this.actionService = actionService;
|
||||||
|
this.mct = mct;
|
||||||
|
this.definitions = newViews.filter(function (newView) {
|
||||||
|
return newView.region === mct.regions.properties;
|
||||||
|
}).map(function (newView) {
|
||||||
|
return newView.factory;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionDialogDecorator.prototype.getActions = function (context) {
|
||||||
|
var mct = this.mct;
|
||||||
|
var definitions = this.definitions;
|
||||||
|
|
||||||
|
return this.actionService.getActions(context).map(function (action) {
|
||||||
|
if (action.dialogService) {
|
||||||
|
var domainObject = objectUtils.toNewFormat(
|
||||||
|
context.domainObject.getModel(),
|
||||||
|
objectUtils.parseKeyString(context.domainObject.getId())
|
||||||
|
);
|
||||||
|
|
||||||
|
definitions = definitions.filter(function (definition) {
|
||||||
|
return definition.canView(domainObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (definitions.length > 0) {
|
||||||
|
action.dialogService = Object.create(action.dialogService);
|
||||||
|
action.dialogService.getUserInput = function (form, value) {
|
||||||
|
return new mct.Dialog(
|
||||||
|
definitions[0].view(context.domainObject),
|
||||||
|
form.title
|
||||||
|
).show();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return action;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return ActionDialogDecorator;
|
||||||
|
});
|
@ -1,13 +1,17 @@
|
|||||||
define([
|
define([
|
||||||
'legacyRegistry',
|
'legacyRegistry',
|
||||||
|
'./actions/ActionDialogDecorator',
|
||||||
'./directives/MCTView',
|
'./directives/MCTView',
|
||||||
'./services/Instantiate',
|
'./services/Instantiate',
|
||||||
'./capabilities/APICapabilityDecorator'
|
'./capabilities/APICapabilityDecorator',
|
||||||
|
'./policies/AdapterCompositionPolicy'
|
||||||
], function (
|
], function (
|
||||||
legacyRegistry,
|
legacyRegistry,
|
||||||
|
ActionDialogDecorator,
|
||||||
MCTView,
|
MCTView,
|
||||||
Instantiate,
|
Instantiate,
|
||||||
APICapabilityDecorator
|
APICapabilityDecorator,
|
||||||
|
AdapterCompositionPolicy
|
||||||
) {
|
) {
|
||||||
legacyRegistry.register('src/adapter', {
|
legacyRegistry.register('src/adapter', {
|
||||||
"extensions": {
|
"extensions": {
|
||||||
@ -17,7 +21,7 @@ define([
|
|||||||
implementation: MCTView,
|
implementation: MCTView,
|
||||||
depends: [
|
depends: [
|
||||||
"newViews[]",
|
"newViews[]",
|
||||||
"PublicAPI"
|
"mct"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -41,6 +45,19 @@ define([
|
|||||||
depends: [
|
depends: [
|
||||||
"$injector"
|
"$injector"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "decorator",
|
||||||
|
provides: "actionService",
|
||||||
|
implementation: ActionDialogDecorator,
|
||||||
|
depends: [ "mct", "newViews[]" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
policies: [
|
||||||
|
{
|
||||||
|
category: "composition",
|
||||||
|
implementation: AdapterCompositionPolicy,
|
||||||
|
depends: [ "mct" ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
26
src/adapter/policies/AdapterCompositionPolicy.js
Normal file
26
src/adapter/policies/AdapterCompositionPolicy.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
define([], function () {
|
||||||
|
function AdapterCompositionPolicy(mct) {
|
||||||
|
this.mct = mct;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdapterCompositionPolicy.prototype.allow = function (
|
||||||
|
containerType,
|
||||||
|
childType
|
||||||
|
) {
|
||||||
|
var containerObject = containerType.getInitialModel();
|
||||||
|
var childObject = childType.getInitialModel();
|
||||||
|
|
||||||
|
containerObject.type = containerType.getKey();
|
||||||
|
childObject.type = childType.getKey();
|
||||||
|
|
||||||
|
var composition = this.mct.Composition(containerObject);
|
||||||
|
|
||||||
|
if (composition) {
|
||||||
|
return composition.canContain(childObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return AdapterCompositionPolicy;
|
||||||
|
});
|
@ -3,19 +3,22 @@ define([
|
|||||||
'./TimeConductor',
|
'./TimeConductor',
|
||||||
'./View',
|
'./View',
|
||||||
'./objects/ObjectAPI',
|
'./objects/ObjectAPI',
|
||||||
'./composition/CompositionAPI'
|
'./composition/CompositionAPI',
|
||||||
|
'./ui/Dialog'
|
||||||
], function (
|
], function (
|
||||||
Type,
|
Type,
|
||||||
TimeConductor,
|
TimeConductor,
|
||||||
View,
|
View,
|
||||||
ObjectAPI,
|
ObjectAPI,
|
||||||
CompositionAPI
|
CompositionAPI,
|
||||||
|
Dialog
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
Type: Type,
|
Type: Type,
|
||||||
TimeConductor: new TimeConductor(),
|
TimeConductor: new TimeConductor(),
|
||||||
View: View,
|
View: View,
|
||||||
Objects: ObjectAPI,
|
Objects: ObjectAPI,
|
||||||
Composition: CompositionAPI
|
Composition: CompositionAPI,
|
||||||
|
Dialog: Dialog
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -52,6 +52,9 @@ define([
|
|||||||
if (!this._children) {
|
if (!this._children) {
|
||||||
throw new Error("Must load composition before you can add!");
|
throw new Error("Must load composition before you can add!");
|
||||||
}
|
}
|
||||||
|
if (!this.canContain(child)) {
|
||||||
|
throw new Error("This object cannot contain that object.");
|
||||||
|
}
|
||||||
if (this.contains(child)) {
|
if (this.contains(child)) {
|
||||||
if (skipMutate) {
|
if (skipMutate) {
|
||||||
return; // don't add twice, don't error.
|
return; // don't add twice, don't error.
|
||||||
@ -94,6 +97,10 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CompositionCollection.prototype.canContain = function (domainObject) {
|
||||||
|
return this.provider.canContain(this.domainObject, domainObject);
|
||||||
|
};
|
||||||
|
|
||||||
CompositionCollection.prototype.destroy = function () {
|
CompositionCollection.prototype.destroy = function () {
|
||||||
if (this.provider.off) {
|
if (this.provider.off) {
|
||||||
this.provider.off(
|
this.provider.off(
|
||||||
|
@ -59,6 +59,10 @@ define([
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DefaultCompositionProvider.prototype.canContain = function (domainObject, child) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
DefaultCompositionProvider.prototype.remove = function (domainObject, child) {
|
DefaultCompositionProvider.prototype.remove = function (domainObject, child) {
|
||||||
// TODO: this needs to be synchronized via mutation
|
// TODO: this needs to be synchronized via mutation
|
||||||
var index = domainObject.composition.indexOf(child);
|
var index = domainObject.composition.indexOf(child);
|
||||||
|
@ -2,9 +2,15 @@ define(['text!./dialog.html', 'zepto'], function (dialogTemplate, $) {
|
|||||||
function Dialog(view, title) {
|
function Dialog(view, title) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
this.showing = false;
|
||||||
|
this.enabledState = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog.prototype.show = function () {
|
Dialog.prototype.show = function () {
|
||||||
|
if (this.showing) {
|
||||||
|
throw new Error("Dialog already showing.");
|
||||||
|
}
|
||||||
|
|
||||||
var $body = $('body');
|
var $body = $('body');
|
||||||
var $dialog = $(dialogTemplate);
|
var $dialog = $(dialogTemplate);
|
||||||
var $contents = $dialog.find('.contents .editor');
|
var $contents = $dialog.find('.contents .editor');
|
||||||
@ -13,31 +19,45 @@ define(['text!./dialog.html', 'zepto'], function (dialogTemplate, $) {
|
|||||||
var $ok = $dialog.find('.ok');
|
var $ok = $dialog.find('.ok');
|
||||||
var $cancel = $dialog.find('.cancel');
|
var $cancel = $dialog.find('.cancel');
|
||||||
|
|
||||||
var view = this.view;
|
|
||||||
|
|
||||||
function dismiss() {
|
|
||||||
$dialog.remove();
|
|
||||||
view.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.title) {
|
if (this.title) {
|
||||||
$dialog.find('.title').text(this.title);
|
$dialog.find('.title').text(this.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
$body.append($dialog);
|
$body.append($dialog);
|
||||||
this.view.show($contents[0]);
|
this.view.show($contents[0]);
|
||||||
|
this.$dialog = $dialog;
|
||||||
|
this.$ok = $ok;
|
||||||
|
this.showing = true;
|
||||||
|
|
||||||
|
[$ok, $cancel, $close].forEach(function ($button) {
|
||||||
|
$button.on('click', this.hide.bind(this));
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
$ok.on('click', resolve);
|
$ok.on('click', resolve);
|
||||||
$ok.on('click', dismiss);
|
|
||||||
|
|
||||||
$cancel.on('click', reject);
|
$cancel.on('click', reject);
|
||||||
$cancel.on('click', dismiss);
|
|
||||||
|
|
||||||
$close.on('click', reject);
|
$close.on('click', reject);
|
||||||
$close.on('click', dismiss);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Dialog.prototype.hide = function () {
|
||||||
|
if (!this.showing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$dialog.remove();
|
||||||
|
this.view.destroy();
|
||||||
|
this.showing = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Dialog.prototype.enabled = function (state) {
|
||||||
|
if (state !== undefined) {
|
||||||
|
this.enabledState = state;
|
||||||
|
if (this.showing) {
|
||||||
|
this.$ok.toggleClass('disabled', !state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.enabledState;
|
||||||
|
};
|
||||||
|
|
||||||
return Dialog;
|
return Dialog;
|
||||||
});
|
});
|
@ -31,8 +31,27 @@ define([
|
|||||||
this.setTaskStatus = this.setTaskStatus.bind(this);
|
this.setTaskStatus = this.setTaskStatus.bind(this);
|
||||||
this.selectTask = this.selectTask.bind(this);
|
this.selectTask = this.selectTask.bind(this);
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
this.mutableObject = mct.Objects.getMutable(domainObject);
|
this.mutableObject = mct.Objects.getMutable(domainObject);
|
||||||
this.mutableObject.on('tasks', this.updateTasks.bind(this));
|
this.mutableObject.on('tasks', this.updateTasks.bind(this));
|
||||||
|
=======
|
||||||
|
//If anything on object changes, re-render view
|
||||||
|
this.mutableObject.on("*", this.objectChanged);
|
||||||
|
};
|
||||||
|
|
||||||
|
TodoView.prototype.show = function (container) {
|
||||||
|
var self = this;
|
||||||
|
this.destroy();
|
||||||
|
|
||||||
|
self.$els = $(todoTemplate);
|
||||||
|
self.$buttons = {
|
||||||
|
all: self.$els.find('.example-todo-button-all'),
|
||||||
|
incomplete: self.$els.find('.example-todo-button-incomplete'),
|
||||||
|
complete: self.$els.find('.example-todo-button-complete')
|
||||||
|
};
|
||||||
|
|
||||||
|
$(container).empty().append(self.$els);
|
||||||
|
>>>>>>> origin/api-tutorials
|
||||||
|
|
||||||
this.$el = $(todoTemplate);
|
this.$el = $(todoTemplate);
|
||||||
this.$emptyMessage = this.$el.find('.example-no-tasks');
|
this.$emptyMessage = this.$el.find('.example-no-tasks');
|
||||||
@ -41,6 +60,7 @@ define([
|
|||||||
this.$el.on('change', 'li', this.setTaskStatus.bind(this));
|
this.$el.on('change', 'li', this.setTaskStatus.bind(this));
|
||||||
this.$el.on('click', '.example-task-description', this.selectTask.bind(this));
|
this.$el.on('click', '.example-task-description', this.selectTask.bind(this));
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
this.updateSelection = this.updateSelection.bind(this);
|
this.updateSelection = this.updateSelection.bind(this);
|
||||||
mct.selection.on('change', this.updateSelection);
|
mct.selection.on('change', this.updateSelection);
|
||||||
}
|
}
|
||||||
@ -48,6 +68,12 @@ define([
|
|||||||
TodoView.prototype.show = function (container) {
|
TodoView.prototype.show = function (container) {
|
||||||
$(container).empty().append(this.$el);
|
$(container).empty().append(this.$el);
|
||||||
this.render();
|
this.render();
|
||||||
|
=======
|
||||||
|
self.initialize();
|
||||||
|
self.objectChanged(this.domainObject);
|
||||||
|
|
||||||
|
mct.selection.on('change', self.render);
|
||||||
|
>>>>>>> origin/api-tutorials
|
||||||
};
|
};
|
||||||
|
|
||||||
TodoView.prototype.destroy = function () {
|
TodoView.prototype.destroy = function () {
|
||||||
@ -166,19 +192,58 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
TodoToolbarView.prototype.show = function (container) {
|
TodoToolbarView.prototype.show = function (container) {
|
||||||
$(container).empty().append(this.$el);
|
var self = this;
|
||||||
|
this.destroy();
|
||||||
|
this.$els = $(toolbarTemplate);
|
||||||
this.render();
|
this.render();
|
||||||
|
$(container).append(this.$els);
|
||||||
};
|
};
|
||||||
|
|
||||||
TodoToolbarView.prototype.render = function () {
|
TodoToolbarView.prototype.render = function () {
|
||||||
this.$remove.toggle(this.selection >= 0);
|
var self = this;
|
||||||
|
var $els = this.$els;
|
||||||
|
|
||||||
|
self.mutableObject = mct.Objects.getMutable(this.domainObject);
|
||||||
|
|
||||||
|
var $add = $els.find('a.example-add');
|
||||||
|
var $remove = $els.find('a.example-remove');
|
||||||
|
|
||||||
|
$add.on('click', function () {
|
||||||
|
var $dialog = $(dialogTemplate),
|
||||||
|
view = {
|
||||||
|
show: function (container) {
|
||||||
|
$(container).append($dialog);
|
||||||
|
},
|
||||||
|
destroy: function () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TodoToolbarView.prototype.handleSelectionChange = function (selection) {
|
new mct.Dialog(view, "Add a Task").show().then(function () {
|
||||||
if (selection && selection.length) {
|
var description = $dialog.find('input').val();
|
||||||
this.selection = selection[0].index;
|
var tasks = self.mutableObject.get('tasks');
|
||||||
} else {
|
tasks.push({ description: description });
|
||||||
this.selection = -1;
|
self.mutableObject.set('tasks', tasks);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$remove.on('click', function () {
|
||||||
|
var index = mct.selection.selected()[0].index;
|
||||||
|
if (index !== undefined) {
|
||||||
|
var tasks = self.mutableObject.get('tasks').filter(function (t, i) {
|
||||||
|
return i !== index;
|
||||||
|
});
|
||||||
|
self.mutableObject.set("tasks", tasks);
|
||||||
|
self.mutableObject.set("selected", undefined);
|
||||||
|
mct.selection.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.$remove = $remove;
|
||||||
|
self.handleSelectionChange();
|
||||||
|
mct.selection.on('change', self.handleSelectionChange);
|
||||||
|
};
|
||||||
|
|
||||||
|
TodoToolbarView.prototype.handleSelectionChange = function () {
|
||||||
|
var selected = mct.selection.selected();
|
||||||
|
if (this.$remove) {
|
||||||
|
this.$remove.toggle(selected.length > 0);
|
||||||
}
|
}
|
||||||
this.render();
|
this.render();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user