Gets local package installation 'working', now needs a little UI work.
This commit is contained in:
@@ -1,29 +1,127 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesInstallLocalController($scope, $route, $location) {
|
||||
function PackagesInstallLocalController($scope, $route, $location, Upload, umbRequestHelper, packageResource, $cookieStore) {
|
||||
|
||||
var vm = this;
|
||||
vm.state = "upload";
|
||||
|
||||
vm.localPackage = {
|
||||
"icon":"https://our.umbraco.org/media/wiki/154472/635997115126742822_logopng.png?bgcolor=fff&height=154&width=281&format=png",
|
||||
"name": "SvgIconPicker Version: 0.1.0",
|
||||
"author": "Søren Kottal",
|
||||
"authorLink": "https://github.com/skttl/",
|
||||
"info": "https://github.com/skttl/Umbraco.SvgIconPicker",
|
||||
"licens": "GPLv3",
|
||||
"licensLink": "http://www.gnu.org/licenses/quick-guide-gplv3.en.html",
|
||||
"licensAccept": false,
|
||||
"readme": "Color Palettes is a simple property editor that let you define different color palettes (or get them from Adobe Kuler or COLOURlovers) and present them to the editor as a list of radio buttons.",
|
||||
"filePath": "",
|
||||
"riskAccept": false
|
||||
vm.localPackage = {};
|
||||
vm.loadPackage = loadPackage;
|
||||
vm.installPackage = installPackage;
|
||||
vm.installState = {
|
||||
status: ""
|
||||
};
|
||||
vm.zipFile = {
|
||||
uploadStatus: "idle",
|
||||
uploadProgress: 0,
|
||||
serverErrorMessage: null
|
||||
};
|
||||
|
||||
vm.loadPackage = loadPackage;
|
||||
$scope.handleFiles = function (files, event) {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
upload(files[i]);
|
||||
}
|
||||
};
|
||||
|
||||
function loadPackage(){
|
||||
vm.state = "packageDetails";
|
||||
function upload(file) {
|
||||
|
||||
Upload.upload({
|
||||
url: umbRequestHelper.getApiUrl("packageInstallApiBaseUrl", "UploadLocalPackage"),
|
||||
fields: {},
|
||||
file: file
|
||||
}).progress(function (evt) {
|
||||
|
||||
// calculate progress in percentage
|
||||
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10);
|
||||
|
||||
// set percentage property on file
|
||||
vm.zipFile.uploadProgress = progressPercentage;
|
||||
|
||||
// set uploading status on file
|
||||
vm.zipFile.uploadStatus = "uploading";
|
||||
|
||||
}).success(function (data, status, headers, config) {
|
||||
|
||||
if (data.notifications && data.notifications.length > 0) {
|
||||
|
||||
// set error status on file
|
||||
vm.zipFile.uploadStatus = "error";
|
||||
|
||||
// Throw message back to user with the cause of the error
|
||||
vm.zipFile.serverErrorMessage = data.notifications[0].message;
|
||||
|
||||
//TODO: Handle the error in UI
|
||||
|
||||
} else {
|
||||
|
||||
// set done status on file
|
||||
vm.zipFile.uploadStatus = "done";
|
||||
|
||||
vm.localPackage = data;
|
||||
}
|
||||
|
||||
}).error(function (evt, status, headers, config) {
|
||||
|
||||
//TODO: Handle the error in UI
|
||||
|
||||
// set status done
|
||||
vm.zipFile.uploadStatus = "error";
|
||||
|
||||
//if the service returns a detailed error
|
||||
if (evt.InnerException) {
|
||||
vm.zipFile.serverErrorMessage = evt.InnerException.ExceptionMessage;
|
||||
|
||||
//Check if its the common "too large file" exception
|
||||
if (evt.InnerException.StackTrace && evt.InnerException.StackTrace.indexOf("ValidateRequestEntityLength") > 0) {
|
||||
vm.zipFile.serverErrorMessage = "File too large to upload";
|
||||
}
|
||||
|
||||
} else if (evt.Message) {
|
||||
file.serverErrorMessage = evt.Message;
|
||||
}
|
||||
|
||||
// If file not found, server will return a 404 and display this message
|
||||
if (status === 404) {
|
||||
vm.zipFile.serverErrorMessage = "File not found";
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function loadPackage() {
|
||||
if (vm.zipFile.uploadStatus === "done") {
|
||||
vm.state = "packageDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function installPackage() {
|
||||
vm.installState.status = "Installing";
|
||||
|
||||
//TODO: If any of these fail, will they keep calling the next one?
|
||||
packageResource
|
||||
.installFiles(vm.localPackage)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "Restarting, please hold...";
|
||||
return packageResource.installData(pack);
|
||||
},
|
||||
installError)
|
||||
.then(function(pack) {
|
||||
vm.installState.status = "All done, your browser will now refresh";
|
||||
return packageResource.cleanUp(pack);
|
||||
},
|
||||
installError)
|
||||
.then(installComplete, installError);
|
||||
}
|
||||
|
||||
function installComplete() {
|
||||
var url = window.location.href + "?installed=" + vm.localPackage.packageGuid;
|
||||
$cookieStore.put("umbPackageInstallId", vm.localPackage.packageGuid);
|
||||
window.location.reload(true);
|
||||
}
|
||||
|
||||
function installError() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,43 @@
|
||||
|
||||
|
||||
<div class="umb-upload-field">
|
||||
<i class="icon-box"></i>
|
||||
<small class="faded"><strong>Drop to upload</strong></small>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Drag and drop files area -->
|
||||
<div ngf-drop
|
||||
ng-hide="hideDropzone"
|
||||
ng-model="filesHolder"
|
||||
ngf-change="handleFiles($files, $event)"
|
||||
class="dropzone"
|
||||
ngf-drag-over-class="drag-over"
|
||||
ngf-multiple="false"
|
||||
ngf-allow-dir="false"
|
||||
ngf-pattern="*.zip"
|
||||
ngf-max-size="{{ maxFileSize }}"
|
||||
ng-class="{'is-small': compact!=='false' || (done.length+queue.length) > 0 }">
|
||||
|
||||
|
||||
<div class="content">
|
||||
|
||||
<!-- Drag and drop illustration -->
|
||||
<i class="icon-box" draggable="false"></i>
|
||||
<small class="faded" draggable="false"><strong>Drop to upload</strong></small>
|
||||
|
||||
<!-- Select files -->
|
||||
<div class="file-select"
|
||||
ngf-select
|
||||
ng-model="filesHolder"
|
||||
ngf-change="handleFiles($files, $event)"
|
||||
ngf-multiple="true"
|
||||
ngf-pattern="*.zip"
|
||||
ngf-max-size="{{ maxFileSize }}">
|
||||
- <localize key="media_orClickHereToUpload">or click here to choose files</localize>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h3><strong>Upload package</strong></h3>
|
||||
<p class="faded">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
|
||||
@@ -18,6 +51,8 @@
|
||||
|
||||
<button type="button"
|
||||
class="umb-era-button -blue"
|
||||
ng-disabled="vm.zipFile.uploadStatus !== 'done'"
|
||||
ng-class="{'-inactive' : vm.zipFile.uploadStatus !== 'done'}"
|
||||
ng-click="vm.loadPackage()">Next
|
||||
</button>
|
||||
</form>
|
||||
@@ -49,7 +84,7 @@
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
<strong>License</strong>
|
||||
<a href="{{ vm.localPackage.licensLink }}">{{ vm.localPackage.licens }}</a>
|
||||
<a href="{{ vm.localPackage.licenseLink }}">{{ vm.localPackage.license }}</a>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item">
|
||||
@@ -58,18 +93,21 @@
|
||||
<small> {{ vm.localPackage.readme }} </small>
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item mt-3">
|
||||
<div class="umb-info-local-item mt-3" ng-if="vm.installState.status == ''">
|
||||
<button type="button"
|
||||
ng-class="{'-inactive' : localPackageForm.$invalid}"
|
||||
ng-disabled="localPackageForm.$invalid"
|
||||
class="umb-era-button -blue inline-flex">
|
||||
class="umb-era-button -blue inline-flex"
|
||||
ng-click="vm.installPackage()">
|
||||
Install package
|
||||
</button>
|
||||
<label for="licens-accept" class="umb-package-installer-label">
|
||||
<input type="checkbox" id="licens-accept" ng-model="vm.localPackage.packageLicensAccept" required>
|
||||
<label for="license-accept" class="umb-package-installer-label">
|
||||
<input type="checkbox" id="license-accept" ng-model="vm.localPackage.packageLicenseAccept" required>
|
||||
<strong class="label-text">I accept <a href="#">terms of use</a></strong>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
<div class="umb-info-local-item">
|
||||
<p>{{vm.installState.status}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
|
||||
<div ng-show="vm.loading === false">
|
||||
<div class="umb-packages-section">
|
||||
<div class="umb-packages-section" ng-if="vm.searchQuery == ''">
|
||||
<div class="umb-packages-categories">
|
||||
<a href=""
|
||||
class="umb-packages-category"
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<div class="umb-package-info">
|
||||
<div class="umb-package-name">{{ package.name }}</div>
|
||||
<div class="umb-package-description">{{ package.description | limitTo: 40 }}<span ng-if="package.description > (package.description | limitTo: 40)">...</span></div>
|
||||
<div class="umb-package-description">{{ package.excerpt | limitTo: 40 }}<span ng-if="package.excerpt > (package.excerpt | limitTo: 40)">...</span></div>
|
||||
|
||||
<div class="umb-package-numbers">
|
||||
<small class="umb-package-downloads">
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
<div class="umb-package-info">
|
||||
<div class="umb-package-name">{{ package.name }}</div>
|
||||
<div class="umb-package-description">{{ package.description | limitTo: 40 }}<span ng-if="package.description > (package.description | limitTo: 40)">...</span></div>
|
||||
<div class="umb-package-description">{{ package.excerpt | limitTo: 40 }}<span ng-if="package.excerpt > (package.excerpt | limitTo: 40)">...</span></div>
|
||||
|
||||
<div class="umb-package-numbers">
|
||||
<small class="umb-package-downloads">
|
||||
@@ -86,7 +86,7 @@
|
||||
</div> <!-- end packages -->
|
||||
</div>
|
||||
|
||||
<div class="umb-packages__pagination" ng-if="vm.pagination.totalPages > 1">
|
||||
<div class="umb-packages__pagination" ng-if="vm.pagination.totalPages > 1 && vm.loading === false">
|
||||
|
||||
<umb-pagination page-number="vm.pagination.pageNumber"
|
||||
total-pages="vm.pagination.totalPages"
|
||||
|
||||
@@ -594,25 +594,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
return Request.CreateResponse(HttpStatusCode.OK, tempFiles);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used for the response of PostAddFile so that we can analyze the response in a filter and remove the
|
||||
/// temporary files that were created.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
private class PostedFiles : IHaveUploadedFiles, INotificationModel
|
||||
{
|
||||
public PostedFiles()
|
||||
{
|
||||
UploadedFiles = new List<ContentItemFile>();
|
||||
Notifications = new List<Notification>();
|
||||
}
|
||||
public List<ContentItemFile> UploadedFiles { get; private set; }
|
||||
|
||||
[DataMember(Name = "notifications")]
|
||||
public List<Notification> Notifications { get; private set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the item can be moved/copied to the new location
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -13,11 +14,16 @@ using System.Xml.Linq;
|
||||
using Umbraco.Core.Auditing;
|
||||
using umbraco.BusinessLogic;
|
||||
using umbraco.cms.businesslogic.packager.repositories;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Packaging.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.UI;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
@@ -26,7 +32,117 @@ namespace Umbraco.Web.Editors
|
||||
[UmbracoApplicationAuthorize(Core.Constants.Applications.Developer)]
|
||||
public class PackageInstallController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
[HttpPost]
|
||||
[FileUploadCleanupFilter(false)]
|
||||
public async Task<LocalPackageInstallModel> UploadLocalPackage()
|
||||
{
|
||||
if (Request.Content.IsMimeMultipartContent() == false)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
|
||||
}
|
||||
|
||||
var root = IOHelper.MapPath("~/App_Data/TEMP/FileUploads");
|
||||
//ensure it exists
|
||||
Directory.CreateDirectory(root);
|
||||
var provider = new MultipartFormDataStreamProvider(root);
|
||||
|
||||
var result = await Request.Content.ReadAsMultipartAsync(provider);
|
||||
|
||||
//must have a file
|
||||
if (result.FileData.Count == 0)
|
||||
{
|
||||
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
//TODO: App/Tree Permissions?
|
||||
var model = new LocalPackageInstallModel
|
||||
{
|
||||
PackageGuid = Guid.NewGuid()
|
||||
};
|
||||
|
||||
//get the files
|
||||
foreach (var file in result.FileData)
|
||||
{
|
||||
var fileName = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' });
|
||||
var ext = fileName.Substring(fileName.LastIndexOf('.') + 1).ToLower();
|
||||
|
||||
//TODO: Only allow .zip
|
||||
if (ext.InvariantEquals("zip") || ext.InvariantEquals("umb"))
|
||||
{
|
||||
//TODO: Currently it has to be here, it's not ideal but that's the way it is right now
|
||||
var packageTempDir = IOHelper.MapPath(SystemDirectories.Data);
|
||||
|
||||
//ensure it's there
|
||||
Directory.CreateDirectory(packageTempDir);
|
||||
|
||||
//copy it - must always be '.umb' for the installer thing to work
|
||||
//the file name must be a GUID - this is what the packager expects (strange yes)
|
||||
//because essentially this is creating a temporary package Id that will be used
|
||||
//for unpacking/installing/etc...
|
||||
var packageTempFileName = model.PackageGuid + ".umb";
|
||||
var packageTempFileLocation = Path.Combine(packageTempDir, packageTempFileName);
|
||||
File.Copy(file.LocalFileName, packageTempFileLocation, true);
|
||||
|
||||
try
|
||||
{
|
||||
var ins = new global::umbraco.cms.businesslogic.packager.Installer(Security.CurrentUser.Id);
|
||||
//this will load in all the metadata too
|
||||
var tempDir = ins.Import(packageTempFileName);
|
||||
model.TemporaryDirectoryPath = Path.Combine(SystemDirectories.Data, tempDir);
|
||||
model.Id = ins.CreateManifest(
|
||||
IOHelper.MapPath(model.TemporaryDirectoryPath),
|
||||
model.PackageGuid.ToString(),
|
||||
//TODO: Does this matter? we're installing a local package
|
||||
string.Empty);
|
||||
|
||||
model.Name = ins.Name;
|
||||
model.Author = ins.Author;
|
||||
model.AuthorUrl = ins.AuthorUrl;
|
||||
model.License = ins.License;
|
||||
model.LicenseUrl = ins.LicenseUrl;
|
||||
model.ReadMe = ins.ReadMe;
|
||||
model.ConflictingMacroAliases = ins.ConflictingMacroAliases;
|
||||
model.ConflictingStyleSheetNames = ins.ConflictingStyleSheetNames;
|
||||
model.ConflictingTemplateAliases = ins.ConflictingTemplateAliases;
|
||||
model.ContainsBinaryFileErrors = ins.ContainsBinaryFileErrors;
|
||||
model.ContainsLegacyPropertyEditors = ins.ContainsLegacyPropertyEditors;
|
||||
model.ContainsMacroConflict = ins.ContainsMacroConflict;
|
||||
model.ContainsStyleSheetConflicts = ins.ContainsStyleSheeConflicts;
|
||||
model.ContainsTemplateConflicts = ins.ContainsTemplateConflicts;
|
||||
model.ContainsUnsecureFiles = ins.ContainsUnsecureFiles;
|
||||
|
||||
model.Url = ins.Url;
|
||||
model.Version = ins.Version;
|
||||
//TODO: We need to add the 'strict' requirement to the installer
|
||||
}
|
||||
finally
|
||||
{
|
||||
//Cleanup file
|
||||
if (File.Exists(packageTempFileLocation))
|
||||
{
|
||||
File.Delete(packageTempFileLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model.Notifications.Add(new Notification(
|
||||
Services.TextService.Localize("speechBubbles/operationFailedHeader"),
|
||||
Services.TextService.Localize("media/disallowedFileType"),
|
||||
SpeechBubbleIcon.Warning));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return model;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the package from Our to install
|
||||
/// </summary>
|
||||
/// <param name="packageGuid"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public PackageInstallModel Fetch(string packageGuid)
|
||||
{
|
||||
@@ -50,6 +166,11 @@ namespace Umbraco.Web.Editors
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the package zip and gets the packages information
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public PackageInstallModel Import(PackageInstallModel model)
|
||||
{
|
||||
@@ -60,6 +181,11 @@ namespace Umbraco.Web.Editors
|
||||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Installs the package files
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public PackageInstallModel InstallFiles(PackageInstallModel model)
|
||||
{
|
||||
@@ -69,7 +195,11 @@ namespace Umbraco.Web.Editors
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Installs the packages data/business logic
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public PackageInstallModel InstallData(PackageInstallModel model)
|
||||
{
|
||||
@@ -79,7 +209,11 @@ namespace Umbraco.Web.Editors
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up the package installation
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public PackageInstallModel CleanUp(PackageInstallModel model)
|
||||
{
|
||||
|
||||
23
src/Umbraco.Web/Models/ContentEditing/PostedFiles.cs
Normal file
23
src/Umbraco.Web/Models/ContentEditing/PostedFiles.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
/// <summary>
|
||||
/// This is used for the response of PostAddFile so that we can analyze the response in a filter and remove the
|
||||
/// temporary files that were created.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
internal class PostedFiles : IHaveUploadedFiles, INotificationModel
|
||||
{
|
||||
public PostedFiles()
|
||||
{
|
||||
UploadedFiles = new List<ContentItemFile>();
|
||||
Notifications = new List<Notification>();
|
||||
}
|
||||
public List<ContentItemFile> UploadedFiles { get; private set; }
|
||||
|
||||
[DataMember(Name = "notifications")]
|
||||
public List<Notification> Notifications { get; private set; }
|
||||
}
|
||||
}
|
||||
75
src/Umbraco.Web/Models/LocalPackageInstallModel.cs
Normal file
75
src/Umbraco.Web/Models/LocalPackageInstallModel.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A model that represents uploading a local package
|
||||
/// </summary>
|
||||
[DataContract(Name = "localPackageInstallModel")]
|
||||
public class LocalPackageInstallModel : PackageInstallModel, IHaveUploadedFiles, INotificationModel
|
||||
{
|
||||
public LocalPackageInstallModel()
|
||||
{
|
||||
UploadedFiles = new List<ContentItemFile>();
|
||||
Notifications = new List<Notification>();
|
||||
}
|
||||
|
||||
public List<ContentItemFile> UploadedFiles { get; private set; }
|
||||
|
||||
[DataMember(Name = "notifications")]
|
||||
public List<Notification> Notifications { get; private set; }
|
||||
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataMember(Name = "url")]
|
||||
public string Url { get; set; }
|
||||
|
||||
[DataMember(Name = "version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[DataMember(Name = "containsUnsecureFiles")]
|
||||
public bool ContainsUnsecureFiles { get; set; }
|
||||
|
||||
[DataMember(Name = "containsTemplateConflicts")]
|
||||
public bool ContainsTemplateConflicts { get; set; }
|
||||
|
||||
[DataMember(Name = "containsStyleSheetConflicts")]
|
||||
public bool ContainsStyleSheetConflicts { get; set; }
|
||||
|
||||
[DataMember(Name = "containsMacroConflict")]
|
||||
public bool ContainsMacroConflict { get; set; }
|
||||
|
||||
[DataMember(Name = "containsLegacyPropertyEditors")]
|
||||
public bool ContainsLegacyPropertyEditors { get; set; }
|
||||
|
||||
[DataMember(Name = "containsBinaryFileErrors")]
|
||||
public bool ContainsBinaryFileErrors { get; set; }
|
||||
|
||||
[DataMember(Name = "conflictingTemplateAliases")]
|
||||
public IDictionary<string, string> ConflictingTemplateAliases { get; set; }
|
||||
|
||||
[DataMember(Name = "conflictingStyleSheetNames")]
|
||||
public IDictionary<string, string> ConflictingStyleSheetNames { get; set; }
|
||||
|
||||
[DataMember(Name = "conflictingMacroAliases")]
|
||||
public IDictionary<string, string> ConflictingMacroAliases { get; set; }
|
||||
|
||||
[DataMember(Name = "readMe")]
|
||||
public string ReadMe { get; set; }
|
||||
|
||||
[DataMember(Name = "licenseUrl")]
|
||||
public string LicenseUrl { get; set; }
|
||||
|
||||
[DataMember(Name = "license")]
|
||||
public string License { get; set; }
|
||||
|
||||
[DataMember(Name = "authorUrl")]
|
||||
public string AuthorUrl { get; set; }
|
||||
|
||||
[DataMember(Name = "author")]
|
||||
public string Author { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
@@ -10,7 +9,7 @@ namespace Umbraco.Web.Models
|
||||
[DataContract(Name = "packageInstallModel")]
|
||||
public class PackageInstallModel
|
||||
{
|
||||
[DataMember(Name="id")]
|
||||
[DataMember(Name = "id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[DataMember(Name = "packageGuid")]
|
||||
@@ -24,5 +23,7 @@ namespace Umbraco.Web.Models
|
||||
|
||||
[DataMember(Name = "zipFilePath")]
|
||||
public string ZipFilePath { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,9 +336,11 @@
|
||||
<Compile Include="Models\ContentEditing\MemberPropertyTypeDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\MemberTypeDisplay.cs" />
|
||||
<Compile Include="Models\ContentEditing\MemberTypeSave.cs" />
|
||||
<Compile Include="Models\ContentEditing\PostedFiles.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyGroupBasic.cs" />
|
||||
<Compile Include="Models\ContentEditing\PropertyTypeBasic.cs" />
|
||||
<Compile Include="Models\ContentEditing\SimpleNotificationModel.cs" />
|
||||
<Compile Include="Models\LocalPackageInstallModel.cs" />
|
||||
<Compile Include="Models\Mapping\ContentTypeModelMapperExtensions.cs" />
|
||||
<Compile Include="Models\Mapping\LockedCompositionsResolver.cs" />
|
||||
<Compile Include="Models\Mapping\PropertyGroupDisplayResolver.cs" />
|
||||
|
||||
Reference in New Issue
Block a user