Merge branch 'temp8' of https://github.com/umbraco/Umbraco-CMS into temp8
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
(function () {
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:multi
|
||||
* @restrict A
|
||||
* @description Used on input fields when you want to validate multiple fields at once.
|
||||
**/
|
||||
function multi($parse, $rootScope) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
link: function (scope, elem, attrs, ngModelCtrl) {
|
||||
var validate = $parse(attrs.multi)(scope);
|
||||
ngModelCtrl.$viewChangeListeners.push(function () {
|
||||
// ngModelCtrl.$setValidity('multi', validate());
|
||||
$rootScope.$broadcast('multi:valueChanged');
|
||||
});
|
||||
|
||||
var deregisterListener = scope.$on('multi:valueChanged', function (event) {
|
||||
ngModelCtrl.$setValidity('multi', validate());
|
||||
});
|
||||
scope.$on('$destroy', deregisterListener); // optional, only required for $rootScope.$on
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.directives.validation').directive('multi', ['$parse', '$rootScope', multi]);
|
||||
})();
|
||||
@@ -242,6 +242,44 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
{ id: id, culture: culture })),
|
||||
'Failed to publish content with id ' + id);
|
||||
},
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.contentResource#getCultureAndDomains
|
||||
* @methodOf umbraco.resources.contentResource
|
||||
*
|
||||
* @description
|
||||
* Gets the culture and hostnames for a content item with the given Id
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* contentResource.getCultureAndDomains(1234)
|
||||
* .then(function(data) {
|
||||
* alert(data.Domains, data.Language);
|
||||
* });
|
||||
* </pre>
|
||||
* @param {Int} id the ID of the node to get the culture and domains for.
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
getCultureAndDomains: function (id) {
|
||||
if (!id) {
|
||||
throw "id cannot be null";
|
||||
}
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetCultureAndDomains", { id: id })),
|
||||
'Failed to retreive culture and hostnames for ' + id);
|
||||
},
|
||||
saveLanguageAndDomains: function (model) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"PostSaveLanguageAndDomains"),
|
||||
model));
|
||||
},
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.contentResource#emptyRecycleBin
|
||||
@@ -334,26 +372,26 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
*/
|
||||
getById: function (id) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetById",
|
||||
{ id: id })),
|
||||
'Failed to retrieve data for content id ' + id)
|
||||
.then(function(result) {
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetById",
|
||||
{ id: id })),
|
||||
'Failed to retrieve data for content id ' + id)
|
||||
.then(function (result) {
|
||||
return $q.when(umbDataFormatter.formatContentGetData(result));
|
||||
});
|
||||
},
|
||||
|
||||
getBlueprintById: function (id) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetBlueprintById",
|
||||
[{ id: id }])),
|
||||
'Failed to retrieve data for content id ' + id)
|
||||
.then(function(result) {
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetBlueprintById",
|
||||
[{ id: id }])),
|
||||
'Failed to retrieve data for content id ' + id)
|
||||
.then(function (result) {
|
||||
return $q.when(umbDataFormatter.formatContentGetData(result));
|
||||
});
|
||||
},
|
||||
@@ -410,15 +448,15 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
});
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetByIds",
|
||||
idQuery)),
|
||||
'Failed to retrieve data for content with multiple ids')
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetByIds",
|
||||
idQuery)),
|
||||
'Failed to retrieve data for content with multiple ids')
|
||||
.then(function (result) {
|
||||
//each item needs to be re-formatted
|
||||
_.each(result, function(r) {
|
||||
_.each(result, function (r) {
|
||||
umbDataFormatter.formatContentGetData(r)
|
||||
});
|
||||
return $q.when(result);
|
||||
@@ -461,13 +499,13 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
getScaffold: function (parentId, alias) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetEmpty",
|
||||
[{ contentTypeAlias: alias }, { parentId: parentId }])),
|
||||
'Failed to retrieve data for empty content item type ' + alias)
|
||||
.then(function(result) {
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetEmpty",
|
||||
[{ contentTypeAlias: alias }, { parentId: parentId }])),
|
||||
'Failed to retrieve data for empty content item type ' + alias)
|
||||
.then(function (result) {
|
||||
return $q.when(umbDataFormatter.formatContentGetData(result));
|
||||
});
|
||||
},
|
||||
@@ -475,13 +513,13 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
getBlueprintScaffold: function (parentId, blueprintId) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetEmpty",
|
||||
[{ blueprintId: blueprintId }, { parentId: parentId }])),
|
||||
'Failed to retrieve blueprint for id ' + blueprintId)
|
||||
.then(function(result) {
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetEmpty",
|
||||
[{ blueprintId: blueprintId }, { parentId: parentId }])),
|
||||
'Failed to retrieve blueprint for id ' + blueprintId)
|
||||
.then(function (result) {
|
||||
return $q.when(umbDataFormatter.formatContentGetData(result));
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,24 +1,70 @@
|
||||
<div ng-controller="Umbraco.Editors.Content.AssignDomainController as vm">
|
||||
<div class="umb-dialog-body">
|
||||
<umb-pane>
|
||||
<p>UI magic to be done...</p>
|
||||
</umb-pane>
|
||||
</div>
|
||||
<div ng-controller="Umbraco.Editors.Content.AssignDomainController as vm" ng-cloak>
|
||||
<div class="umb-dialog-body">
|
||||
<umb-pane>
|
||||
<h5 class="umb-pane-title"><localize key="assignDomain_setLanguage">Culture</localize></h5>
|
||||
<label for="assignDomain_language" class="control-label"><localize key="general_language"></localize></label>
|
||||
<select class="umb-property-editor umb-dropdown" name="language" id="assignDomain_language" ng-model="vm.language" ng-options="lang.name for lang in vm.languages">
|
||||
<option value="">{{vm.inherit}}</option>
|
||||
</select>
|
||||
</umb-pane>
|
||||
<umb-pane>
|
||||
<h5 class="umb-pane-title"><localize key="assignDomain_setDomains">Domains</localize></h5>
|
||||
<form name="vm.domainForm" novalidate="" ng-submit="vm.save()" class="control-group umb-control-group">
|
||||
<small class="help-inline">
|
||||
<localize key="assignDomain_domainHelp"></localize>
|
||||
</small>
|
||||
<div class="umb-el-wrap hidelabel">
|
||||
<table class="table domains" ng-if="vm.domains.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><localize key="assignDomain_domain"></localize></th>
|
||||
<th><localize key="assignDomain_language"></localize></th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="domain in vm.domains">
|
||||
<td>
|
||||
<input type="text" ng-model="domain.Name" multi="vm.validateDomain" ng-pattern="vm.domainPattern" name="domain_name_{{$index}}" />
|
||||
<span ng-if="vm.domainForm.$submitted" ng-messages="vm.domainForm['domain_name_' + $index].$error">
|
||||
<span class="help-inline" ng-message="multi"><localize key="assignDomain_duplicateDomain"></localize></span>
|
||||
<span class="help-inline" ng-message="pattern"><localize key="assignDomain_invalidDomain"></localize></span>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<select name="domain_language_{{$index}}" class="language" ng-model="domain.Lang" ng-options="lang.name for lang in vm.languages"></select>
|
||||
</td>
|
||||
<td>
|
||||
<umb-button icon="icon-trash"
|
||||
action="vm.removeDomain($index)"
|
||||
type="button"
|
||||
button-style="danger">
|
||||
</umb-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<umb-button label-key="assignDomain_addNew"
|
||||
action="vm.addDomain()"
|
||||
type="button">
|
||||
</umb-button>
|
||||
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
|
||||
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
<umb-button label-key="general_cancel"
|
||||
action="vm.closeDialog()"
|
||||
type="button"
|
||||
button-style="link">
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
label-key="general_cancel"
|
||||
action="vm.closeDialog()"
|
||||
type="button"
|
||||
button-style="link">
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
label-key="buttons_save"
|
||||
type="button"
|
||||
button-style="success">
|
||||
</umb-button>
|
||||
<umb-button label-key="buttons_save"
|
||||
type="submit"
|
||||
button-style="success">
|
||||
</umb-button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</umb-pane>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,126 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function AssignDomainController($scope) {
|
||||
|
||||
function AssignDomainController($scope, localizationService, languageResource, contentResource) {
|
||||
var vm = this;
|
||||
vm.closeDialog = closeDialog;
|
||||
|
||||
function closeDialog() {
|
||||
$scope.nav.hideDialog();
|
||||
vm.addDomain = addDomain;
|
||||
vm.removeDomain = removeDomain;
|
||||
vm.save = save;
|
||||
vm.validateDomain = validateDomain;
|
||||
vm.languages = [];
|
||||
vm.domains = [];
|
||||
vm.language = null;
|
||||
vm.domainPattern = /^(http[s]?:\/\/)?([-\w]+(\.[-\w]+)*)(:\d+)?(\/[-\w]*|-)?$/gi; //TODO: This regex is not working as it should.
|
||||
function activate() {
|
||||
languageResource.getAll().then(function (langs) {
|
||||
vm.languages = langs;
|
||||
var defLang = langs.filter(function (l) {
|
||||
return l.isDefault;
|
||||
});
|
||||
|
||||
if (defLang.length > 0) {
|
||||
vm.defaultLanguage = defLang[0];
|
||||
}
|
||||
else {
|
||||
vm.defaultLanguage = langs[0];
|
||||
}
|
||||
getCultureAndDomains();
|
||||
});
|
||||
|
||||
localizationService.localize("assignDomain_inherit").then(function (value) {
|
||||
vm.inherit = value;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function getCultureAndDomains () {
|
||||
contentResource.getCultureAndDomains($scope.currentNode.id)
|
||||
.then(function (data) {
|
||||
if (data.Language !== "undefined") {
|
||||
var lang = vm.languages.filter(function (l) {
|
||||
return matchLanguageById(l, data.Language.Id);
|
||||
|
||||
});
|
||||
if (lang.length > 0) {
|
||||
vm.language = lang[0];
|
||||
}
|
||||
}
|
||||
vm.domains = data.Domains.map(function (d) {
|
||||
var matchedLangs = vm.languages.filter(function (l) {
|
||||
return matchLanguageById(l, d.Language);
|
||||
|
||||
});
|
||||
return {
|
||||
Name: d.Name,
|
||||
Lang: matchedLangs.length > 0 ? matchedLangs[0] : vm.defaultLanguage
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function matchLanguageById(language, id) {
|
||||
return language.Id === id;
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
$scope.nav.hideDialog();
|
||||
}
|
||||
|
||||
function addDomain() {
|
||||
vm.domains.push({
|
||||
Name: '',
|
||||
Lang: vm.defaultLanguage
|
||||
});
|
||||
}
|
||||
|
||||
function removeDomain(index) {
|
||||
vm.domains.splice(index, 1);
|
||||
}
|
||||
|
||||
function validateDomain() {
|
||||
var valid = true, duplicateTest = {};
|
||||
if (vm.domains.length > 1) {
|
||||
|
||||
vm.domains.map(function (d, index) {
|
||||
if (d.Name in duplicateTest) {
|
||||
valid = false;
|
||||
}
|
||||
else {
|
||||
duplicateTest[d.Name] = index;
|
||||
}
|
||||
});
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
function save() {
|
||||
|
||||
if (vm.domainForm.$valid) {
|
||||
var data = {
|
||||
NodeId: $scope.currentNode.id,
|
||||
Domains: vm.domains.map(function (d) {
|
||||
return {
|
||||
Name: d.Name,
|
||||
Lang: d.Lang.id
|
||||
};
|
||||
}),
|
||||
Language: vm.language != null ? vm.language.id : 0
|
||||
};
|
||||
console.log(data);
|
||||
contentResource.saveLanguageAndDomains(data).then(function () {
|
||||
closeDialog();
|
||||
}, function (e) {
|
||||
console.log(e); //TODO: not sure how best to handle this case
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log('not valid');
|
||||
}
|
||||
}
|
||||
|
||||
activate();
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Editors.Content.AssignDomainController", AssignDomainController);
|
||||
})();
|
||||
|
||||
})();
|
||||
@@ -333,7 +333,6 @@
|
||||
<Content Include="Umbraco\Developer\RelationTypes\RelationTypesWebService.asmx" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\TreeMenu\ActionDeleteRelationType.js" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\TreeMenu\ActionNewRelationType.js" />
|
||||
<Content Include="Umbraco\Dialogs\AssignDomain2.aspx" />
|
||||
<Content Include="Umbraco\Dialogs\ChangeDocType.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master" Codebehind="AssignDomain2.aspx.cs" AutoEventWireup="True" Inherits="umbraco.dialogs.AssignDomain2" %>
|
||||
<%@ Import Namespace="Umbraco.Web" %>
|
||||
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
|
||||
<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="head" runat="server">
|
||||
<umb:JsInclude runat="server" FilePath="Dialogs/AssignDomain2.js" PathNameAlias="UmbracoClient" />
|
||||
<umb:JsInclude runat="server" FilePath="PunyCode/punycode.min.js" PathNameAlias="UmbracoClient" />
|
||||
<umb:JsInclude runat="server" FilePath="/Umbraco/lib/jquery-validate/jquery.validate.min.js" PathNameAlias="UmbracoClient" />
|
||||
<umb:CssInclude runat="server" FilePath="Dialogs/AssignDomain2.css" PathNameAlias="UmbracoClient" />
|
||||
<script type="text/javascript">
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
var dialog = new Umbraco.Dialogs.AssignDomain2({
|
||||
nodeId: <%=GetNodeId()%>,
|
||||
restServiceLocation: '<%=GetRestServicePath() %>',
|
||||
invalidDomain: '<%=Services.TextService.Localize("assignDomain/invalidDomain") %>',
|
||||
duplicateDomain: '<%=Services.TextService.Localize("assignDomain/duplicateDomain") %>',
|
||||
<asp:Literal runat="server" ID="data" />
|
||||
});
|
||||
dialog.init();
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ContentPlaceHolderID="body" runat="server">
|
||||
|
||||
<div class="umb-dialog-body">
|
||||
|
||||
<cc1:Feedback ID="feedback" runat="server" />
|
||||
<div id="komask"></div>
|
||||
|
||||
<cc1:Pane runat="server" ID="pane_language" cssClass="hide">
|
||||
<cc1:PropertyPanel runat="server" ID="prop_language">
|
||||
<select class="umb-property-editor umb-dropdown" name="language" data-bind="options: languages, optionsText: 'Code', optionsValue: 'Id', value: language, optionsCaption: '<%=Services.TextService.Localize("assignDomain/inherit") %> '"></select>
|
||||
<!-- <small class="help-inline"><%=Services.TextService.Localize("assignDomain/setLanguageHelp") %></small>-->
|
||||
</cc1:PropertyPanel>
|
||||
</cc1:Pane>
|
||||
|
||||
|
||||
<cc1:Pane runat="server" ID="pane_domains">
|
||||
<small class="help-inline"><%=Services.TextService.Localize("assignDomain/domainHelp") %></small>
|
||||
<cc1:PropertyPanel runat="server">
|
||||
<table class="table domains" data-bind="visible: domains().length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%=Services.TextService.Localize("assignDomain/domain") %></th>
|
||||
<th><%=Services.TextService.Localize("assignDomain/language") %></th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-bind="foreach: domains">
|
||||
<tr>
|
||||
<td valign="top"><input class="domain duplicate" data-bind="value: Name, uniqueName: true" /><input type="hidden" value="" data-bind="uniqueName: true"/></td>
|
||||
<td valign="top"><select class="language" data-bind="options: $parent.languages, optionsText: 'Code', optionsValue: 'Id', value: Lang, uniqueName: true"></select></td>
|
||||
<td valign="top"><a href="#" class="btn btn-danger" data-bind="click: $parent.removeDomain"><i class="icon icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</cc1:PropertyPanel>
|
||||
|
||||
<cc1:PropertyPanel runat="server">
|
||||
<button class="btn" data-bind="click: addDomain"><%=Services.TextService.Localize("assignDomain/addNew") %></button>
|
||||
</cc1:PropertyPanel>
|
||||
|
||||
|
||||
</cc1:Pane>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div runat="server" ID="p_buttons" class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
<a href="#" class="btn btn-link" onclick="UmbClientMgr.closeModalWindow()"><%=Services.TextService.Localize("general/cancel")%></a>
|
||||
<button class="btn btn-primary" id="btnSave"><%=Services.TextService.Localize("buttons/save") %></button>
|
||||
</div>
|
||||
|
||||
</asp:Content>
|
||||
@@ -56,6 +56,8 @@ namespace Umbraco.Web.Editors
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly Lazy<IDictionary<string, ILanguage>> _allLangs;
|
||||
|
||||
public object Domains { get; private set; }
|
||||
|
||||
public ContentController(IPublishedSnapshotService publishedSnapshotService, PropertyEditorCollection propertyEditors)
|
||||
{
|
||||
if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService));
|
||||
@@ -1146,6 +1148,18 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
}
|
||||
|
||||
public ContentDomainsAndCulture GetCultureAndDomains(int id)
|
||||
{
|
||||
var nodeDomains = Services.DomainService.GetAssignedDomains(id, true).ToArray();
|
||||
var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
|
||||
var domains = nodeDomains.Where(d => !d.IsWildcard).Select(d => new DomainDisplay(d.DomainName, d.LanguageId.GetValueOrDefault(0)));
|
||||
return new ContentDomainsAndCulture
|
||||
{
|
||||
Domains = domains,
|
||||
Language = wildcard == null || !wildcard.LanguageId.HasValue ? "undefined" : wildcard.LanguageId.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public DomainSave PostSaveLanguageAndDomains(DomainSave model)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
public class ContentDomainsAndCulture
|
||||
{
|
||||
public IEnumerable<DomainDisplay> Domains { get; set; }
|
||||
|
||||
public string Language { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -163,6 +163,7 @@
|
||||
<Compile Include="Editors\BackOfficeServerVariables.cs" />
|
||||
<Compile Include="ImageProcessorLogger.cs" />
|
||||
<Compile Include="Macros\MacroTagParser.cs" />
|
||||
<Compile Include="Models\ContentEditing\ContentDomainsAndCulture.cs" />
|
||||
<Compile Include="Models\ContentEditing\ContentSavedState.cs" />
|
||||
<Compile Include="Models\Mapping\ContentSavedStateResolver.cs" />
|
||||
<Compile Include="OwinExtensions.cs" />
|
||||
|
||||
Reference in New Issue
Block a user