Added the object list Inspector editor.

This commit is contained in:
alekseybobkov 2015-09-24 21:16:28 -07:00
parent 83b4994d61
commit e54352b62e
10 changed files with 737 additions and 66 deletions

View File

@ -235,7 +235,7 @@
$form.request('onInspectableGetOptions', {
data: data,
}).done(function optionsRequestDoneClosure(data) {
}).done(function dropdownOptionsRequestDoneClosure(data) {
self.optionsRequestDone(data, currentValue, true)
}).always(
this.proxy(this.hideLoadingIndicator)

View File

@ -0,0 +1,503 @@
/*
* Inspector object list editor class.
*/
+function ($) { "use strict";
var Base = $.oc.inspector.propertyEditors.base,
BaseProto = Base.prototype
var ObjectListEditor = function(inspector, propertyDefinition, containerCell) {
this.currentRowInspector = null
this.popup = null
if (propertyDefinition.titleProperty === undefined) {
throw new Error('The titleProperty property should be specified in the objectList editor configuration. Property: ' + propertyDefinition.property)
}
if (propertyDefinition.itemProperties === undefined) {
throw new Error('The itemProperties property should be specified in the objectList editor configuration. Property: ' + propertyDefinition.property)
}
Base.call(this, inspector, propertyDefinition, containerCell)
}
ObjectListEditor.prototype = Object.create(BaseProto)
ObjectListEditor.prototype.constructor = Base
ObjectListEditor.prototype.dispose = function() {
this.unregisterHandlers()
this.removeControls()
this.currentRowInspector = null
this.popup = null
BaseProto.dispose.call(this)
}
//
// Building
//
ObjectListEditor.prototype.build = function() {
var link = document.createElement('a')
$.oc.foundation.element.addClass(link, 'trigger')
link.setAttribute('href', '#')
this.setLinkText(link)
$.oc.foundation.element.addClass(this.containerCell, 'trigger-cell')
this.containerCell.appendChild(link)
}
ObjectListEditor.prototype.setLinkText = function(link, value) {
var value = value !== undefined ? value
: this.inspector.getPropertyValue(this.propertyDefinition.property)
if (value === undefined) {
var placeholder = this.propertyDefinition.placeholder
if (placeholder !== undefined) {
$.oc.foundation.element.addClass(link, 'placeholder')
link.textContent = placeholder
}
else {
link.textContent = 'Items: 0'
}
}
else {
if (value.length === undefined) {
throw new Error('Object list value an array. Property: ' + this.propertyDefinition.property)
}
$.oc.foundation.element.removeClass(link, 'placeholder')
link.textContent = 'Items: ' + value.length
}
}
ObjectListEditor.prototype.getPopupContent = function() {
return '<form> \
<div class="modal-header"> \
<button type="button" class="close" data-dismiss="popup">&times;</button> \
<h4 class="modal-title">{{property}}</h4> \
</div> \
<div> \
<div class="layout inspector-columns-editor"> \
<div class="layout-row"> \
<div class="layout-cell"> \
<div class="layout-relative"> \
<div class="layout"> \
<div class="layout-row min-size"> \
<div class="control-toolbar toolbar-padded"> \
<div class="toolbar-item"> \
<div class="btn-group"> \
<button type="button" class="btn btn-primary \
oc-icon-plus" \
data-cmd="create-item">Add</button> \
<button type="button" class="btn btn-default \
empty oc-icon-trash-o" \
data-cmd="delete-item"></button> \
</div> \
</div> \
</div> \
</div> \
<div class="layout-row"> \
<div class="layout-cell"> \
<div class="layout-relative"> \
<div class="layout-absolute"> \
<div class="control-scrollpad" \
data-control="scrollpad"> \
<div class="scroll-wrapper"> \
<table class="table data \
no-offset-bottom \
inspector-table-list"> \
</table> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
<div class="layout-cell"> \
<div class="layout-relative"> \
<div class="layout-absolute"> \
<div class="control-scrollpad" data-control="scrollpad"> \
<div class="scroll-wrapper inspector-wrapper"> \
<div data-inspector-container> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
<div class="modal-footer"> \
<button type="submit" class="btn btn-primary">OK</button> \
<button type="button" class="btn btn-default"data-dismiss="popup">Cancel</button> \
</div> \
</form>'
}
ObjectListEditor.prototype.buildPopupContents = function(popup) {
this.buildItemsTable(popup)
}
ObjectListEditor.prototype.buildItemsTable = function(popup) {
var table = popup.querySelector('table'),
tbody = document.createElement('tbody'),
items = this.inspector.getPropertyValue(this.propertyDefinition.property),
titleProperty = this.propertyDefinition.titleProperty
if (items === undefined || items.length === 0) {
var row = this.buildEmptyRow()
tbody.appendChild(row)
}
else {
var firstRow = undefined
for (var i = 0, len = items.length; i < len; i++) {
var item = items[i],
itemText = item[titleProperty],
row = this.buildTableRow(itemText, 'rowlink')
row.setAttribute('data-inspector-values', JSON.stringify(item))
tbody.appendChild(row)
if (firstRow === undefined) {
firstRow = row
}
}
}
table.appendChild(tbody)
if (firstRow !== undefined) {
this.selectRow(firstRow)
}
this.updateScrollpads()
}
ObjectListEditor.prototype.buildEmptyRow = function() {
return this.buildTableRow('No items found', 'no-data', 'nolink')
}
ObjectListEditor.prototype.removeEmptyRow = function() {
var tbody = this.getTableBody(),
row = tbody.querySelector('tr.no-data')
if (row) {
tbody.removeChild(row)
}
}
ObjectListEditor.prototype.buildTableRow = function(text, rowClass, cellClass) {
var row = document.createElement('tr'),
cell = document.createElement('td')
cell.textContent = text
if (rowClass !== undefined) {
$.oc.foundation.element.addClass(row, rowClass)
}
if (cellClass !== undefined) {
$.oc.foundation.element.addClass(cell, cellClass)
}
row.appendChild(cell)
return row
}
ObjectListEditor.prototype.updateScrollpads = function() {
$('.control-scrollpad', this.popup).scrollpad('update')
}
//
// Built-in Inspector management
//
ObjectListEditor.prototype.selectRow = function(row) {
var tbody = row.parentNode,
inspectorContainer = this.getInspectorContainer(),
selectedRow = this.getSelectedRow()
if (selectedRow) {
// TODO: validation of the currently existing Inspector is required
this.applyDataToRow(selectedRow)
$.oc.foundation.element.removeClass(selectedRow, 'active')
}
this.disposeInspector()
$.oc.foundation.element.addClass(row, 'active')
this.createInspectorForRow(row, inspectorContainer)
}
ObjectListEditor.prototype.createInspectorForRow = function(row, inspectorContainer) {
var dataStr = row.getAttribute('data-inspector-values')
if (dataStr === undefined || typeof dataStr !== 'string') {
throw new Error('Values not found for the selected row.')
}
var properties = this.propertyDefinition.itemProperties,
values = $.parseJSON(dataStr),
options = {
enableExternalParameterEditor: false,
onChange: this.proxy(this.onInspectorDataChange)
}
this.currentRowInspector = new $.oc.inspector.surface(inspectorContainer, properties, values,
$.oc.inspector.helpers.generateElementUniqueId(inspectorContainer), options)
}
ObjectListEditor.prototype.disposeInspector = function() {
$.oc.foundation.controlUtils.disposeControls(this.popup)
this.currentRowInspector = null
}
ObjectListEditor.prototype.applyDataToRow = function(row) {
if (this.currentRowInspector === null) {
return
}
var data = this.currentRowInspector.getValues()
row.setAttribute('data-inspector-values', JSON.stringify(data))
}
ObjectListEditor.prototype.updateRowText = function(property, value) {
var selectedRow = this.getSelectedRow()
if (!selectedRow) {
throw new Exception('A row is not found for the updated data')
}
if (property !== this.propertyDefinition.titleProperty) {
return
}
selectedRow.firstChild.textContent = value
}
ObjectListEditor.prototype.getSelectedRow = function() {
if (!this.popup) {
throw new Error('Trying to get selected row without a popup reference.')
}
var rows = this.getTableBody().children
for (var i = 0, len = rows.length; i < len; i++) {
if ($.oc.foundation.element.hasClass(rows[i], 'active')) {
return rows[i]
}
}
return null
}
ObjectListEditor.prototype.createItem = function() {
var selectedRow = this.getSelectedRow()
if (selectedRow) {
// TODO: validation of the currently existing Inspector is required
this.applyDataToRow(selectedRow)
$.oc.foundation.element.removeClass(selectedRow, 'active')
}
this.disposeInspector()
var title = 'New item',
row = this.buildTableRow(title, 'rowlink active'),
tbody = this.getTableBody(),
data = {}
data[this.propertyDefinition.titleProperty] = title
row.setAttribute('data-inspector-values', JSON.stringify(data))
tbody.appendChild(row)
this.selectRow(row)
this.removeEmptyRow()
this.updateScrollpads()
}
ObjectListEditor.prototype.deleteItem = function() {
var selectedRow = this.getSelectedRow()
if (!selectedRow) {
return
}
var nextRow = selectedRow.nextElementSibling,
prevRow = selectedRow.previousElementSibling,
tbody = this.getTableBody()
this.disposeInspector()
tbody.removeChild(selectedRow)
var newSelectedRow = nextRow ? nextRow : prevRow
if (newSelectedRow) {
this.selectRow(newSelectedRow)
} else {
tbody.appendChild(this.buildEmptyRow())
}
this.updateScrollpads()
}
ObjectListEditor.prototype.applyDataToParentInspector = function() {
var selectedRow = this.getSelectedRow(),
tbody = this.getTableBody(),
dataRows = tbody.querySelectorAll('tr[data-inspector-values]'),
link = this.getLink(),
result = []
if (selectedRow) {
// TODO: validation of the currently existing Inspector is required
this.applyDataToRow(selectedRow)
}
for (var i = 0, len = dataRows.length; i < len; i++) {
var dataRow = dataRows[i]
result.push($.parseJSON(dataRow.getAttribute('data-inspector-values')))
}
this.inspector.setPropertyValue(this.propertyDefinition.property, result)
this.setLinkText(link, result)
$(link).popup('hide')
return false
}
//
// Helpers
//
ObjectListEditor.prototype.getLink = function() {
return this.containerCell.querySelector('a.trigger')
}
ObjectListEditor.prototype.getPopupFormElement = function() {
var form = this.popup.querySelector('form')
if (!form) {
throw new Error('Cannot find form element in the popup window.')
}
return form
}
ObjectListEditor.prototype.getInspectorContainer = function() {
return this.popup.querySelector('div[data-inspector-container]')
}
ObjectListEditor.prototype.getTableBody = function() {
return this.popup.querySelector('table.inspector-table-list tbody')
}
//
// Event handlers
//
ObjectListEditor.prototype.registerHandlers = function() {
var link = this.getLink(),
$link = $(link)
link.addEventListener('click', this.proxy(this.onTriggerClick))
$link.on('shown.oc.popup', this.proxy(this.onPopupShown))
$link.on('hidden.oc.popup', this.proxy(this.onPopupHidden))
}
ObjectListEditor.prototype.unregisterHandlers = function() {
var link = this.getLink(),
$link = $(link)
link.removeEventListener('click', this.proxy(this.onTriggerClick))
$link.off('shown.oc.popup', this.proxy(this.onPopupShown))
$link.off('hidden.oc.popup', this.proxy(this.onPopupHidden))
}
ObjectListEditor.prototype.onTriggerClick = function(ev) {
$.oc.foundation.event.stop(ev)
var content = this.getPopupContent()
content = content.replace('{{property}}', this.propertyDefinition.title)
$(ev.target).popup({
content: content
})
return false
}
ObjectListEditor.prototype.onPopupShown = function(ev, link, popup) {
$(popup).on('submit.inspector', 'form', this.proxy(this.onSubmit))
$(popup).on('click', 'tr.rowlink', this.proxy(this.onRowClick))
$(popup).on('click.inspector', '[data-cmd]', this.proxy(this.onCommand))
this.popup = popup.get(0)
this.buildPopupContents(this.popup)
}
ObjectListEditor.prototype.onPopupHidden = function(ev, link, popup) {
$(popup).off('.inspector', this.proxy(this.onSubmit))
$(popup).off('click', 'tr.rowlink', this.proxy(this.onRowClick))
$(popup).off('click.inspector', '[data-cmd]', this.proxy(this.onCommand))
this.disposeInspector()
this.popup = null
}
ObjectListEditor.prototype.onSubmit = function(ev) {
this.applyDataToParentInspector()
ev.preventDefault()
return false
}
ObjectListEditor.prototype.onRowClick = function(ev) {
this.selectRow(ev.currentTarget)
}
ObjectListEditor.prototype.onInspectorDataChange = function(property, value) {
this.updateRowText(property, value)
}
ObjectListEditor.prototype.onCommand = function(ev) {
var command = ev.currentTarget.getAttribute('data-cmd')
switch (command) {
case 'create-item' :
this.createItem()
break;
case 'delete-item' :
this.deleteItem()
break;
}
}
//
// Disposing
//
ObjectListEditor.prototype.removeControls = function() {
if (this.popup) {
this.disposeInspector(this.popup)
}
}
$.oc.inspector.propertyEditors.objectList = ObjectListEditor
}(window.jQuery);

View File

@ -10,6 +10,7 @@
var SetEditor = function(inspector, propertyDefinition, containerCell) {
this.editors = []
this.loadedItems = null
Base.call(this, inspector, propertyDefinition, containerCell)
}
@ -19,6 +20,7 @@
SetEditor.prototype.dispose = function() {
this.disposeEditors()
this.disposeControls()
this.editors = null
@ -30,10 +32,6 @@
//
SetEditor.prototype.build = function() {
if (!this.propertyDefinition.items) {
throw new Error('The items are not defined for the set-typed property "' + this.propertyDefinition.property + '"')
}
var link = document.createElement('a')
$.oc.foundation.element.addClass(link, 'trigger')
@ -41,10 +39,19 @@
link.setAttribute('data-group-index', this.getGroupIndex())
this.setLinkText(link)
$.oc.foundation.element.addClass(this.containerCell, 'set')
$.oc.foundation.element.addClass(this.containerCell, 'trigger-cell')
this.containerCell.appendChild(link)
if (this.propertyDefinition.items !== undefined) {
this.loadStaticItems()
}
else {
this.loadDynamicItems()
}
}
SetEditor.prototype.loadStaticItems = function() {
for (var itemValue in this.propertyDefinition.items) {
this.buildItemEditor(itemValue, this.propertyDefinition.items[itemValue])
}
@ -52,14 +59,14 @@
SetEditor.prototype.setLinkText = function(link, value) {
var value = value !== undefined ? value
: this.inspector.getPropertyValue(this.propertyDefinition.property),
text = '[]'
: this.getNormalizedValue(),
text = '[ ]'
if (value === undefined) {
value = this.propertyDefinition.default
}
if (value !== undefined && value.length !== undefined && value.length > 0) {
if (value !== undefined && value.length !== undefined && value.length > 0 && typeof value !== 'string') {
var textValues = []
for (var i = 0, len = value.length; i < len; i++) {
textValues.push(this.valueToText(value[i]))
@ -108,7 +115,48 @@
return this.propertyDefinition.default.indexOf(value) > -1
}
//
// Dynamic items
//
SetEditor.prototype.showLoadingIndicator = function() {
$(this.getLink()).loadIndicator()
}
SetEditor.prototype.hideLoadingIndicator = function() {
$(this.getLink()).loadIndicator('hide')
}
SetEditor.prototype.loadDynamicItems = function() {
var link = this.getLink(),
data = this.inspector.getValues(),
$form = $(link).closest('form')
$.oc.foundation.element.addClass(link, 'loading-indicator-container size-small')
this.showLoadingIndicator()
$form.request('onInspectableGetOptions', {
data: data,
})
.done(this.proxy(this.itemsRequestDone))
.always(this.proxy(this.hideLoadingIndicator))
}
SetEditor.prototype.itemsRequestDone = function(data, currentValue, initialization) {
this.loadedItems = {}
if (data.options) {
for (var i = 0, len = data.options.length; i < len; i++) {
this.buildItemEditor(data.options[i].value, data.options[i].title)
this.loadedItems[data.options[i].value] = data.options[i].title
}
}
this.setLinkText(this.getLink())
}
//
// Helpers
//
@ -117,20 +165,67 @@
return this.containerCell.querySelector('a.trigger')
}
SetEditor.prototype.getItemsSource = function() {
if (this.propertyDefinition.items !== undefined) {
return this.propertyDefinition.items
}
return this.loadedItems
}
SetEditor.prototype.valueToText = function(value) {
if (!this.propertyDefinition.items) {
var source = this.getItemsSource()
if (!source) {
return value
}
for (var itemValue in this.propertyDefinition.items) {
for (var itemValue in source) {
if (itemValue == value) {
return this.propertyDefinition.items[itemValue]
return source[itemValue]
}
}
return value
}
/*
* Removes items that don't exist in the defined items from
* the value.
*/
SetEditor.prototype.cleanUpValue = function(value) {
if (!value) {
return value
}
var result = [],
source = this.getItemsSource()
for (var i = 0, len = value.length; i < len; i++) {
var currentValue = value[i]
if (source[currentValue] !== undefined) {
result.push(currentValue)
}
}
return result
}
SetEditor.prototype.getNormalizedValue = function() {
var value = this.inspector.getPropertyValue(this.propertyDefinition.property)
if (value === undefined) {
return value
}
if (value.length === undefined || typeof value === 'string') {
return undefined
}
return value
}
//
// Editor API methods
//
@ -159,7 +254,7 @@
// current set value is [create] and checkboxValue is "create".
// The result of the method will be TRUE.
var value = this.inspector.getPropertyValue(this.propertyDefinition.property)
var value = this.getNormalizedValue()
if (value === undefined) {
return this.isCheckedByDefault(checkboxValue)
@ -173,7 +268,7 @@
}
SetEditor.prototype.setPropertyValue = function(checkboxValue, isChecked) {
var currentValue = this.inspector.getPropertyValue(this.propertyDefinition.property)
var currentValue = this.getNormalizedValue()
if (currentValue === undefined) {
currentValue = this.propertyDefinition.default
@ -195,7 +290,7 @@
}
}
this.inspector.setPropertyValue(this.propertyDefinition.property, currentValue)
this.inspector.setPropertyValue(this.propertyDefinition.property, this.cleanUpValue(currentValue))
this.setLinkText(this.getLink())
}
@ -215,5 +310,15 @@
}
}
SetEditor.prototype.disposeControls = function() {
var link = this.getLink()
if (this.propertyDefinition.items === undefined) {
$(link).loadIndicator('destroy')
}
link.parentNode.removeChild(link)
}
$.oc.inspector.propertyEditors.set = SetEditor
}(window.jQuery);

View File

@ -26,7 +26,7 @@
link.setAttribute('href', '#')
this.setLinkText(link)
$.oc.foundation.element.addClass(this.containerCell, 'text-multiline')
$.oc.foundation.element.addClass(this.containerCell, 'trigger-cell')
this.containerCell.appendChild(link)
}

View File

@ -76,6 +76,7 @@
this.externalParameterEditors = null
this.values = null
this.originalValues = null
this.options.onChange = null
BaseProto.dispose.call(this)
}
@ -230,16 +231,11 @@
}
}
Surface.prototype.applyGroupIndexAttribute = function(property, row) {
if (property.groupIndex !== undefined && property.itemType == 'property') {
row.setAttribute('data-group-index', property.groupIndex)
}
}
Surface.prototype.getRowCssClass = function(property) {
var result = property.itemType
if (property.itemType == 'property' && property.groupIndex !== undefined) {
// The property.groupedControl flag doesn't allow to collapse the grouped control row itself.
if (property.itemType == 'property' && property.groupIndex !== undefined && !property.groupedControl) {
result += ' grouped'
result += this.isGroupExpanded(property.group) ? ' expanded' : ' collapsed'
}
@ -315,6 +311,12 @@
// Field grouping
//
Surface.prototype.applyGroupIndexAttribute = function(property, row) {
if (property.groupIndex !== undefined && property.itemType == 'property' && !property.groupedControl) {
row.setAttribute('data-group-index', property.groupIndex)
}
}
Surface.prototype.isGroupExpanded = function(group) {
var statuses = this.loadGroupStatuses()
@ -417,6 +419,7 @@
$.oc.foundation.element.addClass(row, 'control-group')
property.groupIndex = editor.getGroupIndex()
property.groupedControl = true
this.buildGroupExpandControl(row.querySelector('span.title-element'), property, true)
}
@ -437,46 +440,11 @@
return this.values[property]
}
Surface.prototype.getValues = function() {
var result = {}
// TODO: implement validation in this method. It should be optional,
// as the method is used by other classes internally, but the validation
// is required only for the external callers.
for (var i=0, len = this.parsedProperties.properties.length; i < len; i++) {
var property = this.parsedProperties.properties[i]
if (property.itemType !== 'property') {
continue
}
var value = null,
externalParameterEditor = this.findExternalParameterEditor(property.property)
if (!externalParameterEditor || !externalParameterEditor.isEditorVisible()) {
value = this.getPropertyValue(property.property)
if (value === undefined) {
value = property.default
}
}
else {
value = externalParameterEditor.getValue()
value = '{{ ' + value + ' }}'
}
result[property.property] = value
}
return result
}
Surface.prototype.setPropertyValue = function(property, value, supressChangeEvents, forceEditorUpdate) {
this.values[property] = value
if (!supressChangeEvents) {
if (this.originalValues[property] === undefined || this.originalValues[property] != value) {
if (this.originalValues[property] === undefined || !this.comparePropertyValues(this.originalValues[property], value)) {
this.markPropertyChanged(property, true)
}
else {
@ -484,6 +452,10 @@
}
this.notifyEditorsPropertyChanged(property, value)
if (this.options.onChange !== null) {
this.options.onChange(property, value)
}
}
if (forceEditorUpdate) {
@ -598,6 +570,61 @@
return div.innerHTML
}
Surface.prototype.comparePropertyValues = function(oldValue, newValue) {
if (oldValue === undefined && newValue !== undefined) {
return false
}
if (oldValue !== undefined && newValue === undefined) {
return false
}
if (typeof oldValue == 'object' && typeof newValue == 'object') {
return JSON.stringify(oldValue) == JSON.stringify(newValue)
}
return oldValue == newValue
}
//
// External API
//
Surface.prototype.getValues = function() {
var result = {}
// TODO: implement validation in this method. It should be optional,
// as the method is used by other classes internally, but the validation
// is required only for the external callers.
for (var i=0, len = this.parsedProperties.properties.length; i < len; i++) {
var property = this.parsedProperties.properties[i]
if (property.itemType !== 'property') {
continue
}
var value = null,
externalParameterEditor = this.findExternalParameterEditor(property.property)
if (!externalParameterEditor || !externalParameterEditor.isEditorVisible()) {
value = this.getPropertyValue(property.property)
if (value === undefined) {
value = property.default
}
}
else {
value = externalParameterEditor.getValue()
value = '{{ ' + value + ' }}'
}
result[property.property] = value
}
return result
}
// EVENT HANDLERS
//
@ -614,7 +641,8 @@
// ============================
Surface.DEFAULTS = {
enableExternalParameterEditor: false
enableExternalParameterEditor: false,
onChange: null
}
// REGISTRATION

View File

@ -54,6 +54,11 @@
this.tally++
}
LoadIndicator.prototype.destroy = function() {
this.$el.removeData('oc.loadIndicator')
this.$el = null
}
LoadIndicator.DEFAULTS = {
text: ''
}

View File

@ -116,9 +116,12 @@
}
}
&.text-multiline, &.set {
&.trigger-cell {
padding: 0!important;
a.trigger {
display: block;
padding: 5px 12px 7px 12px;
overflow: hidden;
text-overflow: ellipsis;
color: @color-inspector-text;
@ -127,6 +130,16 @@
&.placeholder {
color: #b5babd;
}
.loading-indicator {
background-color: @color-inspector-bg;
span {
margin-top: -12px;
right: 10px;
left: auto;
}
}
}
}
@ -317,7 +330,7 @@
.select2-selection {
background: transparent;
height: 30px;
height: 29px;
line-height: 29px;
padding: 0 3px 0 12px;
.border-radius(0) !important;

View File

@ -34,6 +34,10 @@ table.table.data {
font-size: 12px;
&.no-offset-bottom {
margin-bottom: 0!important;
}
thead {
background: @color-list-head-bg;
@ -228,6 +232,12 @@ table.table.data {
}
}
&.no-active-indicator tbody {
tr td:first-child {
border-left: none;
}
}
tfoot {
a { color: @color-list-text; text-decoration: none; }
td, th {

View File

@ -1786,6 +1786,8 @@ if(this.options.opaque!==undefined){indicator.addClass('is-opaque')}
this.$el.prepend(indicator)
this.$el.addClass('in-progress')
this.tally++}
LoadIndicator.prototype.destroy=function(){this.$el.removeData('oc.loadIndicator')
this.$el=null}
LoadIndicator.DEFAULTS={text:''}
var old=$.fn.loadIndicator
$.fn.loadIndicator=function(option){var args=arguments;return this.each(function(){var $this=$(this)

View File

@ -2320,6 +2320,7 @@ table td[class*="col-"],table th[class*="col-"]{position:static;float:none;displ
.table-responsive > .table-bordered > tbody > tr:last-child > th,.table-responsive > .table-bordered > tfoot > tr:last-child > th,.table-responsive > .table-bordered > tbody > tr:last-child > td,.table-responsive > .table-bordered > tfoot > tr:last-child > td{border-bottom:0}
}
table.table.data{font-size:12px}
table.table.data.no-offset-bottom{margin-bottom:0 !important}
table.table.data thead{background:#ffffff}
table.table.data thead td,table.table.data thead th{border-width:1px;border-top:1px solid #e2e2e2 !important;border-color:#e2e2e2;padding:0;font-weight:normal}
table.table.data thead td > a,table.table.data thead th > a,table.table.data thead td > span,table.table.data thead th > span{display:block;padding:13px 15px;text-transform:uppercase;color:#333333;text-decoration:none}
@ -2359,6 +2360,7 @@ table.table.data tbody td.column-slim{padding-left:0;padding-right:0}
table.table.data tbody.icons td i[class^="icon-"]{display:inline-block;margin-right:7px;font-size:15px;color:#95a5a6;position:relative;top:1px}
table.table.data tbody.clickable{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
table.table.data tbody td.column-compact{padding:0}
table.table.data.no-active-indicator tbody tr td:first-child{border-left:none}
table.table.data tfoot a{color:#666666;text-decoration:none}
table.table.data tfoot td,table.table.data tfoot th{border-color:#e2e2e2;padding:10px 15px}
table.table.data th.list-cell-type-switch,table.table.data td.list-cell-type-switch{text-align:center}
@ -2440,8 +2442,11 @@ table.table.data tr.list-tree-level-10 td.list-cell-index-1{padding-left:125px}
.inspector-fields td.text input[type=text]::-moz-placeholder{font-weight:normal !important;color:#b5babd}
.inspector-fields td.text input[type=text]:-ms-input-placeholder{font-weight:normal !important;color:#b5babd}
.inspector-fields td.text.active{background:#ffffff;border-left:1px solid #c8cccd}
.inspector-fields td.text-multiline a.trigger,.inspector-fields td.set a.trigger{display:block;overflow:hidden;text-overflow:ellipsis;color:#333333;text-decoration:none}
.inspector-fields td.text-multiline a.trigger.placeholder,.inspector-fields td.set a.trigger.placeholder{color:#b5babd}
.inspector-fields td.trigger-cell{padding:0 !important}
.inspector-fields td.trigger-cell a.trigger{display:block;padding:5px 12px 7px 12px;overflow:hidden;text-overflow:ellipsis;color:#333333;text-decoration:none}
.inspector-fields td.trigger-cell a.trigger.placeholder{color:#b5babd}
.inspector-fields td.trigger-cell a.trigger .loading-indicator{background-color:#f2f2f2}
.inspector-fields td.trigger-cell a.trigger .loading-indicator span{margin-top:-12px;right:10px;left:auto}
.inspector-fields td.dropdown{padding:0 !important}
.inspector-fields td select{width:90%}
.inspector-fields td div.external-param-editor-container{position:relative;padding-right:15px}
@ -2467,7 +2472,7 @@ table.table.data tr.list-tree-level-10 td.list-cell-index-1{padding-left:125px}
.inspector-fields div.custom-checkbox{margin-top:0;margin-bottom:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.inspector-fields div.custom-checkbox label:before{top:-12px}
.inspector-fields .select2-container{width:100% !important}
.inspector-fields .select2-container .select2-selection{background:transparent;height:30px;line-height:29px;padding:0 3px 0 12px;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;border:none !important;font-size:12px}
.inspector-fields .select2-container .select2-selection{background:transparent;height:29px;line-height:29px;padding:0 3px 0 12px;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;border:none !important;font-size:12px}
.inspector-fields .select2-container .select2-selection.select2-default{font-weight:normal !important}
.inspector-fields .select2-container .loading-indicator > span{top:15px}
.inspector-fields .select2-container.select2-container--open{-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;border:none !important}