Concatenate all general js files into tutti.js
This commit is contained in:
279
src/scripts/tutti/10_tasks.js
Normal file
279
src/scripts/tutti/10_tasks.js
Normal file
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* Removes the task from the task list and shot list, and show the 'task-add-link'
|
||||
* when this was the last task in its category.
|
||||
*/
|
||||
function _remove_task_from_list(task_id) {
|
||||
var $task_link = $('#task-' + task_id)
|
||||
var $task_link_parent = $task_link.parent();
|
||||
$task_link.hideAndRemove(300, function() {
|
||||
if ($task_link_parent.children('.task-link').length == 0) {
|
||||
$task_link_parent.find('.task-add-link').removeClass('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an item such as tasks/shots in the #item-details div
|
||||
*/
|
||||
function item_open(item_id, item_type, pushState)
|
||||
{
|
||||
if (item_id === undefined || item_type === undefined) {
|
||||
throw new ReferenceError("item_open(" + item_id + ", " + item_type + ") called.");
|
||||
}
|
||||
|
||||
var project_url = ProjectUtils.projectUrl();
|
||||
if (typeof project_url === 'undefined') {
|
||||
throw new ReferenceError("ProjectUtils.projectUrl() undefined");
|
||||
}
|
||||
|
||||
$('#col_right .col_header span.header_text').text(item_type + ' details');
|
||||
|
||||
// Style elements starting with item_type and dash, e.g. "#shot-uuid"
|
||||
$('[id^="' + item_type + '-"]').removeClass('active');
|
||||
$('#' + item_type + '-' + item_id).addClass('active');
|
||||
|
||||
var item_url = '/attract/' + project_url + '/' + item_type + 's/' + item_id;
|
||||
var push_url = item_url;
|
||||
if (ProjectUtils.context() == 'shot' && item_type == 'task'){
|
||||
push_url = '/attract/' + project_url + '/shots/with-task/' + item_id;
|
||||
}
|
||||
|
||||
$.get(item_url, function(item_data) {
|
||||
$('#item-details').html(item_data);
|
||||
}).fail(function(xhr) {
|
||||
if (console) {
|
||||
console.log('Error fetching task', item_id, 'from', item_url);
|
||||
console.log('XHR:', xhr);
|
||||
}
|
||||
$('#item-details').html(xhr.responseText);
|
||||
});
|
||||
|
||||
// Determine whether we should push the new state or not.
|
||||
pushState = (typeof pushState !== 'undefined') ? pushState : true;
|
||||
if (!pushState) return;
|
||||
|
||||
// Push the correct URL onto the history.
|
||||
var push_state = {itemId: item_id, itemType: item_type};
|
||||
|
||||
window.history.pushState(
|
||||
push_state,
|
||||
item_type + ': ' + item_id,
|
||||
push_url
|
||||
);
|
||||
}
|
||||
|
||||
function task_open(task_id)
|
||||
{
|
||||
item_open(task_id, 'task');
|
||||
}
|
||||
|
||||
function shot_open(shot_id)
|
||||
{
|
||||
item_open(shot_id, 'shot');
|
||||
}
|
||||
|
||||
window.onpopstate = function(event)
|
||||
{
|
||||
var state = event.state;
|
||||
|
||||
item_open(state.itemId, state.itemType, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a task and show it in the #item-details div.
|
||||
*/
|
||||
function shot_create(project_url)
|
||||
{
|
||||
if (project_url === undefined) {
|
||||
throw new ReferenceError("shot_create(" + project_url+ ") called.");
|
||||
}
|
||||
var url = '/attract/' + project_url + '/shots/create';
|
||||
|
||||
data = {
|
||||
project_url: project_url
|
||||
};
|
||||
|
||||
$.post(url, data, function(shot_data) {
|
||||
shot_open(shot_data.shot_id);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
if (console) {
|
||||
console.log('Error creating task');
|
||||
console.log('XHR:', xhr);
|
||||
}
|
||||
$('#item-details').html(xhr.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a task and show it in the #item-details div.
|
||||
*/
|
||||
function task_create(shot_id, project_url, task_type)
|
||||
{
|
||||
if (shot_id === undefined || project_url === undefined || task_type === undefined) {
|
||||
throw new ReferenceError("task_create(" + shot_id + ", " + project_url+ ", " + task_type + ") called.");
|
||||
}
|
||||
var url = '/attract/' + project_url + '/tasks/create';
|
||||
|
||||
data = {
|
||||
task_type: task_type,
|
||||
parent: shot_id,
|
||||
};
|
||||
|
||||
$.post(url, data, function(task_data) {
|
||||
task_open(task_data.task_id, project_url);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
if (console) {
|
||||
console.log('Error creating task');
|
||||
console.log('XHR:', xhr);
|
||||
}
|
||||
$('#item-details').html(xhr.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function attract_form_save(form_id, item_id, item_save_url, options={})
|
||||
{
|
||||
// Mandatory option.
|
||||
if (typeof options.type === 'undefined') {
|
||||
throw new ReferenceError('attract_form_save(): options.type is mandatory.');
|
||||
}
|
||||
|
||||
var $form = $('#' + form_id);
|
||||
var $button = $form.find("button[type='submit']");
|
||||
|
||||
var payload = $form.serialize();
|
||||
var $item = $('#' + item_id);
|
||||
|
||||
$button.attr('disabled', true);
|
||||
$item.addClass('processing');
|
||||
$('#status-bar').text('Saving ' + options.type + '...');
|
||||
|
||||
if (console) console.log('Sending:', payload);
|
||||
|
||||
$.post(item_save_url, payload)
|
||||
.done(function(saved_item) {
|
||||
if (console) console.log('Done saving', saved_item);
|
||||
$('#status-bar')
|
||||
.text('Saved ' + options.type + '. ' + saved_item._updated);
|
||||
$form.find("input[name='_etag']").val(saved_item._etag);
|
||||
|
||||
if (options.done) options.done($item, saved_item);
|
||||
})
|
||||
.fail(function(xhr_or_response_data) {
|
||||
// jQuery sends the response data (if JSON), or an XHR object (if not JSON).
|
||||
if (console) console.log('Failed saving', options.type, xhr_or_response_data);
|
||||
|
||||
$button.removeClass('btn-default').addClass('btn-danger');
|
||||
$('#status-bar').text('Failed saving. ' + xhr_or_response_data.status);
|
||||
|
||||
if (options.fail) options.fail($item, xhr_or_response_data);
|
||||
})
|
||||
.always(function() {
|
||||
$button.attr('disabled', false);
|
||||
$item.removeClass('processing');
|
||||
|
||||
if (options.always) options.always($item);
|
||||
})
|
||||
;
|
||||
|
||||
return false; // prevent synchronous POST to current page.
|
||||
}
|
||||
|
||||
function task_save(task_id, task_url) {
|
||||
return attract_form_save('task_form', 'task-' + task_id, task_url, {
|
||||
done: function($task, saved_task) {
|
||||
// Update the task list.
|
||||
// NOTE: this is tightly linked to the HTML of the task list in for_project.jade.
|
||||
$('.task-name-' + saved_task._id).text(saved_task.name).flashOnce();
|
||||
$task.find('span.name').text(saved_task.name);
|
||||
$task.find('span.type').text(saved_task.properties.task_type);
|
||||
$task.find('span.status').text(saved_task.properties.status.replace('_', ' '));
|
||||
|
||||
$task
|
||||
.removeClassPrefix('status-')
|
||||
.addClass('status-' + saved_task.properties.status)
|
||||
.flashOnce()
|
||||
;
|
||||
},
|
||||
fail: function($item, xhr_or_response_data) {
|
||||
if (xhr_or_response_data.status == 412) {
|
||||
// TODO: implement something nice here. Just make sure we don't throw
|
||||
// away the user's edits. It's up to the user to handle this.
|
||||
} else {
|
||||
$('#item-details').html(xhr_or_response_data.responseText);
|
||||
}
|
||||
},
|
||||
type: 'task'
|
||||
});
|
||||
}
|
||||
|
||||
function shot_save(shot_id, shot_url) {
|
||||
return attract_form_save('shot_form', 'shot-' + shot_id, shot_url, {
|
||||
done: function($shot, saved_shot) {
|
||||
// Update the shot list.
|
||||
$('.shot-name-' + saved_shot._id).text(saved_shot.name);
|
||||
$shot
|
||||
.removeClassPrefix('status-')
|
||||
.addClass('status-' + saved_shot.properties.status)
|
||||
.flashOnce()
|
||||
;
|
||||
},
|
||||
fail: function($item, xhr_or_response_data) {
|
||||
if (xhr_or_response_data.status == 412) {
|
||||
// TODO: implement something nice here. Just make sure we don't throw
|
||||
// away the user's edits. It's up to the user to handle this.
|
||||
} else {
|
||||
$('#item-details').html(xhr_or_response_data.responseText);
|
||||
}
|
||||
},
|
||||
type: 'shot'
|
||||
});
|
||||
}
|
||||
|
||||
function task_delete(task_id, task_etag, task_delete_url) {
|
||||
if (task_id === undefined || task_etag === undefined || task_delete_url === undefined) {
|
||||
throw new ReferenceError("task_delete(" + task_id + ", " + task_etag + ", " + task_delete_url + ") called.");
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: task_delete_url,
|
||||
data: {'etag': task_etag}
|
||||
})
|
||||
.done(function(e) {
|
||||
if (console) console.log('Task', task_id, 'was deleted.');
|
||||
$('#task-details').fadeOutAndClear();
|
||||
_remove_task_from_list(task_id);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
$('#status-bar').text('Unable to delete task, code ' + xhr.status);
|
||||
if (xhr.status == 412) {
|
||||
alert('Someone else edited this task before you deleted it; refresh to try again.');
|
||||
// TODO: implement something nice here. Just make sure we don't throw
|
||||
// away the user's edits. It's up to the user to handle this.
|
||||
// TODO: refresh activity feed and point user to it.
|
||||
} else {
|
||||
// TODO: find a better place to put this error message, without overwriting the
|
||||
// task the user is looking at in-place.
|
||||
$('#task-view-feed').html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$("a.shot-link[data-shot-id]").click(function(e) {
|
||||
e.preventDefault();
|
||||
// delegateTarget is the thing the event hander was attached to,
|
||||
// rather than the thing we clicked on.
|
||||
var shot_id = e.delegateTarget.dataset.shotId;
|
||||
shot_open(shot_id);
|
||||
});
|
||||
$("a.task-link[data-task-id]").click(function(e) {
|
||||
e.preventDefault();
|
||||
var task_id = e.delegateTarget.dataset.taskId;
|
||||
task_open(task_id);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user