Updates to include returning the next step in sequence

This commit is contained in:
Shannon
2014-03-05 10:32:59 +11:00
parent 0d93db5f1f
commit 24ceb5ce2d
5 changed files with 166 additions and 30 deletions

View File

@@ -28,6 +28,14 @@ angular.module("umbraco.install").factory('installerService', function($q, $time
return null;
}
/* Returns the description for the given step name */
function getDescriptionForStepName(steps, name) {
var found = _.find(steps, function(i) {
return i.name == name;
});
return (found) ? found.description : null;
}
var service = {
status : _status,
@@ -125,7 +133,7 @@ angular.module("umbraco.install").factory('installerService', function($q, $time
if(!response.data.complete){
feedback++;
var desc = getDescriptionForStepAtIndex(service.status.steps, feedback);
var desc = getDescriptionForStepName(service.status.steps, response.data.nextStep);
if (desc) {
service.status.feedback = desc;
}

View File

@@ -59,7 +59,7 @@ namespace Umbraco.Web.Install.Controllers
public InstallSetup GetSetup()
{
var setup = new InstallSetup();
//TODO: Check for user/site token
var steps = new List<InstallSetupStep>();
@@ -97,11 +97,11 @@ namespace Umbraco.Web.Install.Controllers
{
var r = new org.umbraco.our.Repository();
var modules = r.Modules();
return modules.Select(package => new Package()
{
Id = package.RepoGuid,
Name = package.Text,
Id = package.RepoGuid,
Name = package.Text,
Thumbnail = package.Thumbnail
});
}
@@ -110,7 +110,7 @@ namespace Umbraco.Web.Install.Controllers
/// Does the install
/// </summary>
/// <returns></returns>
public HttpResponseMessage PostPerformInstall(InstallInstructions installModel)
public InstallProgressResultModel PostPerformInstall(InstallInstructions installModel)
{
if (installModel == null) throw new ArgumentNullException("installModel");
@@ -121,8 +121,87 @@ namespace Umbraco.Web.Install.Controllers
status = InstallStatusTracker.InitializeFromFile(installModel.InstallId).ToArray();
}
foreach (var stepStatus in status)
//var queue = new Queue<InstallTrackingItem>(status);
//while (queue.Count > 0)
//{
// var stepStatus = queue.Dequeue();
// //if it is not complete, then we need to execute it
// if (stepStatus.IsComplete == false)
// {
// var step = InstallHelper.GetAllSteps().Single(x => x.Name == stepStatus.Name);
// JToken instruction = null;
// if (step.HasUIElement)
// {
// //Since this is a UI instruction, we will extract the model from it
// if (installModel.Instructions.Any(x => x.Key == step.Name) == false)
// {
// throw new HttpResponseException(Request.CreateValidationErrorResponse("No instruction defined for step: " + step.Name));
// }
// instruction = installModel.Instructions[step.Name];
// }
// //If this step doesn't require execution then continue to the next one.
// if (step.RequiresExecution() == false)
// {
// //set this as complete and continue
// InstallStatusTracker.SetComplete(installModel.InstallId, stepStatus.Name, null);
// continue;
// }
// try
// {
// var setupData = ExecuteStep(step, instruction);
// //update the status
// InstallStatusTracker.SetComplete(installModel.InstallId, step.Name, setupData != null ? setupData.SavedStepData : null);
// //get the next step if there is one
// var nextStep = "";
// if ((index + 1) < status.Length)
// {
// nextStep = status[index + 1].Name;
// }
// //check if there's a custom view to return for this step
// if (setupData != null && setupData.View.IsNullOrWhiteSpace() == false)
// {
// return new InstallProgressResultModel(false, step.Name, nextStep, setupData.View, setupData.ViewModel);
// }
// return new InstallProgressResultModel(false, step.Name, nextStep);
// }
// catch (Exception ex)
// {
// if (ex is TargetInvocationException && ex.InnerException != null)
// {
// ex = ex.InnerException;
// }
// var installException = ex as InstallException;
// if (installException != null)
// {
// throw new HttpResponseException(Request.CreateValidationErrorResponse(new
// {
// view = installException.View,
// model = installException.ViewModel,
// message = installException.Message
// }));
// }
// throw new HttpResponseException(
// Request.CreateValidationErrorResponse("An error occurred executing the step: " + step.Name + ". Error: " + ex.Message));
// }
// }
//}
for (var index = 0; index < status.Length; index++)
{
var stepStatus = status[index];
//if it is not complete, then we need to execute it
if (stepStatus.IsComplete == false)
{
@@ -134,7 +213,7 @@ namespace Umbraco.Web.Install.Controllers
//Since this is a UI instruction, we will extract the model from it
if (installModel.Instructions.Any(x => x.Key == step.Name) == false)
{
return Request.CreateValidationErrorResponse("No instruction defined for step: " + step.Name);
throw new HttpResponseException(Request.CreateValidationErrorResponse("No instruction defined for step: " + step.Name));
}
instruction = installModel.Instructions[step.Name];
}
@@ -143,7 +222,7 @@ namespace Umbraco.Web.Install.Controllers
if (step.RequiresExecution() == false)
{
//set this as complete and continue
InstallStatusTracker.SetComplete(installModel.InstallId, step.Name, null);
InstallStatusTracker.SetComplete(installModel.InstallId, stepStatus.Name, null);
continue;
}
@@ -154,24 +233,21 @@ namespace Umbraco.Web.Install.Controllers
//update the status
InstallStatusTracker.SetComplete(installModel.InstallId, step.Name, setupData != null ? setupData.SavedStepData : null);
//get the next step if there is one
var nextStep = "";
if ((index + 1) < status.Length)
{
nextStep = status[index + 1].Name;
}
//check if there's a custom view to return for this step
if (setupData != null && setupData.View.IsNullOrWhiteSpace() == false)
{
return Json(new
{
complete = false,
stepCompleted = step.Name,
view = setupData.View,
model = setupData.ViewModel
}, HttpStatusCode.OK);
return new InstallProgressResultModel(false, step.Name, nextStep, setupData.View, setupData.ViewModel);
}
return Json(new
{
complete = false,
stepCompleted = step.Name
}, HttpStatusCode.OK);
return new InstallProgressResultModel(false, step.Name, nextStep);
}
catch (Exception ex)
{
@@ -183,24 +259,31 @@ namespace Umbraco.Web.Install.Controllers
var installException = ex as InstallException;
if (installException != null)
{
return Json(new
throw new HttpResponseException(Request.CreateValidationErrorResponse(new
{
view = installException.View,
model = installException.ViewModel,
message = installException.Message
}, HttpStatusCode.BadRequest);
}));
}
return Request.CreateValidationErrorResponse("An error occurred executing the step: " + step.Name + ". Error: " + ex.Message);
throw new HttpResponseException(
Request.CreateValidationErrorResponse("An error occurred executing the step: " + step.Name + ". Error: " + ex.Message));
}
}
}
InstallStatusTracker.Reset();
return new InstallProgressResultModel(true, "", "");
return Json(new { complete = true }, HttpStatusCode.OK);
//return Json(new { complete = true }, HttpStatusCode.OK);
}
//private InstallSetupStep IterateNextRequiredStep(Queue<InstallTrackingItem> queue)
//{
// var step = InstallHelper.GetAllSteps().Single(x => x.Name == stepStatus.Name);
//}
internal InstallSetupResult ExecuteStep(InstallSetupStep step, JToken instruction)
{
using (DisposableTimer.TraceDuration<InstallApiController>("Executing installation step: " + step.Name, "Step completed"))
@@ -221,7 +304,7 @@ namespace Umbraco.Web.Install.Controllers
}
}
}
private HttpResponseMessage Json(object jsonObject, HttpStatusCode status)
{
var response = Request.CreateResponse(status);
@@ -229,6 +312,6 @@ namespace Umbraco.Web.Install.Controllers
response.Content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
return response;
}
}
}

View File

@@ -0,0 +1,42 @@
using System.Runtime.Serialization;
namespace Umbraco.Web.Install.Models
{
/// <summary>
/// Returned to the UI for each installation step that is completed
/// </summary>
[DataContract(Name = "result", Namespace = "")]
public class InstallProgressResultModel
{
public InstallProgressResultModel(bool processComplete, string stepCompleted, string nextStep, string view = null, object viewModel = null)
{
ProcessComplete = processComplete;
StepCompleted = stepCompleted;
NextStep = nextStep;
ViewModel = viewModel;
View = view;
}
/// <summary>
/// The UI view to show when this step executes, by default no views are shown for the completion of a step unless explicitly specified.
/// </summary>
[DataMember(Name = "view")]
public string View { get; private set; }
[DataMember(Name = "complete")]
public bool ProcessComplete { get; set; }
[DataMember(Name = "stepCompleted")]
public string StepCompleted { get; set; }
[DataMember(Name = "nextStep")]
public string NextStep { get; set; }
/// <summary>
/// The view model to return to the UI if this step is returning a view (optional)
/// </summary>
[DataMember(Name = "model")]
public object ViewModel { get; private set; }
}
}

View File

@@ -2,11 +2,13 @@ using System.Collections.Generic;
namespace Umbraco.Web.Install.Models
{
/// <summary>
/// The object returned from each installation step
/// </summary>
public class InstallSetupResult
{
public InstallSetupResult()
{
{
}
public InstallSetupResult(IDictionary<string, object> savedStepData, string view, object viewModel = null)

View File

@@ -319,6 +319,7 @@
<Compile Include="Install\Models\DatabaseType.cs" />
<Compile Include="Install\Models\InstallationType.cs" />
<Compile Include="Install\Models\InstallInstructions.cs" />
<Compile Include="Install\Models\InstallProgressResultModel.cs" />
<Compile Include="Install\Models\InstallSetup.cs" />
<Compile Include="Install\Models\InstallSetupResult.cs" />
<Compile Include="Install\Models\InstallSetupStep.cs" />