Merge origin/temp8 into temp8
This commit is contained in:
@@ -128,7 +128,12 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
To<UpdatePickerIntegerValuesToUdi>("{38C809D5-6C34-426B-9BEA-EFD39162595C}");
|
||||
To<RenameUmbracoDomainsTable>("{6017F044-8E70-4E10-B2A3-336949692ADD}");
|
||||
To<AddUserLoginDtoDateIndex>("{98339BEF-E4B2-48A8-B9D1-D173DC842BBE}");
|
||||
To<DropXmlTables>("{CDBEDEE4-9496-4903-9CF2-4104E00FF960}");
|
||||
|
||||
Merge()
|
||||
.To<DropXmlTables>("{CDBEDEE4-9496-4903-9CF2-4104E00FF960}")
|
||||
.With()
|
||||
.To<RadioAndCheckboxAndDropdownPropertyEditorsMigration>("{940FD19A-00A8-4D5C-B8FF-939143585726}")
|
||||
.As("{0576E786-5C30-4000-B969-302B61E90CA3}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
public class RadioAndCheckboxAndDropdownPropertyEditorsMigration : MigrationBase
|
||||
{
|
||||
public RadioAndCheckboxAndDropdownPropertyEditorsMigration(IMigrationContext context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var refreshCache = false;
|
||||
|
||||
refreshCache |= Migrate(Constants.PropertyEditors.Aliases.RadioButtonList, (dto, configuration) => UpdateRadioOrCheckboxPropertyDataDto(dto, configuration, true));
|
||||
refreshCache |= Migrate(Constants.PropertyEditors.Aliases.CheckBoxList, (dto, configuration) => UpdateRadioOrCheckboxPropertyDataDto(dto, configuration, false));
|
||||
refreshCache |= Migrate(Constants.PropertyEditors.Aliases.DropDownListFlexible, UpdateDropDownPropertyDataDto);
|
||||
|
||||
if (refreshCache)
|
||||
{
|
||||
//FIXME: trigger cache rebuild. Currently the data in the database tables is wrong.
|
||||
}
|
||||
}
|
||||
|
||||
private bool Migrate(string editorAlias, Func<PropertyDataDto, ValueListConfiguration, bool> updateRadioPropertyDataFunc)
|
||||
{
|
||||
var refreshCache = false;
|
||||
var dataTypes = GetDataTypes(editorAlias);
|
||||
|
||||
foreach (var dataType in dataTypes)
|
||||
{
|
||||
ValueListConfiguration config;
|
||||
|
||||
if (dataType.Configuration.IsNullOrWhiteSpace())
|
||||
continue;
|
||||
|
||||
// parse configuration, and update everything accordingly
|
||||
try
|
||||
{
|
||||
config = (ValueListConfiguration) new ValueListConfigurationEditor().FromDatabase(
|
||||
dataType.Configuration);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error<DropDownPropertyEditorsMigration>(
|
||||
ex,
|
||||
"Invalid radio button configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared",
|
||||
dataType.Configuration);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// get property data dtos
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto>(Sql()
|
||||
.Select<PropertyDataDto>()
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyTypeDto, PropertyDataDto>((pt, pd) => pt.Id == pd.PropertyTypeId)
|
||||
.InnerJoin<DataTypeDto>()
|
||||
.On<DataTypeDto, PropertyTypeDto>((dt, pt) => dt.NodeId == pt.DataTypeId)
|
||||
.Where<PropertyTypeDto>(x => x.DataTypeId == dataType.NodeId));
|
||||
|
||||
// update dtos
|
||||
var updatedDtos = propertyDataDtos.Where(x => updateRadioPropertyDataFunc(x, config));
|
||||
|
||||
// persist changes
|
||||
foreach (var propertyDataDto in updatedDtos) Database.Update(propertyDataDto);
|
||||
|
||||
UpdateDataType(dataType);
|
||||
refreshCache = true;
|
||||
}
|
||||
|
||||
return refreshCache;
|
||||
}
|
||||
|
||||
private List<DataTypeDto> GetDataTypes(string editorAlias)
|
||||
{
|
||||
//need to convert the old drop down data types to use the new one
|
||||
var dataTypes = Database.Fetch<DataTypeDto>(Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == editorAlias));
|
||||
return dataTypes;
|
||||
}
|
||||
|
||||
private void UpdateDataType(DataTypeDto dataType)
|
||||
{
|
||||
dataType.DbType = ValueStorageType.Nvarchar.ToString();
|
||||
Database.Update(dataType);
|
||||
}
|
||||
|
||||
private bool UpdateRadioOrCheckboxPropertyDataDto(PropertyDataDto propData, ValueListConfiguration config, bool singleValue)
|
||||
{
|
||||
//Get the INT ids stored for this property/drop down
|
||||
int[] ids = null;
|
||||
if (!propData.VarcharValue.IsNullOrWhiteSpace())
|
||||
{
|
||||
ids = ConvertStringValues(propData.VarcharValue);
|
||||
}
|
||||
else if (!propData.TextValue.IsNullOrWhiteSpace())
|
||||
{
|
||||
ids = ConvertStringValues(propData.TextValue);
|
||||
}
|
||||
else if (propData.IntegerValue.HasValue)
|
||||
{
|
||||
ids = new[] {propData.IntegerValue.Value};
|
||||
}
|
||||
|
||||
//if there are INT ids, convert them to values based on the configuration
|
||||
if (ids == null || ids.Length <= 0) return false;
|
||||
|
||||
//map the ids to values
|
||||
var values = new List<string>();
|
||||
var canConvert = true;
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var val = config.Items.FirstOrDefault(x => x.Id == id);
|
||||
if (val != null)
|
||||
values.Add(val.Value);
|
||||
else
|
||||
{
|
||||
Logger.Warn<DropDownPropertyEditorsMigration>(
|
||||
"Could not find associated data type configuration for stored Id {DataTypeId}", id);
|
||||
canConvert = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canConvert) return false;
|
||||
|
||||
//The radio button only supports selecting a single value, so if there are multiple for some insane reason we can only use the first
|
||||
propData.VarcharValue = singleValue ? values[0] : JsonConvert.SerializeObject(values);
|
||||
propData.TextValue = null;
|
||||
propData.IntegerValue = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool UpdateDropDownPropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
|
||||
{
|
||||
//Get the INT ids stored for this property/drop down
|
||||
var values = propData.VarcharValue.Split(new []{","}, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
//if there are INT ids, convert them to values based on the configuration
|
||||
if (values == null || values.Length <= 0) return false;
|
||||
|
||||
//The radio button only supports selecting a single value, so if there are multiple for some insane reason we can only use the first
|
||||
propData.VarcharValue = JsonConvert.SerializeObject(values);
|
||||
propData.TextValue = null;
|
||||
propData.IntegerValue = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
private int[] ConvertStringValues(string val)
|
||||
{
|
||||
var splitVals = val.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var intVals = splitVals
|
||||
.Select(x => int.TryParse(x, out var i) ? i : int.MinValue)
|
||||
.Where(x => x != int.MinValue)
|
||||
.ToArray();
|
||||
|
||||
//only return if the number of values are the same (i.e. All INTs)
|
||||
if (splitVals.Length == intVals.Length)
|
||||
return intVals;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private class ValueListConfigurationEditor : ConfigurationEditor<ValueListConfiguration>
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
@@ -8,8 +9,6 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
[DefaultPropertyValueConverter]
|
||||
public class CheckboxListValueConverter : PropertyValueConverterBase
|
||||
{
|
||||
private static readonly char[] Comma = { ',' };
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.CheckBoxList);
|
||||
|
||||
@@ -26,7 +25,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
if (string.IsNullOrEmpty(sourceString))
|
||||
return Enumerable.Empty<string>();
|
||||
|
||||
return sourceString.Split(Comma, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim());
|
||||
return JsonConvert.DeserializeObject<string[]>(sourceString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,17 +10,17 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
=> propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.RadioButtonList);
|
||||
|
||||
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
=> typeof (int);
|
||||
=> typeof (string);
|
||||
|
||||
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
|
||||
=> PropertyCacheLevel.Element;
|
||||
|
||||
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
var intAttempt = source.TryConvertTo<int>();
|
||||
var attempt = source.TryConvertTo<string>();
|
||||
|
||||
if (intAttempt.Success)
|
||||
return intAttempt.Result;
|
||||
if (attempt.Success)
|
||||
return attempt.Result;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -387,6 +387,7 @@
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\PropertyEditorsMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RefactorMacroColumns.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RefactorVariantsModel.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RadioAndCheckboxAndDropdownPropertyEditorsMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RenameUmbracoDomainsTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\SuperZero.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\TablesForScheduledPublishing.cs" />
|
||||
|
||||
@@ -65,9 +65,9 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[TestCase("apples", new[] { "apples" })]
|
||||
[TestCase("apples,oranges", new[] { "apples", "oranges" })]
|
||||
[TestCase(" apples, oranges, pears ", new[] { "apples", "oranges", "pears" })]
|
||||
[TestCase("[\"apples\"]", new[] { "apples" })]
|
||||
[TestCase("[\"apples\",\"oranges\"]", new[] { "apples", "oranges" })]
|
||||
[TestCase("[\"apples\",\"oranges\",\"pears\"]", new[] { "apples", "oranges", "pears" })]
|
||||
[TestCase("", new string[] { })]
|
||||
[TestCase(null, new string[] { })]
|
||||
public void CanConvertCheckboxListPropertyEditor(object value, IEnumerable<string> expected)
|
||||
@@ -78,9 +78,9 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[TestCase("apples", new[] { "apples" })]
|
||||
[TestCase("apples,oranges", new[] { "apples", "oranges" })]
|
||||
[TestCase("apples , oranges, pears ", new[] { "apples", "oranges", "pears" })]
|
||||
[TestCase("[\"apples\"]", new[] { "apples" })]
|
||||
[TestCase("[\"apples\",\"oranges\"]", new[] { "apples", "oranges" })]
|
||||
[TestCase("[\"apples\",\"oranges\",\"pears\"]", new[] { "apples", "oranges", "pears" })]
|
||||
[TestCase("", new string[] { })]
|
||||
[TestCase(null, new string[] { })]
|
||||
public void CanConvertDropdownListMultiplePropertyEditor(object value, IEnumerable<string> expected)
|
||||
@@ -104,7 +104,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("1", 1)]
|
||||
[TestCase("1", 1)]
|
||||
[TestCase("0", 0)]
|
||||
|
||||
@@ -191,13 +191,13 @@ input[type="button"] {
|
||||
.btn-success {
|
||||
.buttonBackground(@btnSuccessBackground, @btnSuccessBackgroundHighlight, @btnSuccessType);
|
||||
}
|
||||
// Info appears as a neutral blue
|
||||
// Info appears as a sand color
|
||||
.btn-info {
|
||||
.buttonBackground(@sand-5, @blueDark, @blueExtraDark, @u-white);
|
||||
.buttonBackground(@sand-5, @sand-6, @blueExtraDark, @blueMid);
|
||||
}
|
||||
// Made for Umbraco, 2019
|
||||
.btn-action {
|
||||
.buttonBackground(@blueExtraDark, @blueDark, @pinkLight, @u-white);
|
||||
.buttonBackground(@blueExtraDark, @blueDark, @white, @u-white);
|
||||
}
|
||||
// Made for Umbraco, 2019
|
||||
.btn-selection {
|
||||
@@ -236,11 +236,11 @@ input[type="button"] {
|
||||
padding: 15px 50px;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
background: @green;
|
||||
background: @ui-btn-positive;
|
||||
color: @white;
|
||||
font-weight: bold;
|
||||
&:hover {
|
||||
background: @green-d1;
|
||||
background: @ui-btn-positive-hover;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -15,6 +15,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.umb-editor-sub-header.--state-selection {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: @pinkLight;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.umb-editor-sub-header.-umb-sticky-bar {
|
||||
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
|
||||
transition: box-shadow 1s;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.umb-user-card:hover,
|
||||
@@ -15,6 +17,22 @@
|
||||
outline: none;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
.umb-user-card.-selected {
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index:2;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
border: 2px solid @ui-selected-border;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 4px 0 darken(@ui-selected-border, 20), inset 0 0 2px 0 darken(@ui-selected-border, 20);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.umb-user-card__content {
|
||||
position: relative;
|
||||
@@ -30,9 +48,12 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.umb-user-card__content:hover,
|
||||
.umb-user-card:focus .umb-user-card__content {
|
||||
border-color: @turquoise;
|
||||
.umb-user-card__goToUser {
|
||||
&:hover {
|
||||
.umb-user-card__name {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.umb-user-card__avatar {
|
||||
@@ -47,24 +68,13 @@
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
|
||||
.umb-user-card__name {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 2px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.umb-user-card__checkmark {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.umb-user-card:hover .umb-user-card__checkmark,
|
||||
.umb-user-card__checkmark--visible {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.umb-user-card__group {
|
||||
@@ -77,4 +87,4 @@
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@
|
||||
|
||||
&.disabled, &[disabled] {
|
||||
color: @white;
|
||||
background-color: @sand-2;
|
||||
background-color: @sand-1;
|
||||
}
|
||||
/*
|
||||
// IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves
|
||||
|
||||
@@ -62,6 +62,15 @@ table {
|
||||
}
|
||||
|
||||
|
||||
.table tr > td:first-child {
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
.table tr.--selected > td:first-child {
|
||||
border-left-color:@ui-selected-border;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// CONDENSED TABLE W/ HALF PADDING
|
||||
// -------------------------------
|
||||
|
||||
@@ -76,9 +76,10 @@
|
||||
@gray-10: #F3F3F5;
|
||||
@gray-11: #F6F6F7;
|
||||
|
||||
@sand-1: hsl(22, 33%, 93%);// added 2019
|
||||
@sand-1: hsl(22, 18%, 84%);// added 2019
|
||||
@sand-2: hsl(22, 34%, 88%);// added 2019
|
||||
@sand-5: hsl(22, 31%, 93%);// added 2019
|
||||
@sand-6: hsl(22, 29%, 95%);// added 2019
|
||||
@sand-7: hsl(22, 26%, 97%);// added 2019
|
||||
|
||||
|
||||
@@ -138,8 +139,8 @@
|
||||
@ui-active-type: @blueExtraDark;
|
||||
@ui-active-type-hover: @blueMid;
|
||||
|
||||
@ui-selected: @sand-1;
|
||||
@ui-selected-hover: ligthen(@sand-1, 10);
|
||||
@ui-selected: @sand-5;
|
||||
@ui-selected-hover: ligthen(@sand-5, 10);
|
||||
@ui-selected-type: @blueExtraDark;
|
||||
@ui-selected-type-hover: @blueMid;
|
||||
@ui-selected-border: @pinkLight;
|
||||
@@ -176,7 +177,7 @@
|
||||
@ui-btn-type: @white;
|
||||
|
||||
@ui-btn-positive: @green;
|
||||
@ui-btn-positive-hover: @green-l1;
|
||||
@ui-btn-positive-hover: lighten(@green, 6%);
|
||||
@ui-btn-positive-type: @white;
|
||||
|
||||
@ui-btn-negative: @red;
|
||||
|
||||
+1
@@ -180,6 +180,7 @@
|
||||
button-style="success"
|
||||
label="Select image"
|
||||
type="button"
|
||||
disabled="model.selection.length === 0"
|
||||
action="submit(model)">
|
||||
</umb-button>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<!--<i ng-show="item.selected" class="icon-check umb-media-grid__checkmark"></i>-->
|
||||
<a ng-if="allowOnClickEdit === 'true'" ng-click="clickEdit(item, $event)" ng-href="" class="icon-edit umb-media-grid__edit"></a>
|
||||
|
||||
<div data-element="media-grid-item-edit" class="umb-media-grid__item-overlay" ng-class="{'-locked': item.selected}" ng-click="clickItemName(item, $event, $index)">
|
||||
<div data-element="media-grid-item-edit" class="umb-media-grid__item-overlay" ng-class="{'-locked': item.selected || !item.file}" ng-click="clickItemName(item, $event, $index)">
|
||||
<i ng-if="onDetailsHover" class="icon-info umb-media-grid__info" ng-mouseover="hoverItemDetails(item, $event, true)" ng-mouseleave="hoverItemDetails(item, $event, false)"></i>
|
||||
<div class="umb-media-grid__item-name">{{item.name}}</div>
|
||||
</div>
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
<div>{{ group.label }}</div>
|
||||
<ins class="umb-expansion-panel__expand" ng-class="{'icon-navigation-down': !group.open, 'icon-navigation-up': group.open}" class="icon-navigation-right"> </ins>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-expansion-panel__content" ng-show="group.open">
|
||||
<umb-property data-element="property-{{group.alias}}" ng-repeat="property in group.properties track by property.alias" property="property">
|
||||
<umb-property-editor model="property"></umb-property-editor>
|
||||
</umb-property>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</umb-editor-container>
|
||||
@@ -38,8 +38,8 @@
|
||||
<umb-editor-footer>
|
||||
|
||||
<umb-editor-footer-content-left>
|
||||
<umb-breadcrumbs
|
||||
ng-if="ancestors && ancestors.length > 0"
|
||||
<umb-breadcrumbs
|
||||
ng-if="ancestors && ancestors.length > 0"
|
||||
ancestors="ancestors">
|
||||
</umb-breadcrumbs>
|
||||
</umb-editor-footer-content-left>
|
||||
@@ -51,6 +51,7 @@
|
||||
ng-if="page.listViewPath"
|
||||
type="link"
|
||||
href="#{{page.listViewPath}}"
|
||||
button-style="link"
|
||||
label="Return to list"
|
||||
label-key="buttons_returnToList">
|
||||
</umb-button>
|
||||
|
||||
+5
-5
@@ -42,7 +42,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.CheckboxListContro
|
||||
return f.checked;
|
||||
}),
|
||||
function(m) {
|
||||
return m.key;
|
||||
return m.value;
|
||||
});
|
||||
//get all of the same values between the arrays
|
||||
var same = _.intersection($scope.model.value, selectedVals);
|
||||
@@ -54,7 +54,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.CheckboxListContro
|
||||
$scope.selectedItems = [];
|
||||
|
||||
for (var i = 0; i < configItems.length; i++) {
|
||||
var isChecked = _.contains($scope.model.value, configItems[i].id);
|
||||
var isChecked = _.contains($scope.model.value, configItems[i].value);
|
||||
$scope.selectedItems.push({
|
||||
checked: isChecked,
|
||||
key: configItems[i].id,
|
||||
@@ -66,13 +66,13 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.CheckboxListContro
|
||||
function changed(item) {
|
||||
var index = _.findIndex($scope.model.value,
|
||||
function (v) {
|
||||
return v === item.key;
|
||||
return v === item.value;
|
||||
});
|
||||
|
||||
|
||||
if (item.checked) {
|
||||
//if it doesn't exist in the model, then add it
|
||||
if (index < 0) {
|
||||
$scope.model.value.push(item.key);
|
||||
$scope.model.value.push(item.value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<li ng-repeat="item in selectedItems track by item.key">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="checkboxlist"
|
||||
value="{{item.key}}"
|
||||
value="{{item.value}}"
|
||||
ng-model="item.checked"
|
||||
ng-change="changed(item)"
|
||||
ng-change="changed(item)"
|
||||
ng-required="model.validation.mandatory && !model.value.length" />
|
||||
{{item.val}}
|
||||
</label>
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
function EditConfigController($scope) {
|
||||
|
||||
$scope.close = function() {
|
||||
if($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.submit = function() {
|
||||
if($scope.model && $scope.model.submit) {
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.GridPrevalueEditor.EditConfigController", EditConfigController);
|
||||
@@ -1,3 +1,25 @@
|
||||
<div class="usky-grid usky-grid-configuration" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.EditConfigController">
|
||||
|
||||
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<form novalidate name="EditConfigForm" val-form-manager>
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
|
||||
|
||||
|
||||
<form name="gridConfigEditor">
|
||||
|
||||
<h4>{{model.name}}</h4>
|
||||
@@ -12,3 +34,34 @@
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="close()">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="success"
|
||||
label-key="general_submit"
|
||||
action="submit()">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</form>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
|
||||
+24
-4
@@ -1,10 +1,25 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.GridPrevalueEditor.LayoutConfigController",
|
||||
function ($scope) {
|
||||
function ($scope, localizationService) {
|
||||
|
||||
|
||||
function init() {
|
||||
setTitle();
|
||||
}
|
||||
|
||||
function setTitle() {
|
||||
if (!$scope.model.title) {
|
||||
localizationService.localize("grid_addGridLayout")
|
||||
.then(function(data){
|
||||
$scope.model.title = data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.currentLayout = $scope.model.currentLayout;
|
||||
$scope.columns = $scope.model.columns;
|
||||
$scope.rows = $scope.model.rows;
|
||||
$scope.currentSection = undefined;
|
||||
|
||||
$scope.scaleUp = function(section, max, overflow){
|
||||
var add = 1;
|
||||
@@ -57,9 +72,12 @@ angular.module("umbraco")
|
||||
template.sections.splice(index, 1);
|
||||
};
|
||||
|
||||
$scope.closeSection = function(){
|
||||
$scope.currentSection = undefined;
|
||||
};
|
||||
|
||||
$scope.close = function() {
|
||||
if($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch("currentLayout", function(layout){
|
||||
if(layout){
|
||||
@@ -71,4 +89,6 @@ angular.module("umbraco")
|
||||
$scope.availableLayoutSpace = $scope.columns - total;
|
||||
}
|
||||
}, true);
|
||||
|
||||
init();
|
||||
});
|
||||
|
||||
@@ -1,8 +1,31 @@
|
||||
<div class="usky-grid usky-grid-configuration" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.LayoutConfigController">
|
||||
|
||||
<div class="umb-forms-settings">
|
||||
|
||||
<h5><localize key="grid_addGridLayout" /></h5>
|
||||
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<form novalidate name="LayoutConfigForm" val-form-manager>
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="umb-forms-settings form-horizontal">
|
||||
|
||||
<p><localize key="grid_addGridLayoutDetail" /></p>
|
||||
|
||||
<umb-control-group label="@general_name">
|
||||
@@ -32,7 +55,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="currentSection" style="padding-bottom: 50px;">
|
||||
<div ng-if="currentSection != null" style="padding-bottom: 50px;">
|
||||
|
||||
<umb-control-group label="@general_width">
|
||||
<div class="grid-size-scaler">
|
||||
@@ -111,4 +134,27 @@
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="close()">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</form>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
|
||||
+25
-1
@@ -1,5 +1,19 @@
|
||||
function RowConfigController($scope) {
|
||||
function RowConfigController($scope, localizationService) {
|
||||
|
||||
function init() {
|
||||
setTitle();
|
||||
}
|
||||
|
||||
function setTitle() {
|
||||
if (!$scope.model.title) {
|
||||
localizationService.localize("grid_addRowConfiguration")
|
||||
.then(function(data){
|
||||
$scope.model.title = data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$scope.currentRow = $scope.model.currentRow;
|
||||
$scope.editors = $scope.model.editors;
|
||||
$scope.columns = $scope.model.columns;
|
||||
@@ -69,6 +83,12 @@ function RowConfigController($scope) {
|
||||
$scope.closeArea = function() {
|
||||
$scope.currentCell = undefined;
|
||||
};
|
||||
|
||||
$scope.close = function() {
|
||||
if($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.nameChanged = false;
|
||||
var originalName = $scope.currentRow.name;
|
||||
@@ -93,6 +113,10 @@ function RowConfigController($scope) {
|
||||
}
|
||||
}, true);
|
||||
|
||||
|
||||
init();
|
||||
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.GridPrevalueEditor.RowConfigController", RowConfigController);
|
||||
|
||||
@@ -1,8 +1,30 @@
|
||||
<div class="usky-grid usky-grid-configuration" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.RowConfigController">
|
||||
|
||||
<div class="umb-form-settings">
|
||||
|
||||
<h5><localize key="grid_addRowConfiguration" /></h5>
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<form novalidate name="RowConfigurationForm" val-form-manager>
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="umb-form-settings form-horizontal">
|
||||
|
||||
<p><localize key="grid_addRowConfigurationDetail" /></p>
|
||||
|
||||
<div class="alert alert-warn ng-scope" ng-show="nameChanged">
|
||||
@@ -14,7 +36,7 @@
|
||||
<umb-control-group label="@general_name">
|
||||
<input type="text" ng-model="currentRow.name" />
|
||||
</umb-control-group>
|
||||
|
||||
|
||||
<umb-control-group label="@general_label">
|
||||
<input type="text" ng-model="currentRow.label" placeholder="Overrides name" />
|
||||
</umb-control-group>
|
||||
@@ -54,7 +76,7 @@
|
||||
</a>
|
||||
</div>
|
||||
</umb-control-group>
|
||||
|
||||
|
||||
<umb-control-group label="@grid_maxItems" description="@grid_maxItemsDescription">
|
||||
<input type="number" ng-model="currentCell.maxItems" class="umb-property-editor-tiny" placeholder="Max" min="0" />
|
||||
</umb-control-group>
|
||||
@@ -97,4 +119,27 @@
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="close()">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</form>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
function DeleteRowConfirmController($scope) {
|
||||
|
||||
$scope.close = function() {
|
||||
if($scope.model.close) {
|
||||
$scope.model.close();
|
||||
}
|
||||
}
|
||||
|
||||
$scope.submit = function() {
|
||||
if($scope.model && $scope.model.submit) {
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.GridPrevalueEditor.DeleteRowConfirmController", DeleteRowConfirmController);
|
||||
+37
-1
@@ -1,4 +1,13 @@
|
||||
<div>
|
||||
<div class="usky-grid usky-grid-configuration" ng-controller="Umbraco.PropertyEditors.GridPrevalueEditor.DeleteRowConfirmController">
|
||||
|
||||
|
||||
<umb-editor-view>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
|
||||
|
||||
|
||||
<h3 class="alert alert-warn ng-scope">Warning!</h3>
|
||||
|
||||
@@ -15,4 +24,31 @@
|
||||
<localize key="general_areyousure">Are you sure?</localize>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
shortcut="esc"
|
||||
action="close()">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="warning"
|
||||
label-key="general_delete"
|
||||
action="submit(model)">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
|
||||
+62
-77
@@ -1,6 +1,6 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.PropertyEditors.GridPrevalueEditorController",
|
||||
function ($scope, gridService) {
|
||||
function ($scope, gridService, editorService) {
|
||||
|
||||
var emptyModel = {
|
||||
styles:[
|
||||
@@ -89,28 +89,23 @@ angular.module("umbraco")
|
||||
};
|
||||
$scope.model.value.templates.push(template);
|
||||
}
|
||||
|
||||
var layoutConfigOverlay = {
|
||||
currentLayout: template,
|
||||
rows: $scope.model.value.layouts,
|
||||
columns: $scope.model.value.columns,
|
||||
view: "views/propertyEditors/grid/dialogs/layoutconfig.html",
|
||||
size: "small",
|
||||
submit: function(model) {
|
||||
editorService.close();
|
||||
},
|
||||
close: function(model) {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.layoutConfigOverlay = {};
|
||||
$scope.layoutConfigOverlay.view = "views/propertyEditors/grid/dialogs/layoutconfig.html";
|
||||
$scope.layoutConfigOverlay.currentLayout = template;
|
||||
$scope.layoutConfigOverlay.rows = $scope.model.value.layouts;
|
||||
$scope.layoutConfigOverlay.columns = $scope.model.value.columns;
|
||||
$scope.layoutConfigOverlay.show = true;
|
||||
editorService.open(layoutConfigOverlay);
|
||||
|
||||
$scope.layoutConfigOverlay.submit = function(model) {
|
||||
$scope.layoutConfigOverlay.show = false;
|
||||
$scope.layoutConfigOverlay = null;
|
||||
};
|
||||
|
||||
$scope.layoutConfigOverlay.close = function(oldModel) {
|
||||
|
||||
//reset templates
|
||||
$scope.model.value.templates = templatesCopy;
|
||||
|
||||
$scope.layoutConfigOverlay.show = false;
|
||||
$scope.layoutConfigOverlay = null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.deleteTemplate = function(index){
|
||||
@@ -135,50 +130,44 @@ angular.module("umbraco")
|
||||
};
|
||||
$scope.model.value.layouts.push(layout);
|
||||
}
|
||||
|
||||
$scope.rowConfigOverlay = {};
|
||||
$scope.rowConfigOverlay.view = "views/propertyEditors/grid/dialogs/rowconfig.html";
|
||||
$scope.rowConfigOverlay.currentRow = layout;
|
||||
$scope.rowConfigOverlay.editors = $scope.editors;
|
||||
$scope.rowConfigOverlay.columns = $scope.model.value.columns;
|
||||
$scope.rowConfigOverlay.show = true;
|
||||
|
||||
$scope.rowConfigOverlay.submit = function(model) {
|
||||
$scope.rowConfigOverlay.show = false;
|
||||
$scope.rowConfigOverlay = null;
|
||||
};
|
||||
|
||||
$scope.rowConfigOverlay.close = function(oldModel) {
|
||||
$scope.model.value.layouts = layoutsCopy;
|
||||
$scope.rowConfigOverlay.show = false;
|
||||
$scope.rowConfigOverlay = null;
|
||||
|
||||
var rowConfigOverlay = {
|
||||
currentRow: layout,
|
||||
editors: $scope.editors,
|
||||
columns: $scope.model.value.columns,
|
||||
view: "views/propertyEditors/grid/dialogs/rowconfig.html",
|
||||
size: "small",
|
||||
submit: function(model) {
|
||||
editorService.close();
|
||||
},
|
||||
close: function(model) {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
|
||||
editorService.open(rowConfigOverlay);
|
||||
|
||||
};
|
||||
|
||||
//var rowDeletesPending = false;
|
||||
$scope.deleteLayout = function(index) {
|
||||
|
||||
var rowDeleteOverlay = {
|
||||
dialogData: {
|
||||
rowName: $scope.model.value.layouts[index].name
|
||||
},
|
||||
view: "views/propertyEditors/grid/dialogs/rowdeleteconfirm.html",
|
||||
size: "small",
|
||||
submit: function(model) {
|
||||
$scope.model.value.layouts.splice(index, 1);
|
||||
editorService.close();
|
||||
},
|
||||
close: function(model) {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.rowDeleteOverlay = {};
|
||||
$scope.rowDeleteOverlay.view = "views/propertyEditors/grid/dialogs/rowdeleteconfirm.html";
|
||||
$scope.rowDeleteOverlay.dialogData = {
|
||||
rowName: $scope.model.value.layouts[index].name
|
||||
};
|
||||
$scope.rowDeleteOverlay.show = true;
|
||||
|
||||
$scope.rowDeleteOverlay.submit = function(model) {
|
||||
|
||||
$scope.model.value.layouts.splice(index, 1);
|
||||
|
||||
$scope.rowDeleteOverlay.show = false;
|
||||
$scope.rowDeleteOverlay = null;
|
||||
};
|
||||
|
||||
$scope.rowDeleteOverlay.close = function(oldModel) {
|
||||
$scope.rowDeleteOverlay.show = false;
|
||||
$scope.rowDeleteOverlay = null;
|
||||
};
|
||||
|
||||
editorService.open(rowDeleteOverlay);
|
||||
};
|
||||
|
||||
|
||||
@@ -210,26 +199,22 @@ angular.module("umbraco")
|
||||
};
|
||||
|
||||
var editConfigCollection = function(configValues, title, callback) {
|
||||
|
||||
var editConfigCollectionOverlay = {
|
||||
config: configValues,
|
||||
title: title,
|
||||
view: "views/propertyeditors/grid/dialogs/editconfig.html",
|
||||
size: "small",
|
||||
submit: function(model) {
|
||||
callback(model.config);
|
||||
editorService.close();
|
||||
},
|
||||
close: function(model) {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.editConfigCollectionOverlay = {};
|
||||
$scope.editConfigCollectionOverlay.view = "views/propertyeditors/grid/dialogs/editconfig.html";
|
||||
$scope.editConfigCollectionOverlay.config = configValues;
|
||||
$scope.editConfigCollectionOverlay.title = title;
|
||||
$scope.editConfigCollectionOverlay.show = true;
|
||||
|
||||
$scope.editConfigCollectionOverlay.submit = function(model) {
|
||||
|
||||
callback(model.config);
|
||||
|
||||
$scope.editConfigCollectionOverlay.show = false;
|
||||
$scope.editConfigCollectionOverlay = null;
|
||||
};
|
||||
|
||||
$scope.editConfigCollectionOverlay.close = function(oldModel) {
|
||||
$scope.editConfigCollectionOverlay.show = false;
|
||||
$scope.editConfigCollectionOverlay = null;
|
||||
};
|
||||
|
||||
editorService.open(editConfigCollectionOverlay);
|
||||
};
|
||||
|
||||
$scope.editConfig = function() {
|
||||
|
||||
@@ -158,28 +158,4 @@
|
||||
</umb-control-group>
|
||||
</div>
|
||||
|
||||
<umb-overlay ng-if="layoutConfigOverlay.show"
|
||||
model="layoutConfigOverlay"
|
||||
view="layoutConfigOverlay.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
<umb-overlay ng-if="rowConfigOverlay.show"
|
||||
model="rowConfigOverlay"
|
||||
view="rowConfigOverlay.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
<umb-overlay ng-if="editConfigCollectionOverlay.show"
|
||||
model="editConfigCollectionOverlay"
|
||||
view="editConfigCollectionOverlay.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
<umb-overlay ng-if="rowDeleteOverlay.show"
|
||||
model="rowDeleteOverlay"
|
||||
view="rowDeleteOverlay.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -142,7 +142,6 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs
|
||||
}
|
||||
|
||||
$scope.options = {
|
||||
displayAtTabNumber: $scope.model.config.displayAtTabNumber ? $scope.model.config.displayAtTabNumber : 1,
|
||||
pageSize: $scope.model.config.pageSize ? $scope.model.config.pageSize : 10,
|
||||
pageNumber: ($routeParams.page && Number($routeParams.page) != NaN && Number($routeParams.page) > 0) ? $routeParams.page : 1,
|
||||
filter: '',
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<div class="row-fluid" ng-switch-when="false">
|
||||
|
||||
<umb-editor-sub-header>
|
||||
<umb-editor-sub-header ng-class="{'--state-selection':(selection.length > 0)}">
|
||||
|
||||
<umb-editor-sub-header-content-left>
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
type="button"
|
||||
label="Clear selection"
|
||||
label-key="buttons_clearSelection"
|
||||
button-style="selection"
|
||||
button-style="white"
|
||||
action="clearSelection()"
|
||||
disabled="actionInProgress">
|
||||
</umb-button>
|
||||
@@ -140,7 +140,7 @@
|
||||
ng-if="options.allowBulkPublish && (buttonPermissions == null || buttonPermissions.canPublish)"
|
||||
style="margin-right: 5px;"
|
||||
type="button"
|
||||
button-style="selection"
|
||||
button-style="white"
|
||||
label-key="actions_publish"
|
||||
icon="icon-globe"
|
||||
action="publish()"
|
||||
@@ -153,7 +153,7 @@
|
||||
ng-if="options.allowBulkUnpublish && (buttonPermissions == null || buttonPermissions.canUnpublish)"
|
||||
style="margin-right: 5px;"
|
||||
type="button"
|
||||
button-style="selection"
|
||||
button-style="white"
|
||||
label-key="actions_unpublish"
|
||||
icon="icon-block"
|
||||
action="unpublish()"
|
||||
@@ -166,7 +166,7 @@
|
||||
ng-if="options.allowBulkCopy && (buttonPermissions == null || buttonPermissions.canCopy)"
|
||||
style="margin-right: 5px;"
|
||||
type="button"
|
||||
button-style="selection"
|
||||
button-style="white"
|
||||
label-key="actions_copy"
|
||||
icon="icon-documents"
|
||||
action="copy()"
|
||||
@@ -179,7 +179,7 @@
|
||||
ng-if="options.allowBulkMove && (buttonPermissions == null || buttonPermissions.canMove)"
|
||||
style="margin-right: 5px;"
|
||||
type="button"
|
||||
button-style="selection"
|
||||
button-style="white"
|
||||
label-key="actions_move"
|
||||
icon="icon-enter"
|
||||
action="move()"
|
||||
@@ -191,7 +191,7 @@
|
||||
<umb-button
|
||||
ng-if="options.allowBulkDelete && (buttonPermissions == null || buttonPermissions.canDelete)"
|
||||
type="button"
|
||||
button-style="selection"
|
||||
button-style="white"
|
||||
label-key="actions_delete"
|
||||
icon="icon-trash"
|
||||
action="delete()"
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<li ng-repeat="item in configItems track by item.id">
|
||||
<label class="radio">
|
||||
<input type="radio" name="{{htmlId}}"
|
||||
value="{{item.id}}"
|
||||
value="{{item.value}}"
|
||||
ng-model="model.value" />
|
||||
{{item.value}}
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
hide-alias="true"
|
||||
navigation="vm.user.navigation">
|
||||
</umb-editor-header>
|
||||
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
|
||||
<div ng-if="!vm.loading" class="umb-user-details-view-wrapper" style="padding: 0;">
|
||||
|
||||
<umb-editor-sub-views
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
<umb-button type="button"
|
||||
action="vm.goToPage(vm.breadcrumbs[0])"
|
||||
button-style="link"
|
||||
label="Return to list"
|
||||
label-key="buttons_returnToList"
|
||||
disabled="vm.loading">
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
|
||||
|
||||
<umb-editor-sub-header>
|
||||
|
||||
<umb-editor-sub-header ng-class="{'--state-selection':(vm.selection.length > 0)}">
|
||||
|
||||
<!-- No selection -->
|
||||
<umb-editor-sub-header-content-left ng-if="vm.selection.length === 0">
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="success"
|
||||
button-style="action"
|
||||
action="vm.createUserGroup()"
|
||||
label="Create Group"
|
||||
label-key="actions_createGroup">
|
||||
@@ -40,6 +40,7 @@
|
||||
<umb-button
|
||||
type="button"
|
||||
label-key="buttons_clearSelection"
|
||||
button-style="white"
|
||||
action="vm.clearSelection()"
|
||||
size="xs">
|
||||
</umb-button>
|
||||
@@ -54,6 +55,7 @@
|
||||
type="button"
|
||||
label="Delete"
|
||||
label-key="general_delete"
|
||||
button-style="white"
|
||||
icon="icon-trash"
|
||||
action="vm.deleteUserGroups()"
|
||||
size="xs">
|
||||
@@ -64,7 +66,7 @@
|
||||
|
||||
<div style="margin-bottom: 20px;" class="flex items-center">
|
||||
<div style="font-size: 16px;">
|
||||
<span class="bold"><localize key="general_groups">Groups</localize> </span> <span>({{vm.userGroups.length}})</span>
|
||||
<span class="bold"><localize key="general_groups">Groups</localize> </span> <span>({{vm.userGroups.length}})</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -76,19 +78,20 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="group in vm.userGroups | filter:vm.filter"
|
||||
ng-click="vm.goToUserGroup(group)"
|
||||
ng-class="{'cursor-pointer': group.hasAccess, 'cursor-not-allowed': !group.hasAccess}">
|
||||
|
||||
<td style="width: 20px; padding-right: 5px">
|
||||
<tr ng-repeat="group in vm.userGroups | filter:vm.filter"
|
||||
ng-click="vm.goToUserGroup(group)"
|
||||
ng-class="{'cursor-pointer': group.hasAccess, 'cursor-not-allowed': !group.hasAccess, '--selected': group.selected}">
|
||||
|
||||
<td style="padding-right: 5px">
|
||||
<input
|
||||
ng-show="group.hasAccess && group.group.alias !== 'admin' && group.group.alias !== 'translator'"
|
||||
type="checkbox"
|
||||
type="checkbox"
|
||||
ng-model="group.selected"
|
||||
ng-click="vm.selectUserGroup(group, vm.selection, $event)" />
|
||||
ng-click="vm.selectUserGroup(group, vm.selection, $event)"
|
||||
style="width: 20px; height: 100px;"/>
|
||||
</td>
|
||||
<td>
|
||||
<umb-user-group-preview
|
||||
<umb-user-group-preview
|
||||
style="border-bottom: none; margin-bottom: 0; padding: 0;"
|
||||
icon="group.group.icon"
|
||||
name="group.group.name"
|
||||
@@ -101,4 +104,4 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -196,27 +196,23 @@
|
||||
vm.activeLayout = selectedLayout;
|
||||
}
|
||||
|
||||
function selectUser(user, selection, event) {
|
||||
|
||||
// prevent the current user to be selected
|
||||
if (!user.isCurrentUser) {
|
||||
|
||||
if (user.selected) {
|
||||
var index = selection.indexOf(user.id);
|
||||
selection.splice(index, 1);
|
||||
user.selected = false;
|
||||
} else {
|
||||
user.selected = true;
|
||||
vm.selection.push(user.id);
|
||||
}
|
||||
|
||||
setBulkActions(vm.users);
|
||||
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
function selectUser(user) {
|
||||
|
||||
if (user.isCurrentUser) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.selected) {
|
||||
var index = vm.selection.indexOf(user.id);
|
||||
vm.selection.splice(index, 1);
|
||||
user.selected = false;
|
||||
} else {
|
||||
user.selected = true;
|
||||
vm.selection.push(user.id);
|
||||
}
|
||||
|
||||
setBulkActions(vm.users);
|
||||
|
||||
}
|
||||
|
||||
function clearSelection() {
|
||||
@@ -227,11 +223,7 @@
|
||||
}
|
||||
|
||||
function clickUser(user) {
|
||||
if (vm.selection.length > 0) {
|
||||
selectUser(user, vm.selection);
|
||||
} else {
|
||||
goToUser(user.id);
|
||||
}
|
||||
goToUser(user.id);
|
||||
}
|
||||
|
||||
function disableUsers() {
|
||||
@@ -625,18 +617,20 @@
|
||||
var firstSelectedUserGroups;
|
||||
|
||||
angular.forEach(users, function (user) {
|
||||
|
||||
|
||||
if (!user.selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if the current user is selected prevent any bulk actions with the user included
|
||||
if (user.isCurrentUser) {
|
||||
vm.allowDisableUser = false;
|
||||
vm.allowEnableUser = false;
|
||||
vm.allowUnlockUser = false;
|
||||
vm.allowSetUserGroup = false;
|
||||
return;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user.userDisplayState && user.userDisplayState.key === "Disabled") {
|
||||
@@ -660,16 +654,17 @@
|
||||
}
|
||||
|
||||
// store the user group aliases of the first selected user
|
||||
if (!firstSelectedUserGroups) {
|
||||
firstSelectedUserGroups = user.userGroups.map(function (ug) { return ug.alias; });
|
||||
vm.allowSetUserGroup = true;
|
||||
} else if (vm.allowSetUserGroup === true) {
|
||||
// for 2nd+ selected user, compare the user group aliases to determine if we should allow bulk editing.
|
||||
// we don't allow bulk editing of users not currently having the same assigned user groups, as we can't
|
||||
// really support that in the user group picker.
|
||||
var userGroups = user.userGroups.map(function (ug) { return ug.alias; });
|
||||
if (_.difference(firstSelectedUserGroups, userGroups).length > 0) {
|
||||
vm.allowSetUserGroup = false;
|
||||
if (vm.allowSetUserGroup === true) {
|
||||
if (!firstSelectedUserGroups) {
|
||||
firstSelectedUserGroups = user.userGroups.map(function (ug) { return ug.alias; });
|
||||
} else {
|
||||
// for 2nd+ selected user, compare the user group aliases to determine if we should allow bulk editing.
|
||||
// we don't allow bulk editing of users not currently having the same assigned user groups, as we can't
|
||||
// really support that in the user group picker.
|
||||
var userGroups = user.userGroups.map(function (ug) { return ug.alias; });
|
||||
if (_.difference(firstSelectedUserGroups, userGroups).length > 0) {
|
||||
vm.allowSetUserGroup = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<umb-load-indicator ng-show="vm.loading"></umb-load-indicator>
|
||||
|
||||
<umb-editor-sub-header>
|
||||
<umb-editor-sub-header ng-class="{'--state-selection':(vm.selection.length > 0)}">
|
||||
|
||||
<!-- No selection -->
|
||||
<umb-editor-sub-header-content-left ng-if="vm.selection.length === 0">
|
||||
@@ -48,7 +48,7 @@
|
||||
<umb-button
|
||||
type="button"
|
||||
size="xs"
|
||||
button-style="outline"
|
||||
button-style="white"
|
||||
label-key="buttons_clearSelection"
|
||||
action="vm.clearSelection()"
|
||||
disabled="actionInProgress">
|
||||
@@ -57,16 +57,16 @@
|
||||
<umb-editor-sub-header-section>
|
||||
<strong>{{ vm.selection.length }} <localize key="general_of">of</localize> {{ vm.users.length }} <localize key="general_selected">selected</localize></strong>
|
||||
</umb-editor-sub-header-section>
|
||||
|
||||
|
||||
</umb-editor-sub-header-content-left>
|
||||
|
||||
<umb-editor-sub-header-content-right ng-if="vm.selection.length > 0">
|
||||
<umb-button
|
||||
style="margin-right: 5px;"
|
||||
ng-if="vm.allowSetUserGroup"
|
||||
type="button"
|
||||
disabled="!vm.allowSetUserGroup"
|
||||
type="button"
|
||||
size="xs"
|
||||
button-style="outline"
|
||||
button-style="white"
|
||||
label-key="actions_setGroup"
|
||||
icon="icon-users"
|
||||
action="vm.openBulkUserGroupPicker()">
|
||||
@@ -74,22 +74,22 @@
|
||||
|
||||
<umb-button
|
||||
style="margin-right: 5px;"
|
||||
ng-if="vm.allowEnableUser"
|
||||
disabled="!vm.allowEnableUser"
|
||||
type="button"
|
||||
size="xs"
|
||||
button-style="outline"
|
||||
button-style="white"
|
||||
state="vm.enableUserButtonState"
|
||||
label-key="actions_enable"
|
||||
icon="icon-check"
|
||||
action="vm.enableUsers()">
|
||||
</umb-button>
|
||||
|
||||
|
||||
<umb-button
|
||||
style="margin-right: 5px;"
|
||||
ng-if="vm.allowUnlockUser"
|
||||
disabled="!vm.allowUnlockUser"
|
||||
type="button"
|
||||
size="xs"
|
||||
button-style="outline"
|
||||
button-style="white"
|
||||
state="vm.unlockUserButtonState"
|
||||
label-key="actions_unlock"
|
||||
icon="icon-unlocked"
|
||||
@@ -97,10 +97,10 @@
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
ng-if="vm.allowDisableUser"
|
||||
disabled="!vm.allowDisableUser"
|
||||
type="button"
|
||||
size="xs"
|
||||
button-style="outline"
|
||||
button-style="white"
|
||||
state="vm.disableUserButtonState"
|
||||
label-key="actions_disable"
|
||||
icon="icon-block"
|
||||
@@ -123,7 +123,7 @@
|
||||
<!-- State filter -->
|
||||
<div style="position: relative;" ng-if="vm.userStatesFilter.length > 0">
|
||||
<a class="btn btn-link dropdown-toggle flex" href="" ng-click="vm.toggleFilter('state')">
|
||||
<span><localize key="general_status">Status</localize>:</span>
|
||||
<span><localize key="general_status">Status</localize>:</span>
|
||||
<span class="bold truncate dib" style="margin-left: 5px; margin-right: 3px; max-width: 150px;">{{ vm.getFilterName(vm.userStatesFilter) }}</span>
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
@@ -167,7 +167,7 @@
|
||||
<!-- Order By -->
|
||||
<div style="position: relative;">
|
||||
<a class="btn btn-link dropdown-toggle flex" href="" ng-click="vm.toggleFilter('orderBy')">
|
||||
<span><localize key="general_orderBy">Order by</localize>:</span>
|
||||
<span><localize key="general_orderBy">Order by</localize>:</span>
|
||||
<span class="bold" style="margin-left: 2px;">{{ vm.getSortLabel(vm.usersOptions.orderBy, vm.usersOptions.orderDirection) }} </span>
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
@@ -191,20 +191,18 @@
|
||||
|
||||
<!-- Layout: Cards -->
|
||||
<div class="umb-user-cards" ng-if="vm.activeLayout.path === '1' && vm.loading === false">
|
||||
<a href="" class="umb-user-card" ng-repeat="user in vm.users track by user.key" ng-click="vm.clickUser(user)">
|
||||
<div class="umb-user-card__content" ng-class="{'umb-user-card__content--selected': user.selected}">
|
||||
<umb-badge class="umb-user-card__badge" size="xs" ng-if="user.userDisplayState.key !== 'Active'" color="{{user.userDisplayState.color}}">
|
||||
{{ user.userDisplayState.name }}
|
||||
</umb-badge>
|
||||
<div class="umb-user-card__avatar">
|
||||
<umb-avatar size="l" color="secondary" name="{{user.name}}" img-src="{{user.avatars[2]}}" img-srcset="{{user.avatars[3]}} 2x, {{user.avatars[4]}} 3x">
|
||||
</umb-avatar>
|
||||
<div class="umb-user-card" ng-class="{'-selected': user.selected}" ng-repeat="user in vm.users track by user.key" ng-click="vm.selectUser(user)">
|
||||
<div class="umb-user-card__content">
|
||||
<div class="umb-user-card__goToUser" ng-click="vm.clickUser(user)">
|
||||
<umb-badge class="umb-user-card__badge" size="xs" ng-if="user.userDisplayState.key !== 'Active'" color="{{user.userDisplayState.color}}">
|
||||
{{ user.userDisplayState.name }}
|
||||
</umb-badge>
|
||||
<div class="umb-user-card__avatar">
|
||||
<umb-avatar size="l" color="secondary" name="{{user.name}}" img-src="{{user.avatars[2]}}" img-srcset="{{user.avatars[3]}} 2x, {{user.avatars[4]}} 3x">
|
||||
</umb-avatar>
|
||||
</div>
|
||||
<div class="umb-user-card__name">{{user.name}}</div>
|
||||
</div>
|
||||
<div class="umb-user-card__checkmark" ng-class="{'umb-user-card__checkmark--visible': user.selected || vm.selection.length > 0 }"
|
||||
ng-click="vm.selectUser(user, vm.selection, $event)">
|
||||
<umb-checkmark ng-if="!user.isCurrentUser" checked="user.selected" size="s"></umb-checkmark>
|
||||
</div>
|
||||
<div class="umb-user-card__name" href="">{{user.name}}</div>
|
||||
<div class="umb-user-card__group">
|
||||
<span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span>
|
||||
</div>
|
||||
@@ -222,7 +220,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Layout: Table -->
|
||||
@@ -244,9 +242,14 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="user in vm.users track by user.key" ng-click="vm.clickUser(user)" style="cursor: pointer;" ng-mouseenter="user.hover = true" ng-mouseleave="user.hover = false">
|
||||
<tr ng-repeat="user in vm.users track by user.key"
|
||||
ng-click="vm.selectUser(user, vm.selection, $event)"
|
||||
ng-class="{'--selected': user.selected}"
|
||||
style="cursor: pointer;"
|
||||
ng-mouseenter="user.hover = true"
|
||||
ng-mouseleave="user.hover = false">
|
||||
<td style="padding-left: 10px;">
|
||||
<div ng-if="!user.isCurrentUser" ng-click="vm.selectUser(user, vm.selection, $event)">
|
||||
<div ng-if="!user.isCurrentUser">
|
||||
<umb-checkmark
|
||||
ng-if="vm.selection.length > 0 || user.hover"
|
||||
checked="user.selected"
|
||||
@@ -254,7 +257,7 @@
|
||||
</umb-checkmark>
|
||||
</div>
|
||||
</td>
|
||||
<td scope="row">
|
||||
<td scope="row" ng-click="vm.clickUser(user)">
|
||||
<umb-avatar
|
||||
size="xs"
|
||||
color="secondary"
|
||||
@@ -263,7 +266,7 @@
|
||||
img-srcset="{{user.avatars[1]}} 2x, {{user.avatars[2]}} 3x">
|
||||
</umb-avatar>
|
||||
</td>
|
||||
<td class="bold">{{user.name}}</td>
|
||||
<td class="bold" ng-click="vm.clickUser(user)">{{user.name}}</td>
|
||||
<td><span ng-repeat="userGroup in user.userGroups">{{ userGroup.name }}<span ng-if="!$last">, </span></span></td>
|
||||
<td>{{ user.formattedLastLogin }}</td>
|
||||
<td style="text-transform: capitalize;">
|
||||
@@ -331,7 +334,7 @@
|
||||
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" ng-message="valServerField">{{addUserForm.name.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_username" label-for="username" required="true" ng-if="!vm.usernameIsEmail">
|
||||
@@ -341,7 +344,7 @@
|
||||
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" ng-message="valServerField">{{addUserForm.username.errorMsg}}</span>
|
||||
</span>
|
||||
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_email" label-for="email" required="true">
|
||||
@@ -355,7 +358,7 @@
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@user_usergroup" description="@user_groupsHelp" required="true">
|
||||
|
||||
|
||||
<umb-user-group-preview
|
||||
ng-repeat="group in vm.newUser.userGroups"
|
||||
icon="group.icon"
|
||||
@@ -417,18 +420,18 @@
|
||||
|
||||
<!-- Create user success -->
|
||||
<div ng-if="vm.usersViewState === 'createUserSuccess'">
|
||||
|
||||
|
||||
<umb-editor-sub-header>
|
||||
<umb-editor-sub-header-content-left>
|
||||
<a class="umb-package-details__back-link" href="" ng-click="vm.setUsersViewState('overview');">← <localize key="user_backToUsers">Back to users</localize></a>
|
||||
</umb-editor-sub-header-content-left>
|
||||
</umb-editor-sub-header>
|
||||
|
||||
|
||||
<div class="flex justify-center">
|
||||
|
||||
<umb-box style="max-width: 500px;">
|
||||
<umb-box-content>
|
||||
|
||||
|
||||
<!-- Success text -->
|
||||
<div class="flex items-center" style="margin-bottom: 15px;">
|
||||
<umb-checkmark
|
||||
@@ -442,7 +445,7 @@
|
||||
</div>
|
||||
|
||||
<p style="line-height: 1.6em; margin-bottom: 20px;"><localize key="user_userCreatedSuccessHelp"></localize></p>
|
||||
|
||||
|
||||
<!-- New password -->
|
||||
<div>
|
||||
<label class="bold"><localize key="user_password">Password</localize></label>
|
||||
@@ -510,7 +513,7 @@
|
||||
|
||||
<umb-box style="max-width: 500px;">
|
||||
<umb-box-content>
|
||||
|
||||
|
||||
<!-- Success text -->
|
||||
<div class="flex items-center" style="margin-bottom: 15px;">
|
||||
<umb-checkmark
|
||||
|
||||
@@ -8,11 +8,6 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A property editor to allow multiple checkbox selection of pre-defined items.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Due to remaining backwards compatible, this stores the id of the checkbox items in the database
|
||||
/// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the string value is published
|
||||
/// in cache and not the int ID.
|
||||
/// </remarks>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.CheckBoxList, "Checkbox list", "checkboxlist", Icon="icon-bulleted-list", Group="lists")]
|
||||
public class CheckBoxListPropertyEditor : DataEditor
|
||||
{
|
||||
@@ -31,6 +26,6 @@ namespace Umbraco.Web.PropertyEditors
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(Logger, Attribute);
|
||||
protected override IDataValueEditor CreateValueEditor() => new MultipleValueEditor(Logger, Attribute);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
protected override IDataValueEditor CreateValueEditor()
|
||||
{
|
||||
return new PublishValuesMultipleValueEditor(Logger, Attribute);
|
||||
return new MultipleValueEditor(Logger, Attribute);
|
||||
}
|
||||
|
||||
protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownFlexibleConfigurationEditor(_textService);
|
||||
|
||||
@@ -13,7 +13,6 @@ namespace Umbraco.Web.PropertyEditors
|
||||
// initialize defaults
|
||||
|
||||
PageSize = 10;
|
||||
DisplayAtTabNumber = 1;
|
||||
OrderBy = "SortOrder";
|
||||
OrderDirection = "asc";
|
||||
|
||||
@@ -43,9 +42,6 @@ namespace Umbraco.Web.PropertyEditors
|
||||
[ConfigurationField("pageSize", "Page Size", "number", Description = "Number of items per page")]
|
||||
public int PageSize { get; set; }
|
||||
|
||||
[ConfigurationField("displayAtTabNumber", "Display At Tab Number", "number", Description = "Which tab position that the list of child items will be displayed")]
|
||||
public int DisplayAtTabNumber { get; set; }
|
||||
|
||||
[ConfigurationField("orderBy", "Order By", "views/propertyeditors/listview/sortby.prevalues.html",
|
||||
Description = "The default sort order for the list")]
|
||||
public string OrderBy { get; set; }
|
||||
@@ -64,7 +60,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
Description = "The bulk actions that are allowed from the list view")]
|
||||
public BulkActionPermissionSettings BulkActionPermissions { get; set; } = new BulkActionPermissionSettings(); // TODO: managing defaults?
|
||||
|
||||
[ConfigurationField("tabName", "Tab Name", "textstring", Description = "The name of the listview tab (default if empty: 'Child Items')")]
|
||||
[ConfigurationField("tabName", "Content app name", "textstring", Description = "The name of the listview content app (default if empty: 'Child Items')")]
|
||||
public string TabName { get; set; }
|
||||
|
||||
public class Property
|
||||
|
||||
+10
-11
@@ -1,33 +1,32 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom value editor to handle posted json data and to return json data for the multiple selected items
|
||||
/// A value editor to handle posted json array data and to return array data for the multiple selected csv items
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is re-used by editors such as the multiple drop down list or check box list
|
||||
/// </remarks>
|
||||
internal class PublishValuesMultipleValueEditor : DataValueEditor
|
||||
internal class MultipleValueEditor : DataValueEditor
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
internal PublishValuesMultipleValueEditor(ILogger logger, DataEditorAttribute attribute)
|
||||
internal MultipleValueEditor(ILogger logger, DataEditorAttribute attribute)
|
||||
: base(attribute)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override so that we can return a json array to the editor for multi-select values
|
||||
/// Override so that we can return an array to the editor for multi-select values
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="dataTypeService"></param>
|
||||
@@ -36,8 +35,8 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <returns></returns>
|
||||
public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null)
|
||||
{
|
||||
var delimited = base.ToEditor(property, dataTypeService, culture, segment).ToString();
|
||||
return delimited.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var json = base.ToEditor(property, dataTypeService, culture, segment).ToString();
|
||||
return JsonConvert.DeserializeObject<string[]>(json) ?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -55,9 +54,9 @@ namespace Umbraco.Web.PropertyEditors
|
||||
return null;
|
||||
}
|
||||
|
||||
var values = json.Select(item => item.Value<string>()).ToList();
|
||||
//change to delimited
|
||||
return string.Join(",", values);
|
||||
var values = json.Select(item => item.Value<string>()).ToArray();
|
||||
|
||||
return JsonConvert.SerializeObject(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <summary>
|
||||
/// A property editor to allow the individual selection of pre-defined items.
|
||||
/// </summary>
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.RadioButtonList, "Radio button list", "radiobuttons", ValueType = ValueTypes.Integer, Group="lists", Icon="icon-target")]
|
||||
[DataEditor(Constants.PropertyEditors.Aliases.RadioButtonList, "Radio button list", "radiobuttons", ValueType = ValueTypes.String, Group="lists", Icon="icon-target")]
|
||||
public class RadioButtonsPropertyEditor : DataEditor
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
+5
-2
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -17,8 +18,10 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
|
||||
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
|
||||
{
|
||||
return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToArray()
|
||||
?? Enumerable.Empty<string>();
|
||||
if(source == null) return Array.Empty<string>();
|
||||
|
||||
|
||||
return JsonConvert.DeserializeObject<string[]>(source.ToString()) ?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
|
||||
|
||||
@@ -861,7 +861,7 @@
|
||||
<Compile Include="PropertyEditors\DateTimeValidator.cs" />
|
||||
<Compile Include="PropertyEditors\IntegerPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\MultipleTextStringPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\PublishValuesMultipleValueEditor.cs" />
|
||||
<Compile Include="PropertyEditors\MultipleValueEditor.cs" />
|
||||
<Compile Include="PropertyEditors\RadioButtonsPropertyEditor.cs" />
|
||||
<Compile Include="PropertyEditors\RichTextPreValueController.cs" />
|
||||
<Compile Include="PropertyEditors\RichTextConfigurationEditor.cs" />
|
||||
|
||||
Reference in New Issue
Block a user