Skip to content

Commit

Permalink
Added ability to copy and paste exhibits
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeryH committed Apr 2, 2015
1 parent e89771e commit 46f37b6
Show file tree
Hide file tree
Showing 6 changed files with 304 additions and 8 deletions.
28 changes: 28 additions & 0 deletions Source/Chronozoom.UI/api/Chronozoom.svc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,21 @@ internal static IChronozoomSVC Instance
}
}

/// <summary>
/// Documented under IChronozoomSVC
/// </summary>
/// <param name="exhibitId"></param>
/// <returns></returns>
public Exhibit ExportExhibit(string exhibitId)
{
Guid guid = new Guid(exhibitId);

using (Utils.ExportImport xfer = new Utils.ExportImport())
{
return xfer.ExportExhibit(guid);
}
}

/// <summary>
/// Documented under IChronozoomSVC
/// </summary>
Expand All @@ -303,6 +318,19 @@ public String ImportTimelines(string intoTimelineId, List<Utils.ExportImport.Fla
}
}

/// <summary>
/// Documented under IChronozoomSVC
/// </summary>
public String ImportExhibit(string intoTimelineId, Exhibit newExhibit)
{
Guid guid = new Guid(intoTimelineId);

using (Utils.ExportImport xfer = new Utils.ExportImport())
{
return xfer.ImportExhibit(guid, newExhibit);
}
}

/// <summary>
/// Documented under IChronozoomSVC
/// </summary>
Expand Down
25 changes: 25 additions & 0 deletions Source/Chronozoom.UI/api/IChronozoomSVC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ public interface IChronozoomSVC
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/export/timeline/{topmostTimelineId}")]
List<Utils.ExportImport.FlatTimeline> ExportTimelines(string topmostTimelineId);

/// <summary>
/// For exporting an exhibit to temporary storage so can be imported later
/// as a copy.
/// </summary>
/// <param name="exhibitId">Must be a GUID, provided as a string.</param>
/// <returns>
/// A json formatted Exhibit
/// </returns>
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/export/exhibit/{exhibitId}")]
Exhibit ExportExhibit(string exhibitId);

/// <summary>
/// For importing a timeline and it's descendant sub-timelines into an existing timeline.
/// Typically this is a timeline from a different collection that is being copied.
Expand All @@ -43,6 +55,19 @@ public interface IChronozoomSVC
[WebInvoke(Method = "PUT", UriTemplate = "/import/timeline/{intoTimelineId}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
String ImportTimelines(string intoTimelineId, List<Utils.ExportImport.FlatTimeline> newTimelineTree);

/// <summary>
/// For importing an exhibit into an existing timeline.
/// It should be noted that the supplied exhibit to import must fit within the
/// date bounds of the target destination timeline's start and end dates.
/// </summary>
/// <param name="intoTimelineId">Must be a GUID, provided as a string.</param>
/// <param name="newExhibit">Must be a structure created by an IChronozoomSVC.ExportExhibit implementation, provided as a JSON.stringify string.</param>
/// <returns>A success, warning about date bounds exceeded, or general error message.</returns>
[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "/import/exhibit/{intoTimelineId}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
String ImportExhibit(string intoTimelineId, Exhibit newExhibit);


/// <summary>
/// For importing a collection from a file provided by the user as a new collection under the existing user, with new GUIDs.
/// If the user is not logged in as a valid user then the import will not proceed.
Expand Down
98 changes: 94 additions & 4 deletions Source/Chronozoom.UI/cz.merged.js
Original file line number Diff line number Diff line change
Expand Up @@ -3308,7 +3308,7 @@ var CZ;
this.pasteButton.onmousehover = function (event)
{
this.vc.element.css('cursor', 'pointer');
this.vc.element.attr('title', 'Paste Timeline');
this.vc.element.attr('title', 'Paste Timeline/Exhibit');
this.parent.settings.strokeStyle = "yellow";
}

Expand All @@ -3322,15 +3322,26 @@ var CZ;
this.pasteButton.onmouseclick = function (event)
{
var newTimeline = localStorage.getItem('ExportedTimeline');
var newExhibit = localStorage.getItem('ExportedExhibit');

if ((localStorage.getItem('ExportedSchemaVersion') == constants.schemaVersion) && newTimeline != null)
var sameDbSchema = localStorage.getItem('ExportedSchemaVersion') == constants.schemaVersion;

if (sameDbSchema && newTimeline != null)
{
// timeline from same db schema version is on "clipboard" so attempt "paste"
CZ.Service.importTimelines(this.parent.guid, newTimeline).then(function (importMessage)
{
CZ.Authoring.showMessageWindow(importMessage);
});
}
else if (sameDbSchema && newExhibit != null)
{
// exhibit from same db schema version is on "clipboard" so attempt "paste"
CZ.Service.importExhibit(this.parent.guid, newExhibit).then(function (importMessage)
{
CZ.Authoring.showMessageWindow(importMessage);
});
}
else
{
// unable to paste as nothing suitable is on "clipboard" so inform user
Expand Down Expand Up @@ -3377,7 +3388,8 @@ var CZ;
CZ.Service.exportTimelines(this.parent.guid).then(function (exportData)
{
localStorage.setItem('ExportedSchemaVersion', constants.schemaVersion);
localStorage.setItem('ExportedTimeline', JSON.stringify(exportData));
localStorage.setItem('ExportedTimeline', JSON.stringify(exportData));
localStorage.removeItem('ExportedExhibit');
CZ.Authoring.showMessageWindow('"' + exportData[0].timeline.title + '" has been copied to your clip-board. You can paste this into a different timeline.');
});
}
Expand Down Expand Up @@ -4915,12 +4927,14 @@ var CZ;
numberOfLines: 2
}, titleWidth);

//adding edit button
//adding edit and copy button
if (CZ.Authoring.isEnabled) {
var imageSize = (titleTop - infodot.y) * 0.75;
var editButton = VCContent.addImage(infodot, layerid, id + "__edit", time - imageSize / 2, infodot.y + imageSize * 0.2, imageSize, imageSize, "/images/edit.svg");
var copyButton = VCContent.addImage(infodot, layerid, id + "__copy", time - imageSize / 2 - imageSize * 1.3, infodot.y + imageSize * 0.2, imageSize, imageSize, "/images/copy.svg");

editButton.reactsOnMouse = true;
copyButton.reactsOnMouse = true;

editButton.onmouseclick = function () {
CZ.Authoring.isActive = true;
Expand All @@ -4929,6 +4943,17 @@ var CZ;
return true;
};

copyButton.onmouseclick = function () {
CZ.Service.exportExhibit(this.parent.guid).then(function (exportData) {
localStorage.setItem('ExportedSchemaVersion', constants.schemaVersion);
localStorage.setItem('ExportedExhibit', JSON.stringify(exportData));
localStorage.removeItem('ExportedTimeline');
CZ.Authoring.showMessageWindow('"' + exportData.title + '" has been copied to your clip-board. You can paste this into a different timeline.');
});
return true;
};


editButton.onmouseenter = function ()
{
this.vc.element.css('cursor', 'pointer');
Expand All @@ -4942,6 +4967,18 @@ var CZ;
this.vc.element.attr('title', '');
infodot.settings.strokeStyle = CZ.Settings.infoDotBorderColor;
};

copyButton.onmouseenter = function () {
this.vc.element.css('cursor', 'pointer');
this.vc.element.attr('title', 'Copy Exhibit to Clipboard');
infodot.settings.strokeStyle = "yellow";
};

copyButton.onmouseleave = function () {
this.vc.element.css('cursor', 'default');
this.vc.element.attr('title', '');
infodot.settings.strokeStyle = CZ.Settings.infoDotBorderColor;
};
}

var biblBottom = vyc + centralSquareSize + 63.0 / 450 * 2 * radv;
Expand Down Expand Up @@ -9859,6 +9896,59 @@ var CZ;
}
Service.importTimelines = importTimelines;

// .../export/exhibit/{exhibitId}
function exportExhibit(exhibitId) {
if (typeof exhibitId === 'undefined') {
throw 'exportExhibit(exhibitId) requires a parameter.';
}
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(exhibitId) == false) {
if (exhibitId != "00000000-0000-0000-0000-000000000000")
throw 'exportExhibit(exhibitId) has an invalid parameter. The provided parameter must be a GUID.';
}
CZ.Authoring.resetSessionTimer();
var request = new Request(_serviceUrl);
request.addToPath('export');
request.addToPath('exhibit');
request.addToPath(exhibitId);
return $.ajax
({
type: 'GET',
cache: false,
url: request.url,
dataType: 'json'
});
}
Service.exportExhibit = exportExhibit;

// .../import/exhibit/{intoTimelineId}
function importExhibit(intoTimelineId, newExhibit) {
if (typeof intoTimelineId === 'undefined' || typeof newExhibit === 'undefined') {
throw 'importExhibit(intoTimelineId, newExhibit) is missing a parameter.';
}
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(intoTimelineId) == false) {
if (intoTimelineId != "00000000-0000-0000-0000-000000000000")
throw 'importExhibit(intoTimelineId, newExhibit) has an invalid intoTimelineId parameter. This must be a GUID.';
}
if (typeof newExhibit !== 'string') {
throw 'importExhibit(intoTimelineId, newExhibit) has an invalid newTimelineTree parameter. This must be a JSON.stringify string.';
}
CZ.Authoring.resetSessionTimer();
var request = new Request(_serviceUrl);
request.addToPath('import');
request.addToPath('exhibit');
request.addToPath(intoTimelineId);
return $.ajax
({
type: 'PUT',
cache: false,
url: request.url,
contentType: 'application/json',
dataType: 'json',
data: newExhibit // should already be JSON.stringified
});
}
Service.importExhibit = importExhibit;

// .../import/collection
function importCollection(collectionTree)
{
Expand Down
53 changes: 53 additions & 0 deletions Source/Chronozoom.UI/scripts/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,59 @@ var CZ;
}
Service.importTimelines = importTimelines;

// .../export/exhibit/{exhibitId}
function exportExhibit(exhibitId) {
if (typeof exhibitId === 'undefined') {
throw 'exportExhibit(exhibitId) requires a parameter.';
}
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(exhibitId) == false) {
if (exhibitId != "00000000-0000-0000-0000-000000000000")
throw 'exportExhibit(exhibitId) has an invalid parameter. The provided parameter must be a GUID.';
}
CZ.Authoring.resetSessionTimer();
var request = new Request(_serviceUrl);
request.addToPath('export');
request.addToPath('exhibit');
request.addToPath(exhibitId);
return $.ajax
({
type: 'GET',
cache: false,
url: request.url,
dataType: 'json'
});
}
Service.exportExhibit = exportExhibit;

// .../import/exhibit/{intoTimelineId}
function importExhibit(intoTimelineId, newExhibit) {
if (typeof intoTimelineId === 'undefined' || typeof newExhibit === 'undefined') {
throw 'importExhibit(intoTimelineId, newExhibit) is missing a parameter.';
}
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(intoTimelineId) == false) {
if (intoTimelineId != "00000000-0000-0000-0000-000000000000")
throw 'importExhibit(intoTimelineId, newExhibit) has an invalid intoTimelineId parameter. This must be a GUID.';
}
if (typeof newExhibit !== 'string') {
throw 'importExhibit(intoTimelineId, newExhibit) has an invalid newTimelineTree parameter. This must be a JSON.stringify string.';
}
CZ.Authoring.resetSessionTimer();
var request = new Request(_serviceUrl);
request.addToPath('import');
request.addToPath('exhibit');
request.addToPath(intoTimelineId);
return $.ajax
({
type: 'PUT',
cache: false,
url: request.url,
contentType: 'application/json',
dataType: 'json',
data: newExhibit // should already be JSON.stringified
});
}
Service.importExhibit = importExhibit;

// .../import/collection
function importCollection(collectionTree)
{
Expand Down
Loading

0 comments on commit 46f37b6

Please sign in to comment.