<commit_before>isic.views.UploadDatasetView = isic.View.extend({
    events: {
        'click #isic-upload-images': function (event) {
            this.$('#isic-upload-images').addClass('active');
            this.$('#isic-upload-metadata').removeClass('active');
            this.initializeUploadWidget();
            this.updateUploadWidget();
        },
        'click #isic-upload-metadata': function (event) {
            this.$('#isic-upload-images').removeClass('active');
            this.$('#isic-upload-metadata').addClass('active');
            this.initializeUploadWidget();
            this.updateUploadWidget();
        },
        'click #isic-upload-reset': function (event) {
            this.resetUpload();
        },
        'change input[name="attribution"]': function (event) {
            // Update attribution name field sensitivity
            var target = $(event.target);
            if (target.val() === 'anonymous') {
                this.$('#isic-dataset-attribution-name').prop('disabled', true);
            } else {
                this.$('#isic-dataset-attribution-name').prop('disabled', false);
            }
        },
        'change #isic-dataset-license': function (event) {
            // Disable anonymous attribution unless CC-0 license is selected
            var target = $(event.target);
            var anonymous = this.$('#isic-dataset-attribution-anonymous');
            if (target.val() === 'CC-0') {
                anonymous.prop('disabled', false);
            } else {
                if (anonymous.prop('checked')) {
                    this.$('#isic-dataset-attribution-attributed-to').prop('checked', true);
                    this.$('#isic-dataset-attribution-attributed-to').change();
                }
                anonymous.prop('disabled', true);
            }
        },
        'submit #isic-dataset-form': function (event) {
            event.preventDefault();
            this.$('#isic-dataset-submit').prop('disabled', true);
            this.submitDataset();
        }
    },

    initialize: function (settings) {
        this.uploadedZipFiles = [];
        this.uploadedCsvFiles = [];
        this.uploadFolder = null;

        this.render();
    },

    render: function () {
        this.$el.html(isic.templates.uploadDataset({
            user: girder.currentUser
        }));

        if (!this.uploadWidget) {
            this.initializeUploadWidget();
        }
        this.updateUploadWidget();

        this.$('input#isic-dataset-name').focus();

        return this;
    },

    initializeUploadWidget: function () {
        if (this.uploadWidget) {
            this.stopListening(this.uploadWidget);
            this.uploadWidget.destroy();
        }
        this.uploadWidget = new girder.views.UploadWidget({
            parentView: this,
            modal: false,
            noParent: true,
            title: false,
            overrideStart: true
        });

        this.uploadWidget.setElement(this.$('.isic-upload-widget-container'));

        this.listenTo(this.uploadWidget, 'g:filesChanged', this.filesSelected);
        this.listenTo(this.uploadWidget, 'g:uploadStarted', this.uploadStarted);
        this.listenTo(this.uploadWidget, 'g:uploadFinished', this.uploadFinished);
    },

    filesSelected: function (files) {
        // TODO: could validate based on file extension
    },
    uploadStarted: function (files) {
        // Prepare upload folder in user's home and start upload
        if (this.uploadFolder) {
            // Folder already created
            this.startUpload(this.uploadFolder);
        } else {
            // Create new upload folder with unique name
            this.uploadFolder = new girder.models.FolderModel({
                name: 'isic_upload_' + Date.now(),
                parentType: 'user',
                parentId: girder.currentUser.get('_id'),
                description: 'ISIC uploads'
            });

            this.uploadFolder.once('g:saved', function () {
                this.startUpload(this.uploadFolder);
            }, this).once('g:error', function () {
                girder.events.trigger('g:alert', {
                    icon: 'cancel',
                    text: 'Could not create upload folder.',
                    type: 'error',
                    timeout: 4000
                });
            }, this).save();
        }
    },

    uploadFinished: function (files) {
        var filenames = _.pluck(files.files, 'name');
        if (this.uploadingImages()) {
            this.uploadedZipFiles = filenames;
        } else {
            this.uploadedCsvFiles = filenames;
        }
        this.updateUploadWidget();
    },

    startUpload: function (folder) {
        // Configure upload widget and begin upload
        this.uploadWidget.parentType = 'folder';
        this.uploadWidget.parent = folder;
        this.uploadWidget.uploadNextFile();
    },

    submitDataset: function () {
        var name = $('#isic-dataset-name').val();
        var description = $('#isic-dataset-description').val();
        var license = $('#isic-dataset-license').val();
        var signature = $('#isic-dataset-agreement-signature').val();
        var anonymous = $('#isic-dataset-attribution-anonymous').prop('checked');
        var attribution = $('#isic-dataset-attribution-name').val();

        // Post dataset
        // TODO: processing happens synchronously; revisit using jobs?
        girder.restRequest({
            type: 'POST',
            path: 'dataset',
            data: {
                uploadFolderId: this.uploadFolder.id,
                name: name,
                description: description,
                license: license,
                signature: signature,
                anonymous: anonymous,
                attribution: attribution
            },
            error: null
        }).done(_.bind(function () {
            // TODO: if updated to use jobs, navigate to job status page instead
            girder.confirm({
                text: '
Dataset successfully submitted.
',
                yesClass: 'hidden',
                noText: 'OK',
                escapedHtml: true
            });
            isic.router.navigate('', {trigger: true});
        }, this)).error(_.bind(function (resp) {
            // TODO: add custom error dialog instead of using confirm dialog
            girder.confirm({
                text: '
Error submitting dataset

' + resp.responseJSON.message,
                yesClass: 'hidden',
                noText: 'OK',
                escapedHtml: true
            });
            this.$('#isic-dataset-submit').prop('disabled', false);
        }, this));
    },

    uploadingImages: function () {
        return (this.$('#isic-upload-images.active').length > 0);
    },

    updateUploadWidget: function () {
        var visible = false;
        var uploadList = [];
        var uploadingImages = this.uploadingImages();
        if (uploadingImages) {
            if (this.uploadedZipFiles.length) {
                visible = false;
                uploadList = this.uploadedZipFiles;
            } else {
                visible = true;
            }
        } else {
            if (this.uploadedCsvFiles.length) {
                visible = false;
                uploadList = this.uploadedCsvFiles;
            } else {
                visible = true;
            }
        }

        this.$('.isic-upload-description-container').toggle(visible);
        this.$('.isic-upload-description-zip').toggle(uploadingImages);
        this.$('.isic-upload-description-csv').toggle(!uploadingImages);
        this.$('.isic-upload-widget-container').toggle(visible);
        this.$('.isic-upload-reset-container').toggle(!visible);

        this.uploadWidget.render();
        this.$('.isic-upload-list').text(
            'Uploaded: ' + uploadList.join(', '));
    },

    resetUpload: function () {
        var uploadList = null;
        if (this.uploadingImages()) {
            uploadList = this.uploadedZipFiles;
        } else {
            uploadList = this.uploadedCsvFiles;
        }

        // Delete uploaded files
        _.each(uploadList, function (name) {
            var items = new girder.collections.ItemCollection();
            items.once('g:changed', function () {
                if (!items.isEmpty()) {
                    var item = items.first();
                    item.destroy();

                    while (uploadList.length) {
                        uploadList.pop();
                    }
                    this.updateUploadWidget();
                }
            }, this).fetch({
                name: name,
                folderId: this.uploadFolder.id
            });
        }, this);
    }
});

isic.router.route('uploadDataset', 'uploadDataset', function (id) {
    // Route to index if user doesn't have permission to contribute datasets
    var datasetModel = new isic.models.DatasetModel();
    datasetModel.userCanContribute(girder.currentUser, _.bind(function (datasetContributor) {
        if (datasetContributor) {
            girder.events.trigger('g:navigateTo', isic.views.UploadDatasetView);
        } else {
            isic.router.navigate('', {trigger: true});
        }
    }, this));
});
<commit_msg>Fix error when submitting upload form without uploading files<commit_after>isic.views.UploadDatasetView = isic.View.extend({
    events: {
        'click #isic-upload-images': function (event) {
            this.$('#isic-upload-images').addClass('active');
            this.$('#isic-upload-metadata').removeClass('active');
            this.initializeUploadWidget();
            this.updateUploadWidget();
        },
        'click #isic-upload-metadata': function (event) {
            this.$('#isic-upload-images').removeClass('active');
            this.$('#isic-upload-metadata').addClass('active');
            this.initializeUploadWidget();
            this.updateUploadWidget();
        },
        'click #isic-upload-reset': function (event) {
            this.resetUpload();
        },
        'change input[name="attribution"]': function (event) {
            // Update attribution name field sensitivity
            var target = $(event.target);
            if (target.val() === 'anonymous') {
                this.$('#isic-dataset-attribution-name').prop('disabled', true);
            } else {
                this.$('#isic-dataset-attribution-name').prop('disabled', false);
            }
        },
        'change #isic-dataset-license': function (event) {
            // Disable anonymous attribution unless CC-0 license is selected
            var target = $(event.target);
            var anonymous = this.$('#isic-dataset-attribution-anonymous');
            if (target.val() === 'CC-0') {
                anonymous.prop('disabled', false);
            } else {
                if (anonymous.prop('checked')) {
                    this.$('#isic-dataset-attribution-attributed-to').prop('checked', true);
                    this.$('#isic-dataset-attribution-attributed-to').change();
                }
                anonymous.prop('disabled', true);
            }
        },
        'submit #isic-dataset-form': function (event) {
            event.preventDefault();
            this.$('#isic-dataset-submit').prop('disabled', true);
            this.submitDataset();
        }
    },

    initialize: function (settings) {
        this.uploadedZipFiles = [];
        this.uploadedCsvFiles = [];
        this.uploadFolder = null;

        this.render();
    },

    render: function () {
        this.$el.html(isic.templates.uploadDataset({
            user: girder.currentUser
        }));

        if (!this.uploadWidget) {
            this.initializeUploadWidget();
        }
        this.updateUploadWidget();

        this.$('input#isic-dataset-name').focus();

        return this;
    },

    initializeUploadWidget: function () {
        if (this.uploadWidget) {
            this.stopListening(this.uploadWidget);
            this.uploadWidget.destroy();
        }
        this.uploadWidget = new girder.views.UploadWidget({
            parentView: this,
            modal: false,
            noParent: true,
            title: false,
            overrideStart: true
        });

        this.uploadWidget.setElement(this.$('.isic-upload-widget-container'));

        this.listenTo(this.uploadWidget, 'g:filesChanged', this.filesSelected);
        this.listenTo(this.uploadWidget, 'g:uploadStarted', this.uploadStarted);
        this.listenTo(this.uploadWidget, 'g:uploadFinished', this.uploadFinished);
    },

    filesSelected: function (files) {
        // TODO: could validate based on file extension
    },
    uploadStarted: function (files) {
        // Prepare upload folder in user's home and start upload
        if (this.uploadFolder) {
            // Folder already created
            this.startUpload(this.uploadFolder);
        } else {
            // Create new upload folder with unique name
            this.uploadFolder = new girder.models.FolderModel({
                name: 'isic_upload_' + Date.now(),
                parentType: 'user',
                parentId: girder.currentUser.get('_id'),
                description: 'ISIC uploads'
            });

            this.uploadFolder.once('g:saved', function () {
                this.startUpload(this.uploadFolder);
            }, this).once('g:error', function () {
                girder.events.trigger('g:alert', {
                    icon: 'cancel',
                    text: 'Could not create upload folder.',
                    type: 'error',
                    timeout: 4000
                });
            }, this).save();
        }
    },

    uploadFinished: function (files) {
        var filenames = _.pluck(files.files, 'name');
        if (this.uploadingImages()) {
            this.uploadedZipFiles = filenames;
        } else {
            this.uploadedCsvFiles = filenames;
        }
        this.updateUploadWidget();
    },

    startUpload: function (folder) {
        // Configure upload widget and begin upload
        this.uploadWidget.parentType = 'folder';
        this.uploadWidget.parent = folder;
        this.uploadWidget.uploadNextFile();
    },

    submitDataset: function () {
        var name = $('#isic-dataset-name').val();
        var description = $('#isic-dataset-description').val();
        var license = $('#isic-dataset-license').val();
        var signature = $('#isic-dataset-agreement-signature').val();
        var anonymous = $('#isic-dataset-attribution-anonymous').prop('checked');
        var attribution = $('#isic-dataset-attribution-name').val();
        var uploadFolderId = this.uploadFolder ? this.uploadFolder.id : null;

        // Post dataset
        // TODO: processing happens synchronously; revisit using jobs?
        girder.restRequest({
            type: 'POST',
            path: 'dataset',
            data: {
                uploadFolderId: uploadFolderId,
                name: name,
                description: description,
                license: license,
                signature: signature,
                anonymous: anonymous,
                attribution: attribution
            },
            error: null
        }).done(_.bind(function () {
            // TODO: if updated to use jobs, navigate to job status page instead
            girder.confirm({
                text: '
Dataset successfully submitted.
',
                yesClass: 'hidden',
                noText: 'OK',
                escapedHtml: true
            });
            isic.router.navigate('', {trigger: true});
        }, this)).error(_.bind(function (resp) {
            // TODO: add custom error dialog instead of using confirm dialog
            girder.confirm({
                text: '
Error submitting dataset

' + resp.responseJSON.message,
                yesClass: 'hidden',
                noText: 'OK',
                escapedHtml: true
            });
            this.$('#isic-dataset-submit').prop('disabled', false);
        }, this));
    },

    uploadingImages: function () {
        return (this.$('#isic-upload-images.active').length > 0);
    },

    updateUploadWidget: function () {
        var visible = false;
        var uploadList = [];
        var uploadingImages = this.uploadingImages();
        if (uploadingImages) {
            if (this.uploadedZipFiles.length) {
                visible = false;
                uploadList = this.uploadedZipFiles;
            } else {
                visible = true;
            }
        } else {
            if (this.uploadedCsvFiles.length) {
                visible = false;
                uploadList = this.uploadedCsvFiles;
            } else {
                visible = true;
            }
        }

        this.$('.isic-upload-description-container').toggle(visible);
        this.$('.isic-upload-description-zip').toggle(uploadingImages);
        this.$('.isic-upload-description-csv').toggle(!uploadingImages);
        this.$('.isic-upload-widget-container').toggle(visible);
        this.$('.isic-upload-reset-container').toggle(!visible);

        this.uploadWidget.render();
        this.$('.isic-upload-list').text(
            'Uploaded: ' + uploadList.join(', '));
    },

    resetUpload: function () {
        var uploadList = null;
        if (this.uploadingImages()) {
            uploadList = this.uploadedZipFiles;
        } else {
            uploadList = this.uploadedCsvFiles;
        }

        // Delete uploaded files
        _.each(uploadList, function (name) {
            var items = new girder.collections.ItemCollection();
            items.once('g:changed', function () {
                if (!items.isEmpty()) {
                    var item = items.first();
                    item.destroy();

                    while (uploadList.length) {
                        uploadList.pop();
                    }
                    this.updateUploadWidget();
                }
            }, this).fetch({
                name: name,
                folderId: this.uploadFolder.id
            });
        }, this);
    }
});

isic.router.route('uploadDataset', 'uploadDataset', function (id) {
    // Route to index if user doesn't have permission to contribute datasets
    var datasetModel = new isic.models.DatasetModel();
    datasetModel.userCanContribute(girder.currentUser, _.bind(function (datasetContributor) {
        if (datasetContributor) {
            girder.events.trigger('g:navigateTo', isic.views.UploadDatasetView);
        } else {
            isic.router.navigate('', {trigger: true});
        }
    }, this));
});
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
function renderStatusLine() {
	$("#plugin_content").append( "

" );
}

function renderView( /* Array of String */ columns, /* Array of String */ buttons ) {
    renderStatusLine();
    renderButtons(buttons);
    var txt = "

";
    for ( var name in columns ) {
    	txt = txt + "" + columns[name] + "	";
    }
    txt = txt + "

";
    $("#plugin_content").append( txt );
    renderButtons(buttons);
    renderStatusLine();
}

function renderButtons( buttons ) {
	$("#plugin_content").append( "

" +
	                             "<form method='post' enctype='multipart/form-data'>
" +
	                             buttons + "
</form>

" );
}

function renderData( eventData )  {
	$(".statusline").empty().append(eventData.status);
	$("#bundles > tbody > tr").remove();
    for ( var idx in eventData.data ) {
        entry( eventData.data[idx] );
    }
    $("#bundles").trigger("update");
    if ( drawDetails ) {
	    renderDetails(eventData);
    }
}

function entry( /* Object */ dataEntry ) {
    var trElement = tr( null, { id: "entry" + dataEntry.id } );
    entryInternal( trElement,  dataEntry );
	$("#bundles > tbody").append(trElement);
}

function actionButton( /* Element */ parent, /* string */ id, /* Obj */ action ) {
	var enabled = action.enabled;
	var op = action.link;
	var opLabel = action.name;
	var img = action.image;

	var input = createElement( "input", null, {
            type: 'image',
            title: opLabel,
            alt: opLabel,
            src: imgRoot + '/bundle_' + img + '.png',
            onClick: 'changeDataEntryState(' + id + ', "' + op + '");'
        });

    if (!enabled) {
        input.setAttribute( "disabled", true );
    }
    var div = createElement("div");
    div.setAttribute("style", "float:left; margin-left:10px;");
    div.appendChild(input);
    parent.appendChild( div );
}

function entryInternal( /* Element */ parent, /* Object */ dataEntry ) {
    var id = dataEntry.id;
    var name = dataEntry.name;
    var state = dataEntry.state;

    var inputElement = createElement("img", "rightButton", {
    	src: appRoot + "/res/imgs/arrow_right.png",
    	border: "none",
    	id: 'img' + id,
    	title: "Back",
    	alt: "Back",
    	width: 14,
    	height: 14,
        onClick: 'showDetails(' + id + ');'
    });
    var titleElement;
    if ( drawDetails ) {
    	titleElement = text(name);
    } else {
        titleElement = createElement ("a", null, {
    	    href: window.location.pathname + "/" + id
        });
        titleElement.appendChild(text(name));
    }

    parent.appendChild( td( null, null, [ text( id ) ] ) );
    parent.appendChild( td( null, null, [ inputElement, text(" "), titleElement ] ) );
    parent.appendChild( td( null, null, [ text( state ) ] ) );
    var actionsTd = td( null, null );

    for ( var a in dataEntry.actions ) {
    	actionButton( actionsTd, id, dataEntry.actions[a] );
    }
    parent.appendChild( actionsTd );
}

function loadData() {
	$.get(pluginRoot + "/.json", null, function(data) {
	    renderData(data);
	}, "json");
}

function changeDataEntryState(/* long */ id, /* String */ action) {
	$.post(pluginRoot + "/" + id, {"action":action}, function(data) {
	    renderData(data);
	}, "json");
}

function refreshPackages() {
	$.post(window.location.pathname, {"action": "refreshPackages"}, function(data) {
	    renderData(data);
	}, "json");
}

function showDetails( id ) {
    $.get(pluginRoot + "/" + id + ".json", null, function(data) {
    	renderDetails(data);
    }, "json");
}

function hideDetails( id ) {
	$("#img" + id).each(function() {
		$("#bundleInlineDetails").remove();
        this.setAttribute("src", appRoot + "/res/imgs/arrow_right.png");
        this.setAttribute("onClick", "showDetails('" + id + "')");
        this.setAttribute("title", "Details");
        this.setAttribute("alt", "Details");
	});
}

function renderDetails( data ) {
	data = data.data[0];
	$("#entry" + data.id + " > td").eq(1).append("
");
	$("#img" + data.id).each(function() {
		if ( drawDetails ) {
            this.setAttribute("src", appRoot + "/res/imgs/arrow_left.png");
    	    var ref = window.location.pathname;
    	    ref = ref.substring(0, ref.lastIndexOf('/'));
            this.setAttribute("onClick", "window.location = '" + ref + "';");
            this.setAttribute("title", "Back");
            this.setAttribute("alt", "Back");
		} else {
            this.setAttribute("src", appRoot + "/res/imgs/arrow_down.png");
            this.setAttribute("onClick", "hideDetails('" + data.id + "')");
            this.setAttribute("title", "Hide Details");
            this.setAttribute("alt", "Hide Details");
		}
	});
	$("#bundleInlineDetails").append("

");
    var details = data.props;
    for (var idx in details) {
        var prop = details[idx];

        var txt = "
" + prop.key + "	";
        if (prop.value) {
        	if ( prop.key == 'Bundle Documentation' )  {
        		txt = txt + "" + prop.value + "";
        	} else  {
        		if ( $.isArray(prop.value) ) {
	        		var i = 0;
	        		for(var pi in prop.value) {
	        			var value = prop.value[pi];
		                if (i > 0) { txt = txt + "
"; }
		                var span;
		                if (value.substring(0, 2) == "!!") {
		                	txt = txt + "" + value + "";
		                } else {
		                	txt = txt + value;
		                }
		                i++;
	        		}
        		} else {
        			txt = txt + prop.value;
        		}
        	}
        } else {
        	txt = txt + "\u00a0";
        }
        txt = txt + "
";
        $("#bundleInlineDetails > table > tbody").append(txt);
	}
}

function renderBundles(data) {
	$(document).ready(function(){
    	renderView( ["Id", "Name", "Status", "Actions"],
        		"<input type='hidden' name='action' value='install' style='margin-left:20px;'/>" +
                "<input class='input' type='file' name='bundlefile' size='50' style='margin-left:10px;'/>" +
         		" - Start <input class='checkradio' type='checkbox' name='bundlestart' value='start' style='vertical-align:middle;'/>" +
        		" - Start Level <input class='input' type='input' name='bundlestartlevel' value='" + startLevel + "' size='4'/>" +
         		"<input type='submit' value='Install or Update' style='margin-left:60px'/>" +
        		"<button id='refreshPackages' type='button' name='refresh' style='margin-left:10px'>Refresh Packages</button>"
        		 );
        $("#refreshPackages").click(refreshPackages);
        renderData(data);

        var extractMethod = function(node) {
        	var link = node.getElementsByTagName("a");
            if ( link && link.length == 1 ) {
            	return link[0].innerHTML;
            }
            return node.innerHTML;
        };
        $("#bundles").tablesorter({
            headers: {
        	    0: { sorter:"digit"},
                3: { sorter: false }
            },
            sortList: [[1,0]],
            textExtraction:extractMethod
        });
    });
}
<commit_msg>FELIX-858 : Fix minor display problem in Safari with upload box.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
function renderStatusLine() {
	$("#plugin_content").append( "

" );
}

function renderView( /* Array of String */ columns, /* Array of String */ buttons ) {
    renderStatusLine();
    renderButtons(buttons);
    var txt = "

";
    for ( var name in columns ) {
    	txt = txt + "" + columns[name] + "	";
    }
    txt = txt + "

";
    $("#plugin_content").append( txt );
    renderButtons(buttons);
    renderStatusLine();
}

function renderButtons( buttons ) {
	$("#plugin_content").append( "

" +
	                             "<form method='post' enctype='multipart/form-data'>
" +
	                             buttons + "
</form>

" );
}

function renderData( eventData )  {
	$(".statusline").empty().append(eventData.status);
	$("#bundles > tbody > tr").remove();
    for ( var idx in eventData.data ) {
        entry( eventData.data[idx] );
    }
    $("#bundles").trigger("update");
    if ( drawDetails ) {
	    renderDetails(eventData);
    }
}

function entry( /* Object */ dataEntry ) {
    var trElement = tr( null, { id: "entry" + dataEntry.id } );
    entryInternal( trElement,  dataEntry );
	$("#bundles > tbody").append(trElement);
}

function actionButton( /* Element */ parent, /* string */ id, /* Obj */ action ) {
	var enabled = action.enabled;
	var op = action.link;
	var opLabel = action.name;
	var img = action.image;

	var input = createElement( "input", null, {
            type: 'image',
            title: opLabel,
            alt: opLabel,
            src: imgRoot + '/bundle_' + img + '.png',
            onClick: 'changeDataEntryState(' + id + ', "' + op + '");'
        });

    if (!enabled) {
        input.setAttribute( "disabled", true );
    }
    var div = createElement("div");
    div.setAttribute("style", "float:left; margin-left:10px;");
    div.appendChild(input);
    parent.appendChild( div );
}

function entryInternal( /* Element */ parent, /* Object */ dataEntry ) {
    var id = dataEntry.id;
    var name = dataEntry.name;
    var state = dataEntry.state;

    var inputElement = createElement("img", "rightButton", {
    	src: appRoot + "/res/imgs/arrow_right.png",
    	border: "none",
    	id: 'img' + id,
    	title: "Back",
    	alt: "Back",
    	width: 14,
    	height: 14,
        onClick: 'showDetails(' + id + ');'
    });
    var titleElement;
    if ( drawDetails ) {
    	titleElement = text(name);
    } else {
        titleElement = createElement ("a", null, {
    	    href: window.location.pathname + "/" + id
        });
        titleElement.appendChild(text(name));
    }

    parent.appendChild( td( null, null, [ text( id ) ] ) );
    parent.appendChild( td( null, null, [ inputElement, text(" "), titleElement ] ) );
    parent.appendChild( td( null, null, [ text( state ) ] ) );
    var actionsTd = td( null, null );

    for ( var a in dataEntry.actions ) {
    	actionButton( actionsTd, id, dataEntry.actions[a] );
    }
    parent.appendChild( actionsTd );
}

function loadData() {
	$.get(pluginRoot + "/.json", null, function(data) {
	    renderData(data);
	}, "json");
}

function changeDataEntryState(/* long */ id, /* String */ action) {
	$.post(pluginRoot + "/" + id, {"action":action}, function(data) {
	    renderData(data);
	}, "json");
}

function refreshPackages() {
	$.post(window.location.pathname, {"action": "refreshPackages"}, function(data) {
	    renderData(data);
	}, "json");
}

function showDetails( id ) {
    $.get(pluginRoot + "/" + id + ".json", null, function(data) {
    	renderDetails(data);
    }, "json");
}

function hideDetails( id ) {
	$("#img" + id).each(function() {
		$("#bundleInlineDetails").remove();
        this.setAttribute("src", appRoot + "/res/imgs/arrow_right.png");
        this.setAttribute("onClick", "showDetails('" + id + "')");
        this.setAttribute("title", "Details");
        this.setAttribute("alt", "Details");
	});
}

function renderDetails( data ) {
	data = data.data[0];
	$("#entry" + data.id + " > td").eq(1).append("
");
	$("#img" + data.id).each(function() {
		if ( drawDetails ) {
            this.setAttribute("src", appRoot + "/res/imgs/arrow_left.png");
    	    var ref = window.location.pathname;
    	    ref = ref.substring(0, ref.lastIndexOf('/'));
            this.setAttribute("onClick", "window.location = '" + ref + "';");
            this.setAttribute("title", "Back");
            this.setAttribute("alt", "Back");
		} else {
            this.setAttribute("src", appRoot + "/res/imgs/arrow_down.png");
            this.setAttribute("onClick", "hideDetails('" + data.id + "')");
            this.setAttribute("title", "Hide Details");
            this.setAttribute("alt", "Hide Details");
		}
	});
	$("#bundleInlineDetails").append("

");
    var details = data.props;
    for (var idx in details) {
        var prop = details[idx];

        var txt = "
" + prop.key + "	";
        if (prop.value) {
        	if ( prop.key == 'Bundle Documentation' )  {
        		txt = txt + "" + prop.value + "";
        	} else  {
        		if ( $.isArray(prop.value) ) {
	        		var i = 0;
	        		for(var pi in prop.value) {
	        			var value = prop.value[pi];
		                if (i > 0) { txt = txt + "
"; }
		                var span;
		                if (value.substring(0, 2) == "!!") {
		                	txt = txt + "" + value + "";
		                } else {
		                	txt = txt + value;
		                }
		                i++;
	        		}
        		} else {
        			txt = txt + prop.value;
        		}
        	}
        } else {
        	txt = txt + "\u00a0";
        }
        txt = txt + "
";
        $("#bundleInlineDetails > table > tbody").append(txt);
	}
}

function renderBundles(data) {
	$(document).ready(function(){
    	renderView( ["Id", "Name", "Status", "Actions"],
        		"<input type='hidden' name='action' value='install'/>" +
                "<input class='input' type='file' name='bundlefile' size='50' style='margin-left:10px'/>" +
         		" - Start <input class='checkradio' type='checkbox' name='bundlestart' value='start' style='vertical-align:middle;'/>" +
        		" - Start Level <input class='input' type='input' name='bundlestartlevel' value='" + startLevel + "' size='4'/>" +
         		"<input type='submit' value='Install or Update' style='margin-left:60px'/>" +
        		"<button id='refreshPackages' type='button' name='refresh' style='margin-left:10px'>Refresh Packages</button>"
        		 );
        $("#refreshPackages").click(refreshPackages);
        renderData(data);

        var extractMethod = function(node) {
        	var link = node.getElementsByTagName("a");
            if ( link && link.length == 1 ) {
            	return link[0].innerHTML;
            }
            return node.innerHTML;
        };
        $("#bundles").tablesorter({
            headers: {
        	    0: { sorter:"digit"},
                3: { sorter: false }
            },
            sortList: [[1,0]],
            textExtraction:extractMethod
        });
    });
}
<|endoftext|>


<commit_before>(function () {
    'use strict';

    let API = {
        nodes (args) {
            const p = '/api/v1/nodes';
            if (!args) {
                return p;
            }
            if (typeof args === 'string' || args instanceof String) {
                return `${p}/${args}`;
            }
            return `${p}?${args.toString()}`;
        },

        cache (args) {
            const p = '/api/v1/cache';
            if (!args) {
                return p;
            }
            if (typeof args === 'string' || args instanceof String) {
                return `${p}/${args}`;
            }
            return `${p}?${args.toString()}`;
        },

        log () {
            return '/api/v1/log';
        },
    };

    function main () {
        return Promise.all([
            setupSearch(),
            setupDownload(),
            setupTrash(),
            setupDoCache(),
            setupSync(),
            setupCompare(),
            setupLogWatcher(),
        ]).then(_ => 0);
    }

    function setupSearch () {
        let input = document.querySelector('#search-input');
        let button = document.querySelector('#search-button');
        let result = document.querySelector('#search-result');

        input.addEventListener('keypress', (event) => {
            if (event.keyCode !== 10 && event.keyCode !== 13) {
                return;
            }
            onSubmitSearch(input.value, result);
        });
        button.addEventListener('click', (event) => {
            onSubmitSearch(input.value, result);
        });

        return Promise.resolve();
    }

    function onSubmitSearch (pattern, searchResultArea) {
        return search(pattern).then((data) => {
            return appendSearchResult(searchResultArea, data);
        });
    }

    function search (pattern) {
        let args = new URLSearchParams();
        args.set('pattern', pattern);
        let headers = new Headers();
        headers.set('Cache-Control', 'no-store');
        return fetch(API.nodes(args), {
          method: 'GET',
          headers: headers,
        }).then((response) => {
            return response.json();
        });
    }

    function appendSearchResult (searchResultArea, data) {
        data = createSearchResultList(data);
        searchResultArea.insertBefore(data, searchResultArea.firstElementChild);
    }

    function createSearchResultList (data) {
        let wrapper = document.createElement('div');
        wrapper.classList.add('search-group');

        wrapper.addEventListener('contextmenu', (event) => {
            event.preventDefault();
            let entries = wrapper.querySelectorAll('.search-entry');
            for (let entry of entries) {
                entry.classList.toggle('selected');
            }
        });

        if (data.length <= 0) {
            wrapper.classList.add('empty');
        } else {
            for (let result of data) {
                result = createSearchResult(result);
                wrapper.appendChild(result);
            }
        }

        return wrapper;
    }

    function createSearchResult (resultData) {
        let wrapper = document.createElement('div');
        wrapper.dataset.id = resultData.id;
        wrapper.classList.add('search-entry');

        let nameLabel = document.createElement('span');
        nameLabel.textContent = resultData.name;
        wrapper.appendChild(nameLabel);

        wrapper.addEventListener('click', (event) => {
            wrapper.classList.toggle('selected');
        });

        return wrapper;
    }

    function setupDownload () {
        let button = document.querySelector('#download-button');

        button.addEventListener('click', (event) => {
            let idList = getSelectedIDList();
            download(idList);
        });

        return Promise.resolve();
    }

    function download (idList) {
        let requests = idList.map((v) => {
            return fetch(API.cache(v), {
                method: 'PUT',
            });
        });
        return Promise.all(requests);
    }

    function setupTrash () {
        let button = document.querySelector('#trash-button');

        button.addEventListener('click', (event) => {
            let rv = confirm('trash?');
            if (!rv) {
                return;
            }
            let idList = getSelectedIDList();
            trash(idList);
        });

        return Promise.resolve();
    }

    function trash (idList) {
        let requests = idList.map((v) => {
            return fetch(API.nodes(v), {
                method: 'DELETE',
            });
        });
        return Promise.all(requests);
    }

    function setupDoCache () {
        let button = document.querySelector('#do-cache-button');

        button.addEventListener('click', (event) => {
            doCache();
        });

        return Promise.resolve();
    }

    function doCache () {
        let args = new URLSearchParams();
        args.append('paths[]', '/tmp');

        return fetch(API.cache(), {
            method: 'POST',
            body: args,
        }).then((response) => {
            return response.text();
        });
    }

    function setupSync () {
        let button = document.querySelector('#sync-button');

        button.addEventListener('click', (event) => {
            doSync();
        });

        return Promise.resolve();
    }

    function doSync () {
        return fetch(API.cache(), {
            method: 'POST',
        });
    }

    function setupCompare () {
        let button = document.querySelector('#compare-button');

        button.addEventListener('click', (event) => {
            let idList = getSelectedIDList();
            compare(idList);
        });

        return Promise.resolve();
    }

    async function compare (idList) {
        let args = new URLSearchParams();
        for (let id of idList) {
            args.append('nodes[]', id);
        }
        let rv = await fetch(API.cache(args), {
            method: 'GET',
        });
        rv = await rv.json();
        updateCompareResult(rv);
    }

    function updateCompareResult (result) {
        let block = document.querySelector('#compare-result');
        while (block.firstChild) {
            block.firstChild.remove();
        }
        if (!result) {
            block.textContent = 'OK';
            return;
        }
        for (let [size, path] of result) {
            let pre = document.createElement('pre');
            pre.textContent = `${size}: ${path}`;
            block.appendChild(pre);
        }
    }

    function getSelectedIDList () {
        let list = document.querySelectorAll('#search-result .selected');
        let idList = Array.prototype.map.call(list, (v) => {
            return v.dataset.id;
        });
        list.forEach((v) => {
            v.classList.remove('selected');
        });
        return idList;
    }

    function setupLogWatcher () {
      let result = document.querySelector('#log-watcher');
      let ws = new WebSocket(`ws://${location.host}/api/v1/socket`);

      ws.addEventListener('message', function (event) {
          let record = formatRecord(JSON.parse(event.data));
          result.insertBefore(record, result.firstElementChild);
      });
      ws.addEventListener('close', function (event) {
          console.info('close', event);
      });
      ws.addEventListener('error', function (event) {
          console.info('error', event);
      });

      let headers = new Headers();
      headers.set('Cache-Control', 'no-store');
      return fetch(API.log(), {
          method: 'GET',
          headers: headers,
      }).then((response) => {
          return response.json();
      }).then((logs) => {
          let msgs = logs.map(formatRecord);
          msgs.reverse();
          msgs.forEach((record) => {
              result.appendChild(record);
          });
      });
    }

    function formatRecord (record) {
        let a = document.createElement('pre');
        a.textContent = record.message;
        return a;
    }

    return main();

})();
<commit_msg>reconnect socket if needed<commit_after>(function () {
    'use strict';

    let API = {
        nodes (args) {
            const p = '/api/v1/nodes';
            if (!args) {
                return p;
            }
            if (typeof args === 'string' || args instanceof String) {
                return `${p}/${args}`;
            }
            return `${p}?${args.toString()}`;
        },

        cache (args) {
            const p = '/api/v1/cache';
            if (!args) {
                return p;
            }
            if (typeof args === 'string' || args instanceof String) {
                return `${p}/${args}`;
            }
            return `${p}?${args.toString()}`;
        },

        log () {
            return '/api/v1/log';
        },
    };

    function main () {
        return Promise.all([
            setupSearch(),
            setupDownload(),
            setupTrash(),
            setupDoCache(),
            setupSync(),
            setupCompare(),
            setupLogWatcher(),
        ]).then(_ => 0);
    }

    function setupSearch () {
        let input = document.querySelector('#search-input');
        let button = document.querySelector('#search-button');
        let result = document.querySelector('#search-result');

        input.addEventListener('keypress', (event) => {
            if (event.keyCode !== 10 && event.keyCode !== 13) {
                return;
            }
            onSubmitSearch(input.value, result);
        });
        button.addEventListener('click', (event) => {
            onSubmitSearch(input.value, result);
        });

        return Promise.resolve();
    }

    function onSubmitSearch (pattern, searchResultArea) {
        return search(pattern).then((data) => {
            return appendSearchResult(searchResultArea, data);
        });
    }

    function search (pattern) {
        let args = new URLSearchParams();
        args.set('pattern', pattern);
        let headers = new Headers();
        headers.set('Cache-Control', 'no-store');
        return fetch(API.nodes(args), {
          method: 'GET',
          headers: headers,
        }).then((response) => {
            return response.json();
        });
    }

    function appendSearchResult (searchResultArea, data) {
        data = createSearchResultList(data);
        searchResultArea.insertBefore(data, searchResultArea.firstElementChild);
    }

    function createSearchResultList (data) {
        let wrapper = document.createElement('div');
        wrapper.classList.add('search-group');

        wrapper.addEventListener('contextmenu', (event) => {
            event.preventDefault();
            let entries = wrapper.querySelectorAll('.search-entry');
            for (let entry of entries) {
                entry.classList.toggle('selected');
            }
        });

        if (data.length <= 0) {
            wrapper.classList.add('empty');
        } else {
            for (let result of data) {
                result = createSearchResult(result);
                wrapper.appendChild(result);
            }
        }

        return wrapper;
    }

    function createSearchResult (resultData) {
        let wrapper = document.createElement('div');
        wrapper.dataset.id = resultData.id;
        wrapper.classList.add('search-entry');

        let nameLabel = document.createElement('span');
        nameLabel.textContent = resultData.name;
        wrapper.appendChild(nameLabel);

        wrapper.addEventListener('click', (event) => {
            wrapper.classList.toggle('selected');
        });

        return wrapper;
    }

    function setupDownload () {
        let button = document.querySelector('#download-button');

        button.addEventListener('click', (event) => {
            let idList = getSelectedIDList();
            download(idList);
        });

        return Promise.resolve();
    }

    function download (idList) {
        let requests = idList.map((v) => {
            return fetch(API.cache(v), {
                method: 'PUT',
            });
        });
        return Promise.all(requests);
    }

    function setupTrash () {
        let button = document.querySelector('#trash-button');

        button.addEventListener('click', (event) => {
            let rv = confirm('trash?');
            if (!rv) {
                return;
            }
            let idList = getSelectedIDList();
            trash(idList);
        });

        return Promise.resolve();
    }

    function trash (idList) {
        let requests = idList.map((v) => {
            return fetch(API.nodes(v), {
                method: 'DELETE',
            });
        });
        return Promise.all(requests);
    }

    function setupDoCache () {
        let button = document.querySelector('#do-cache-button');

        button.addEventListener('click', (event) => {
            doCache();
        });

        return Promise.resolve();
    }

    function doCache () {
        let args = new URLSearchParams();
        args.append('paths[]', '/tmp');

        return fetch(API.cache(), {
            method: 'POST',
            body: args,
        }).then((response) => {
            return response.text();
        });
    }

    function setupSync () {
        let button = document.querySelector('#sync-button');

        button.addEventListener('click', (event) => {
            doSync();
        });

        return Promise.resolve();
    }

    function doSync () {
        return fetch(API.cache(), {
            method: 'POST',
        });
    }

    function setupCompare () {
        let button = document.querySelector('#compare-button');

        button.addEventListener('click', (event) => {
            let idList = getSelectedIDList();
            compare(idList);
        });

        return Promise.resolve();
    }

    async function compare (idList) {
        let args = new URLSearchParams();
        for (let id of idList) {
            args.append('nodes[]', id);
        }
        let rv = await fetch(API.cache(args), {
            method: 'GET',
        });
        rv = await rv.json();
        updateCompareResult(rv);
    }

    function updateCompareResult (result) {
        let block = document.querySelector('#compare-result');
        while (block.firstChild) {
            block.firstChild.remove();
        }
        if (!result) {
            block.textContent = 'OK';
            return;
        }
        for (let [size, path] of result) {
            let pre = document.createElement('pre');
            pre.textContent = `${size}: ${path}`;
            block.appendChild(pre);
        }
    }

    function getSelectedIDList () {
        let list = document.querySelectorAll('#search-result .selected');
        let idList = Array.prototype.map.call(list, (v) => {
            return v.dataset.id;
        });
        list.forEach((v) => {
            v.classList.remove('selected');
        });
        return idList;
    }

    function setupLogWatcher () {
      let result = document.querySelector('#log-watcher');

      setupLogSocket(result);

      let headers = new Headers();
      headers.set('Cache-Control', 'no-store');
      return fetch(API.log(), {
          method: 'GET',
          headers: headers,
      }).then((response) => {
          return response.json();
      }).then((logs) => {
          let msgs = logs.map(formatRecord);
          msgs.reverse();
          msgs.forEach((record) => {
              result.appendChild(record);
          });
      });
    }

    function setupLogSocket (resultBlock) {
        let ws = new WebSocket(`ws://${location.host}/api/v1/socket`);
        ws.addEventListener('message', (event) => {
            let record = formatRecord(JSON.parse(event.data));
            resultBlock.insertBefore(record, resultBlock.firstElementChild);
        });
        ws.addEventListener('close', (event) => {
            console.info('close', event);
            setupLogSocket(resultBlock);
        });
        ws.addEventListener('error', (event) => {
            console.info('error', event);
            setTimeout(() => {
                setupLogSocket(resultBlock);
            }, 5 * 1000);
        });
    }

    function formatRecord (record) {
        let a = document.createElement('pre');
        a.textContent = record.message;
        return a;
    }

    return main();

})();
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import {
   Grid,
   GridCell,
   Spacer,
   Text,
   Title,
   TitleBar,
   View
} from '../../src'
import style from '../style.less'

export default class DemoContentText extends Component {
   static propTypes = {
      contents: React.PropTypes.array
   }

   constructor(props) {
      super(props)

      this.handleCancel = this.handleCancel.bind(this)
      this.handleDone = this.handleDone.bind(this)

      this.state = {
         value: 'Flexitarian biodiesel kale chips, hoodie lumbersexual food truck keffiyeh umami single-origin coffee franzen. Celiac viral put a bird on it, farm-to-table heirloom everyday carry before they sold out locavore listicle stumptown. Cold-pressed single-origin coffee seitan, next level biodiesel vinyl synth chia pop-up sartorial ugh post-ironic. Hella bitters cardigan affogato selfies thundercats gentrify, man braid schlitz normcore banjo umami messenger bag sartorial. Humblebrag freegan offal, mumblecore tote bag mustache venmo meditation lumbersexual. Put a bird on it intelligentsia lomo gluten-free bitters marfa. Meh literally try-hard ugh everyday carry.',
         editing: false,
         editLoading: false
      }
   }

   handleCancel(value) {
      this.setState({ editing: false })
   }

   handleDone(value) {
      this.setState({ editing: true, editLoading: true })
      setTimeout(() => {
         this.setState({
            value,
            editing: false,
            editLoading: false
         })
      }, 1000)
   }

   render() {
      return (
         <View width="100%" className={style.docs}>
            <TitleBar title="Text" flush />
            <Spacer size="9" />
            <Grid columns="1[a] 2[b] 4[c-e]" gutter="60px">
               <GridCell>
                  <Title>Text</Title>
                  <Text size="2" color="gray50">

A standard block of text content.

                  </Text>
               </GridCell>
               <GridCell colspan="3">
                  <Text>

Flexitarian biodiesel kale chips, hoodie lumbersexual
                     food truck keffiyeh umami single-origin coffee franzen.
                     Celiac viral put a bird on it, farm-to-table
                     heirloom everyday carry before they sold out locavore
                     listicle stumptown.

                  </Text>
               </GridCell>
            </Grid>
            <Grid columns="1[a] 2[b] 4[c-e]" gutter="60px">
               <GridCell>
                  <Title>Text (editable)</Title>
                  <Text size="2" color="gray50">

With the editable prop,Text
                     can be modified in place.

                  </Text>
               </GridCell>
               <GridCell colspan="3">
                  <Text
                     editing={this.state.editing}
                     editable
                     editorShowEditButton
                     editorLoading={this.state.editLoading}
                     editorOnCancel={this.handleCancel}
                     editorOnDone={this.handleDone}
                     editorValue={this.state.value}
                  />
               </GridCell>
            </Grid>
            <Grid columns="1[a] 2[b] 4[c-e]" gutter="60px">
               <GridCell>
                  <Title>Text Configurations</Title>
                  <Text size="2" color="gray50">
                     Props for using the Modal component
                  </Text>
               </GridCell>
               <GridCell colspan="3">

                           Prop
                           Prop Type
                           Default Value
                           Description/Options

                           children
                           Node
                           -
                           Children if editable === false

                           color
                           String
                           -
                           CSS color (e.g. #CCC)

                           size
                           String
                           -
                           Set content size 1 - 10

                           uppercase
                           Boolean
                           -
                           Make content uppercase

                           weight
                           String
                           normal
                           Set content font-weight

                           editable
                           Boolean
                           false
                           Makes Text component editable

                           editing
                           Boolean
                           false
                           Whether editor is open to edit or not.

                           editorCancelButtonText
                           String
                           Cancel
                           Text for cancel button

                           editorDoneButtonText
                           String
                           Done
                           Text for done button

                           editorOnCancel
                           Function
                           -
                           Returns body text to use.

                           editorOnDone
                           Function
                           -
                           Returns body text to use.

                           editorShowEditButton
                           Boolean
                           false
                           Show edit button at top right of text.

                           editorValue
                           String
                           -
                           Initial and editable body content (replaces children)

               </GridCell>
            </Grid>
         </View>
      )
   }
}
<commit_msg>Change Text demo handleedit and handle done method names.<commit_after>import React, { Component } from 'react'
import {
   Grid,
   GridCell,
   Spacer,
   Text,
   Title,
   TitleBar,
   View
} from '../../src'
import style from '../style.less'

export default class DemoContentText extends Component {
   static propTypes = {
      contents: React.PropTypes.array
   }

   constructor(props) {
      super(props)

      this.handleEditCancel = this.handleEditCancel.bind(this)
      this.handleEditDone = this.handleEditDone.bind(this)

      this.state = {
         value: 'Flexitarian biodiesel kale chips, hoodie lumbersexual food truck keffiyeh umami single-origin coffee franzen. Celiac viral put a bird on it, farm-to-table heirloom everyday carry before they sold out locavore listicle stumptown. Cold-pressed single-origin coffee seitan, next level biodiesel vinyl synth chia pop-up sartorial ugh post-ironic. Hella bitters cardigan affogato selfies thundercats gentrify, man braid schlitz normcore banjo umami messenger bag sartorial. Humblebrag freegan offal, mumblecore tote bag mustache venmo meditation lumbersexual. Put a bird on it intelligentsia lomo gluten-free bitters marfa. Meh literally try-hard ugh everyday carry.',
         editing: false,
         editLoading: false
      }
   }

   handleEditCancel(value) {
      this.setState({ editing: false })
   }

   handleEditDone(value) {
      this.setState({ editing: true, editLoading: true })
      setTimeout(() => {
         this.setState({
            value,
            editing: false,
            editLoading: false
         })
      }, 1000)
   }

   render() {
      return (
         <View width="100%" className={style.docs}>
            <TitleBar title="Text" flush />
            <Spacer size="9" />
            <Grid columns="1[a] 2[b] 4[c-e]" gutter="60px">
               <GridCell>
                  <Title>Text</Title>
                  <Text size="2" color="gray50">

A standard block of text content.

                  </Text>
               </GridCell>
               <GridCell colspan="3">
                  <Text>

Flexitarian biodiesel kale chips, hoodie lumbersexual
                     food truck keffiyeh umami single-origin coffee franzen.
                     Celiac viral put a bird on it, farm-to-table
                     heirloom everyday carry before they sold out locavore
                     listicle stumptown.

                  </Text>
               </GridCell>
            </Grid>
            <Grid columns="1[a] 2[b] 4[c-e]" gutter="60px">
               <GridCell>
                  <Title>Text (editable)</Title>
                  <Text size="2" color="gray50">

With the editable prop,Text
                     can be modified in place.

                  </Text>
               </GridCell>
               <GridCell colspan="3">
                  <Text
                     editing={this.state.editing}
                     editable
                     editorShowEditButton
                     editorLoading={this.state.editLoading}
                     editorOnCancel={this.handleEditCancel}
                     editorOnDone={this.handleEditDone}
                     editorValue={this.state.value}
                  />
               </GridCell>
            </Grid>
            <Grid columns="1[a] 2[b] 4[c-e]" gutter="60px">
               <GridCell>
                  <Title>Text Configurations</Title>
                  <Text size="2" color="gray50">
                     Props for using the Modal component
                  </Text>
               </GridCell>
               <GridCell colspan="3">

                           Prop
                           Prop Type
                           Default Value
                           Description/Options

                           children
                           Node
                           -
                           Children if editable === false

                           color
                           String
                           -
                           CSS color (e.g. #CCC)

                           size
                           String
                           -
                           Set content size 1 - 10

                           uppercase
                           Boolean
                           -
                           Make content uppercase

                           weight
                           String
                           normal
                           Set content font-weight

                           editable
                           Boolean
                           false
                           Makes Text component editable

                           editing
                           Boolean
                           false
                           Whether editor is open to edit or not.

                           editorCancelButtonText
                           String
                           Cancel
                           Text for cancel button

                           editorDoneButtonText
                           String
                           Done
                           Text for done button

                           editorOnCancel
                           Function
                           -
                           Returns body text to use.

                           editorOnDone
                           Function
                           -
                           Returns body text to use.

                           editorShowEditButton
                           Boolean
                           false
                           Show edit button at top right of text.

                           editorValue
                           String
                           -
                           Initial and editable body content (replaces children)

               </GridCell>
            </Grid>
         </View>
      )
   }
}
<|endoftext|>


<commit_before>function solid(){
function cback(e) {
    var t = [];
    for (var n = inputs.length; n--;) {
        if (!inputs[n].value.length) t.push(inputs[n]);
    }
    var r = t.length;
    var i = inputs.length;
    var s = document.querySelectorAll(".top");
    for (var o = s.length; o--;) {
        s[o].style.width = 100 - r / i * 100 + "%";
    }
}
var forms = document.querySelectorAll(".form"),
    inputs = [];
for (var i = forms.length; i--;) {
    var els = forms[i].querySelectorAll("input, textarea, select");
    for (var j = els.length; j--;) {
        if (els[j].type != "button" && els[j].type != "submit") {
            inputs.push(els[j]);
            els[j].addEventListener("input", cback, false);
        }
    }
}
}
function flash(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
    s[o].style.background = cols[i-r-1];
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}

var cols = ["#1ABC9C","#EC7063","#3498DB"];
}

function gradient(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}
}
function sections(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}

function generateCSSGradient(colours) {
var l = colours.length, i;
for( i=0; i<l; i++) colours[i] = colours[i].join(" ");
return "linear-gradient( to right, "+colours.join(", ")+")";
}

//Edit your colors here. Enter the color twice.
var cols = [
["#1ABC9C","0%"],
["#1ABC9C","33.3%"],
["#EC7063","33.3%"],
["#EC7063","66.6%"],
["#3498DB","66.6%"],
["#3498DB","100%"]
];
document.getElementsByClassName('top').innerHTML = '

';
document.querySelector(".colors").style.background = generateCSSGradient(cols);

var window_width = window.innerWidth + "px";
document.querySelector(".colors").style.width = window_width;
};
<commit_msg>Update fort.js<commit_after>function solid(){
    function cback(e) {
        var t = [];
        for (var n = inputs.length; n--;) {
            if (!inputs[n].value.length) t.push(inputs[n]);
        }
        var r = t.length;
        var i = inputs.length;
        var s = document.querySelectorAll(".top");
        for (var o = s.length; o--;) {
            s[o].style.width = 100 - r / i * 100 + "%";
        }
    }
    var forms = document.querySelectorAll(".form"),
    inputs = [];
    for (var i = forms.length; i--;) {
        var els = forms[i].querySelectorAll("input, textarea, select");
        for (var j = els.length; j--;) {
          classes = els[j].className.replace(/\s+/g, ' ').split(' ');
          ignore = false;
          for (var k = classes.length; k--;)
          {
           if (classes[k] == "ignore")
           {
            ignore = true;
            break;
        }
    }
    if (els[j].type != "button" && els[j].type != "submit" && !ignore) {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}
}
function flash(){
    function cback(e) {
        var t = [];
        for (var n = inputs.length; n--;) {
            if (!inputs[n].value.length) t.push(inputs[n]);
        }
        var r = t.length;
        var i = inputs.length;
        var s = document.querySelectorAll(".top");
        for (var o = s.length; o--;) {
            s[o].style.width = 100 - r / i * 100 + "%";
            s[o].style.background = cols[i-r-1];
        }
    }
    var forms = document.querySelectorAll(".form"),
    inputs = [];
    for (var i = forms.length; i--;) {
        var els = forms[i].querySelectorAll("input, textarea, select");
        for (var j = els.length; j--;) {
            classes = els[j].className.replace(/\s+/g, ' ').split(' ');
            ignore = false;
            for (var k = classes.length; k--;)
            {
               if (classes[k] == "ignore")
               {
                ignore = true;
                break;
            }
        }
        if (els[j].type != "button" && els[j].type != "submit" && !ignore) {
            inputs.push(els[j]);
            els[j].addEventListener("input", cback, false);
        }

    }
}
//Edit colors here
var cols = ["#1ABC9C","#EC7063","#3498DB"];
}

function gradient(){
    function cback(e) {
        var t = [];
        for (var n = inputs.length; n--;) {
            if (!inputs[n].value.length) t.push(inputs[n]);
        }
        var r = t.length;
        var i = inputs.length;
        var s = document.querySelectorAll(".top");
        for (var o = s.length; o--;) {
            s[o].style.width = 100 - r / i * 100 + "%";
        }
    }
    var forms = document.querySelectorAll(".form"),
    inputs = [];
    for (var i = forms.length; i--;) {
        var els = forms[i].querySelectorAll("input, textarea, select");
        for (var j = els.length; j--;) {
            classes = els[j].className.replace(/\s+/g, ' ').split(' ');
            ignore = false;
            for (var k = classes.length; k--;)
            {
               if (classes[k] == "ignore")
               {
                ignore = true;
                break;
            }
        }
        if (els[j].type != "button" && els[j].type != "submit" && !ignore) {
            inputs.push(els[j]);
            els[j].addEventListener("input", cback, false);
        }
    }
}
}
function sections(){
    function cback(e) {
        var t = [];
        for (var n = inputs.length; n--;) {
            if (!inputs[n].value.length) t.push(inputs[n]);
        }
        var r = t.length;
        var i = inputs.length;
        var s = document.querySelectorAll(".top");
        for (var o = s.length; o--;) {
            s[o].style.width = 100 - r / i * 100 + "%";
        }
    }
    var forms = document.querySelectorAll(".form"),
    inputs = [];
    for (var i = forms.length; i--;) {
        var els = forms[i].querySelectorAll("input, textarea, select");
        for (var j = els.length; j--;) {
         classes = els[j].className.replace(/\s+/g, ' ').split(' ');
         ignore = false;
         for (var k = classes.length; k--;)
         {
           if (classes[k] == "ignore")
           {
            ignore = true;
            break;
        }
    }
    if (els[j].type != "button" && els[j].type != "submit" && !ignore) {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}

function generateCSSGradient(colours) {
    var l = colours.length, i;
    for( i=0; i<l; i++) colours[i] = colours[i].join(" ");
        return "linear-gradient( to right, "+colours.join(", ")+")";
}

//Edit your colors here. Enter the color twice.
var cols = [
["#1ABC9C","0%"],
["#1ABC9C","33.3%"],
["#EC7063","33.3%"],
["#EC7063","66.6%"],
["#3498DB","66.6%"],
["#3498DB","100%"]
];
document.getElementsByClassName('top').innerHTML = '

';
document.querySelector(".colors").style.background = generateCSSGradient(cols);

var window_width = window.innerWidth + "px";
document.querySelector(".colors").style.width = window_width;

};
<|endoftext|>


<commit_before>// this is a test server to support tests which make requests

var io = require('socket.io');
var server = io(process.env.ZUUL_PORT || 3210, { pingInterval: 2000 });
var expect = require('expect.js');

var debug = require('./debug')('socket.io');

server.of('/foo').on('connection', function() {
    // register namespace
});

server.of('/timeout_socket').on('connection', function() {
    // register namespace
});

server.of('/valid').on('connection', function() {
    // register namespace
});

server.of('/asd').on('connection', function() {
    // register namespace
});

server.on('connection', function(socket) {
    debug('connect');

    // simple test
    socket.on('hi', function() {
        args = Array.prototype.slice.call(arguments);
        debug('on', 'hi', JSON.stringify(Array.from(arguments), null, 2));
        // socket.emit('hi');
        args.unshift('hi');
        socket.emit.apply(socket, args);
    });

    // ack tests
    socket.on('ack', function() {
        debug('on', 'ack', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('ack', function(a, b) {
            debug('on', 'ack', 'ack', JSON.stringify(Array.from(arguments), null, 2));
            if (a === 5 && b.test) {
                socket.emit('got it');
            }
        });
    });

    socket.on('getAckDate', function(data, cb) {
        debug('on', 'getAckDate', JSON.stringify(Array.from(arguments), null, 2));
        cb(new Date('2017-01-01'));
    });

    socket.on('getDate', function() {
        debug('on', 'getDate', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('takeDate', new Date('2017-01-01'));
    });

    socket.on('getDateObj', function() {
        debug('on', 'getDateObj', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('takeDateObj', { date: new Date('2017-01-01') });
    });

    socket.on('getUtf8', function() {
        debug('on', 'getUtf8', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('takeUtf8', 'てすと');
        socket.emit('takeUtf8', 'Я Б Г Д Ж Й');
        socket.emit('takeUtf8', 'Ä ä Ü ü ß');
        socket.emit('takeUtf8', 'utf8 — string');
        socket.emit('takeUtf8', 'utf8 — string');
    });

    // false test
    socket.on('false', function() {
        socket.emit('false', false);
    });

    // binary test
    socket.on('doge', function() {
        var buf = new Buffer('asdfasdf', 'utf8');
        socket.emit('doge', buf);
    });

    // expect receiving binary to be buffer
    socket.on('buffa', function(a) {
        if (Buffer.isBuffer(a)) socket.emit('buffack');
    });

    // expect receiving binary with mixed JSON
    socket.on('jsonbuff', function(a) {
        expect(a.hello).to.eql('lol');
        expect(Buffer.isBuffer(a.message)).to.be(true);
        expect(a.goodbye).to.eql('gotcha');
        socket.emit('jsonbuff-ack');
    });

    // expect receiving buffers in order
    var receivedAbuff1 = false;
    socket.on('abuff1', function(a) {
        expect(Buffer.isBuffer(a)).to.be(true);
        receivedAbuff1 = true;
    });
    socket.on('abuff2', function(a) {
        expect(receivedAbuff1).to.be(true);
        socket.emit('abuff2-ack');
    });

    // expect sent blob to be buffer
    socket.on('blob', function(a) {
        if (Buffer.isBuffer(a)) socket.emit('back');
    });

    // expect sent blob mixed with json to be buffer
    socket.on('jsonblob', function(a) {
        expect(a.hello).to.eql('lol');
        expect(Buffer.isBuffer(a.message)).to.be(true);
        expect(a.goodbye).to.eql('gotcha');
        socket.emit('jsonblob-ack');
    });

    // expect blobs sent in order to arrive in correct order
    var receivedblob1 = false;
    var receivedblob2 = false;
    socket.on('blob1', function(a) {
        expect(Buffer.isBuffer(a)).to.be(true);
        receivedblob1 = true;
    });
    socket.on('blob2', function(a) {
        expect(receivedblob1).to.be(true);
        expect(a).to.eql('second');
        receivedblob2 = true;
    });
    socket.on('blob3', function(a) {
        expect(Buffer.isBuffer(a)).to.be(true);
        expect(receivedblob1).to.be(true);
        expect(receivedblob2).to.be(true);
        socket.emit('blob3-ack');
    });

    // emit buffer to base64 receiving browsers
    socket.on('getbin', function() {
        var buf = new Buffer('asdfasdf', 'utf8');
        socket.emit('takebin', buf);
    });
});
<commit_msg>uupdate demo server<commit_after>// this is a test server to support tests which make requests

var io = require('socket.io');
var server = io(process.env.ZUUL_PORT || 3210, { pingInterval: 2000 });
var expect = require('expect.js');

var debug = require('./debug')('socket.io');

server.of('/foo').on('connection', function() {
    // register namespace
});

server.of('/timeout_socket').on('connection', function() {
    // register namespace
});

server.of('/valid').on('connection', function() {
    // register namespace
});

server.of('/asd').on('connection', function() {
    // register namespace
});

server.of('/demo').on('connection', function(socket) {
    debug('connect');

    // debug('socket.handshake', socket.handshake);

    debug('socket.request._query', socket.request._query);

    // simple test
    socket.on('hi', function() {
        args = Array.prototype.slice.call(arguments);
        debug('on', 'hi', JSON.stringify(Array.from(arguments), null, 2));
        args.unshift('hi');
        socket.emit.apply(socket, args);
    });

    // ack tests
    socket.on('ack', function() {
        debug('on', 'ack', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('ack', function(a, b) {
            debug('on', 'ack', 'ack', JSON.stringify(Array.from(arguments), null, 2));
            if (a === 5 && b.test) {
                socket.emit('got it');
            }
        });
    });

    socket.on('getAckDate', function(data, cb) {
        debug('on', 'getAckDate', JSON.stringify(Array.from(arguments), null, 2));
        cb(new Date('2017-01-01'));
    });

    socket.on('getDate', function() {
        debug('on', 'getDate', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('takeDate', new Date('2017-01-01'));
    });

    socket.on('getDateObj', function() {
        debug('on', 'getDateObj', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('takeDateObj', { date: new Date('2017-01-01') });
    });

    socket.on('getUtf8', function() {
        debug('on', 'getUtf8', JSON.stringify(Array.from(arguments), null, 2));
        socket.emit('takeUtf8', 'てすと');
        socket.emit('takeUtf8', 'Я Б Г Д Ж Й');
        socket.emit('takeUtf8', 'Ä ä Ü ü ß');
        socket.emit('takeUtf8', 'utf8 — string');
        socket.emit('takeUtf8', 'utf8 — string');
    });

    // false test
    socket.on('false', function() {
        socket.emit('false', false);
    });

    // binary test
    socket.on('doge', function() {
        var buf = new Buffer('asdfasdf', 'utf8');
        socket.emit('doge', buf);
    });

    // expect receiving binary to be buffer
    socket.on('buffa', function(a) {
        if (Buffer.isBuffer(a)) socket.emit('buffack');
    });

    // expect receiving binary with mixed JSON
    socket.on('jsonbuff', function(a) {
        expect(a.hello).to.eql('lol');
        expect(Buffer.isBuffer(a.message)).to.be(true);
        expect(a.goodbye).to.eql('gotcha');
        socket.emit('jsonbuff-ack');
    });

    // expect receiving buffers in order
    var receivedAbuff1 = false;
    socket.on('abuff1', function(a) {
        expect(Buffer.isBuffer(a)).to.be(true);
        receivedAbuff1 = true;
    });
    socket.on('abuff2', function(a) {
        expect(receivedAbuff1).to.be(true);
        socket.emit('abuff2-ack');
    });

    // expect sent blob to be buffer
    socket.on('blob', function(a) {
        if (Buffer.isBuffer(a)) socket.emit('back');
    });

    // expect sent blob mixed with json to be buffer
    socket.on('jsonblob', function(a) {
        expect(a.hello).to.eql('lol');
        expect(Buffer.isBuffer(a.message)).to.be(true);
        expect(a.goodbye).to.eql('gotcha');
        socket.emit('jsonblob-ack');
    });

    // expect blobs sent in order to arrive in correct order
    var receivedblob1 = false;
    var receivedblob2 = false;
    socket.on('blob1', function(a) {
        expect(Buffer.isBuffer(a)).to.be(true);
        receivedblob1 = true;
    });
    socket.on('blob2', function(a) {
        expect(receivedblob1).to.be(true);
        expect(a).to.eql('second');
        receivedblob2 = true;
    });
    socket.on('blob3', function(a) {
        expect(Buffer.isBuffer(a)).to.be(true);
        expect(receivedblob1).to.be(true);
        expect(receivedblob2).to.be(true);
        socket.emit('blob3-ack');
    });

    // emit buffer to base64 receiving browsers
    socket.on('getbin', function() {
        var buf = new Buffer('asdfasdf', 'utf8');
        socket.emit('takebin', buf);
    });
});
<|endoftext|>


<commit_before>
  /**
   *  Controller to show correct dialog to finally get share dialog.
   *
   *  - If the visualization is the type table -> Create visualization
   *  - If the visualization derived is private -> Make visualization private
   *  - If the visualization derived is private -> Turn private tables into public
   *  - Show share window
   *
   *  var controller = new cdb.admin.ShareController({
   *    model:  vis_model,
   *    user:   user_model,
   *    config: config_params
   *  });
   */

  cdb.admin.ShareController = cdb.core.View.extend({

    _TEXTS: {
      create_visualization: {
        msg:        _t('If you want to share your map you need to create a visualization.')
      },
      next_button:  _t('Check tables')
    },

    // Add to the stack then number of actions we need to do
    initialize: function() {
      this.user = this.options.user;
      this.config = this.options.config;
      this.stack = [];
      this.any_private_table = _.filter(this.model.get("related_tables"), function(table) {
        return table.privacy.toLowerCase() == "private"
      }).length > 0;

      // Generate stack
      this._generateStack();

      // Start
      this._nextStep();
    },

    _generateStack: function() {
      // If the visualization is a table type
      if (!this.model.isVisualization()) {
        this.stack.push({
          class: 'CreateVizDialog',
          step: 'createVisualization',
          opts: {
            model: this.model,
            msg: this._TEXTS.create_visualization.msg
          },
          center: false,
          callback: '_redirectApp'
        });
      }

      // Check if the visualization is private
      if (this.model.isVisualization() && this.model.get('privacy') == "PRIVATE") {
        this.stack.push({
          class: 'SharePrivateVisDialog',
          step: 'makeVisualizationPublic',
          opts: {
            model: this.model,
            next_button: this.any_private_table ? this._TEXTS.next_button : null
          },
          center: false
        });
      }

      // Check if there are private tables
      if (this.model.isVisualization()) {
        if (this.any_private_table) {
          this.stack.push({
            class: 'SharePrivateTablesDialog',
            step: 'makeTablesPublic',
            opts: {
              model: this.model
            },
            center: false
          });
        }
      }

      // Add share dialog if it is visualization
      if (this.model.isVisualization()) {
        this.stack.push({
          class: 'ShareDialog',
          step: 'showShareDialog',
          opts: {
            vis:    this.model,
            user:   this.user,
            config: this.config
          },
          center: true
        });
      }
    },

    _createDialog: function() {
      var self = this;
      var step = self.stack.shift();

      var dlg = new cdb.admin[step.class](step.opts);

      dlg.cancel = function() { self._clean() }
      dlg.ok = function(r) {
        step.callback && step.callback(r);
        self._nextStep();
      }

      dlg.appendToBody().open({ center: step.center });
      this.addView(dlg);
    },

    _redirectApp: function(vis) {
      window.location.href = "/viz/" + vis.get("id") + "/";
    },

    // Do next step until the end
    _nextStep: function() {
      if (this.stack.length > 0) {
        this._createDialog();
      } else {
        this._clean();
      }
    },

    // hack to prevent remove the dialog inmediatelly
    _clean: function() {
      var self = this;
      setTimeout(function() {
        self.clean()
      }, 1000);
    },

    // Clean clean cleaaaaaaaaaaan!
    clean: function() {
      this.stack = [];
      cdb.core.View.prototype.clean.call(this);
    }

  });<commit_msg>fixed callback function in share_controller<commit_after>
  /**
   *  Controller to show correct dialog to finally get share dialog.
   *
   *  - If the visualization is the type table -> Create visualization
   *  - If the visualization derived is private -> Make visualization private
   *  - If the visualization derived is private -> Turn private tables into public
   *  - Show share window
   *
   *  var controller = new cdb.admin.ShareController({
   *    model:  vis_model,
   *    user:   user_model,
   *    config: config_params
   *  });
   */

  cdb.admin.ShareController = cdb.core.View.extend({

    _TEXTS: {
      create_visualization: {
        msg:        _t('If you want to share your map you need to create a visualization.')
      },
      next_button:  _t('Check tables')
    },

    // Add to the stack then number of actions we need to do
    initialize: function() {
      this.user = this.options.user;
      this.config = this.options.config;
      this.stack = [];
      this.any_private_table = _.filter(this.model.get("related_tables"), function(table) {
        return table.privacy.toLowerCase() == "private"
      }).length > 0;

      // Generate stack
      this._generateStack();

      // Start
      this._nextStep();
    },

    _generateStack: function() {
      // If the visualization is a table type
      if (!this.model.isVisualization()) {
        this.stack.push({
          class: 'CreateVizDialog',
          step: 'createVisualization',
          opts: {
            model: this.model,
            msg: this._TEXTS.create_visualization.msg
          },
          center: false,
          callback: '_redirectApp'
        });
      }

      // Check if the visualization is private
      if (this.model.isVisualization() && this.model.get('privacy') == "PRIVATE") {
        this.stack.push({
          class: 'SharePrivateVisDialog',
          step: 'makeVisualizationPublic',
          opts: {
            model: this.model,
            next_button: this.any_private_table ? this._TEXTS.next_button : null
          },
          center: false
        });
      }

      // Check if there are private tables
      if (this.model.isVisualization()) {
        if (this.any_private_table) {
          this.stack.push({
            class: 'SharePrivateTablesDialog',
            step: 'makeTablesPublic',
            opts: {
              model: this.model
            },
            center: false
          });
        }
      }

      // Add share dialog if it is visualization
      if (this.model.isVisualization()) {
        this.stack.push({
          class: 'ShareDialog',
          step: 'showShareDialog',
          opts: {
            vis:    this.model,
            user:   this.user,
            config: this.config
          },
          center: true
        });
      }
    },

    _createDialog: function() {
      var self = this;
      var step = self.stack.shift();

      var dlg = new cdb.admin[step.class](step.opts);

      dlg.cancel = function() { self._clean() }
      dlg.ok = function(r) {
        step.callback && self[step.callback](r);
        self._nextStep();
      }

      dlg.appendToBody().open({ center: step.center });
      this.addView(dlg);
    },

    _redirectApp: function(vis) {
      window.location.href = "/viz/" + vis.get("id") + "/";
    },

    // Do next step until the end
    _nextStep: function() {
      if (this.stack.length > 0) {
        this._createDialog();
      } else {
        this._clean();
      }
    },

    // hack to prevent remove the dialog inmediatelly
    _clean: function() {
      var self = this;
      setTimeout(function() {
        self.clean()
      }, 1000);
    },

    // Clean clean cleaaaaaaaaaaan!
    clean: function() {
      this.stack = [];
      cdb.core.View.prototype.clean.call(this);
    }

  });<|endoftext|>


<commit_before>// Check if user has permittions to access admin control panel.
//

'use strict';

module.exports = function (N) {

  // Redirect to login page, if no permittions
  //
  N.wire.before('server:admin*', { priority: -100 }, function acp_check_permissions(env, callback) {

    env.extras.settings.fetch('can_access_acp', function (err, can_access_acp) {
      if (err) {
        callback(err);
        return;
      }

      if (!can_access_acp) {

        // for guests - redirect to login
        if (env.user_info.is_guest) {
          callback({
            code: N.io.REDIRECT,
            head: {
              Location: N.router.linkTo('users.auth.login.show')
            }
          });
          return;
        }

        // In other cases - 401 (Not authorised)
        callback(N.io.FORBIDDEN);
        return;
      }

      callback();
    });
  });
};
<commit_msg>Fixed admin login redirect<commit_after>// Check if user has permittions to access admin control panel.
//

'use strict';

module.exports = function (N) {

  // Redirect guests to login page
  //
  N.wire.before('server:admin*', { priority: -110 }, function acp_login_redirect(env, callback) {
    N.wire.emit('internal:users.force_login_guest', env, callback);
  });

  // Check permissions
  //
  N.wire.before('server:admin*', { priority: -100 }, function acp_check_permissions(env, callback) {

    env.extras.settings.fetch('can_access_acp', function (err, can_access_acp) {
      if (err) {
        callback(err);
        return;
      }

      if (!can_access_acp) {
        // In other cases - 401 (Not authorised)
        callback(N.io.FORBIDDEN);
        return;
      }

      callback();
    });
  });
};
<|endoftext|>


<commit_before>/*
 Script: Request.Binary.js
 	Extends the basic Request Class with additional methods for interacting with binary responses.

 License:
 	MIT-style license.
 */
Request.Binary = new Class({
    Extends: Request,

    options: {
        offset: 0,
        length: null
    },

    initialize: function(options){
        this.parent(options);

        if (this.options.length)
            this.headers.extend({
                'Range': 'bytes=' + this.options.offset + '-' + this.options.length
            });

        this.headers.extend({
            'If-Modified-Since': 'Sat, 1 Jan 1970 00:00:00 GMT'
        });

		this.addEvent('request', this.beforeSend.bind(this));
    },

	beforeSend: function(){
		if (this.xhr.overrideMimeType)
            this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
	},

    success: function(text){
        this.response.binary = new ByteStream(text);
        this.onSuccess(this.response.binary, text);
    }
});
<commit_msg>added copyright<commit_after>/*
 Script: Request.Binary.js
 	Extends the basic Request Class with additional methods for interacting with binary responses.

 Copyright:
 	Copyright (c) 2009 Dipl.-Ing. (FH) André Fiedler <kontakt@visualdrugs.net>

 License:
 	MIT-style license.
 */
Request.Binary = new Class({
    Extends: Request,

    options: {
        offset: 0,
        length: null
    },

    initialize: function(options){
        this.parent(options);

        if (this.options.length)
            this.headers.extend({
                'Range': 'bytes=' + this.options.offset + '-' + this.options.length
            });

        this.headers.extend({
            'If-Modified-Since': 'Sat, 1 Jan 1970 00:00:00 GMT'
        });

		this.addEvent('request', this.beforeSend.bind(this));
    },

	beforeSend: function(){
		if (this.xhr.overrideMimeType)
            this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
	},

    success: function(text){
        this.response.binary = new ByteStream(text);
        this.onSuccess(this.response.binary, text);
    }
});
<|endoftext|>