Skip to content

Commit 5044238

Browse files
committed
Rewrite property editor and add Udi support
1 parent a033f14 commit 5044238

File tree

11 files changed

+581
-238
lines changed

11 files changed

+581
-238
lines changed

CHANGELOG

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2.0.0
2+
=====
3+
4+
* Updated styling to match Umbraco v7.6
5+
* Added Udi support
6+
17
1.3.2
28
=====
39

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
1-
<div ng-controller="RJP.MultiUrlPickerController" class="umb-editor umb-contentpicker">
1+
<div ng-controller="RJP.MultiUrlPickerController as ctrl" class="umb-editor umb-contentpicker">
22
<ng-form name="multiUrlPickerForm">
3-
<div ui-sortable="sortableOptions" ng-model="renderModel">
4-
<umb-node-preview ng-repeat="node in renderModel"
5-
icon="node.icon"
6-
name="node.name"
7-
published="node.published"
8-
description="node.url"
9-
sortable="true"
10-
allow-remove="true"
11-
allow-open="true"
12-
on-remove="remove($index)"
13-
on-open="edit($index)">
14-
</umb-node-preview>
3+
<div ui-sortable="ctrl.sortableOptions" ng-model="ctrl.renderModel">
4+
<div ng-repeat="link in ctrl.renderModel">
5+
<umb-node-preview icon="link.icon"
6+
name="link.name"
7+
published="link.published"
8+
description="link.url"
9+
sortable="!ctrl.sortableOptions.disabled"
10+
allow-remove="true"
11+
allow-open="true"
12+
on-remove="ctrl.remove($index)"
13+
on-open="ctrl.openLinkPicker(link, $index)">
14+
</umb-node-preview>
15+
</div>
1516
</div>
1617

17-
<a ng-show="!cfg.maxNumberOfItems || renderModel.length < cfg.maxNumberOfItems"
18+
<a ng-show="!model.config.maxNumberOfItems || ctrl.renderModel.length < model.config.maxNumberOfItems"
1819
class="umb-node-preview-add"
19-
href=""
20-
ng-click="openLinkPicker()"
20+
href
21+
ng-click="ctrl.openLinkPicker()"
2122
prevent-default>
2223
<localize key="general_add">Add</localize>
2324
</a>
2425

25-
<input type="hidden" name="minCount" ng-model="renderModel" />
26-
<input type="hidden" name="maxCount" ng-model="renderModel" />
26+
<input type="hidden" name="minCount" ng-model="ctrl.renderModel" />
27+
<input type="hidden" name="maxCount" ng-model="ctrl.renderModel" />
2728

2829
<div class="help-inline" val-msg-for="minCount" val-toggle-msg="minCount">
29-
You need to add at least {{cfg.minNumberOfItems}} items
30+
You need to add at least {{model.config.minNumberOfItems}} items
3031
</div>
3132

3233
<div class="help-inline" val-msg-for="maxCount" val-toggle-msg="maxCount">
3334
You can only have {{model.config.maxNumberOfItems}} items selected
3435
</div>
3536
</ng-form>
36-
</div>
37+
38+
<umb-overlay ng-if="ctrl.linkPickerOverlay.show"
39+
model="ctrl.linkPickerOverlay"
40+
view="ctrl.linkPickerOverlay.view"
41+
position="right">
42+
</umb-overlay>
43+
</div>
Lines changed: 95 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,110 @@
1-
(function (angular, _) {
2-
'use strict';
1+
(function () {
2+
'use strict'
33

4-
angular.module("umbraco").controller("RJP.MultiUrlPickerController", function ($scope, $q, dialogService, iconHelper, entityResource) {
5-
var documentIds = [];
6-
var mediaIds = [];
4+
var MultiUrlPickerController = function ($scope, angularHelper, entityResource, iconHelper) {
75

8-
$scope.renderModel = [];
9-
$scope.cfg = { maxNumberOfItems: 0, minNumberOfItems: 0 };
10-
$scope.sortableOptions = {
11-
distance: 10,
12-
tolerance: "pointer",
13-
scroll: true,
14-
zIndex: 6000
15-
};
16-
$scope.editedMediaId = -1;
17-
18-
if ($scope.model.value) {
19-
_.each($scope.model.value, function (item, i) {
20-
if (item.id) {
21-
(item.isMedia ? mediaIds : documentIds).push(item.id);
22-
}
23-
});
24-
}
6+
this.renderModel = []
257

26-
var entityLoaded = function (node) {
27-
var item = _.find($scope.renderModel, function (item) {
28-
return +item.id === node.id;
29-
});
30-
item.icon = iconHelper.convertFromLegacyIcon(node.icon);
31-
item.published = node.metaData.NodeObjectType !== 'c66ba18e-eaf3-4cff-8a22-41b16d66a972' || node.metaData.IsPublished;
32-
};
33-
34-
$q.all([
35-
entityResource.getByIds(documentIds, 'Document'),
36-
entityResource.getByIds(mediaIds, 'Media')
37-
]).then(function (result) {
38-
var entities = result[0].concat(result[1]);
39-
40-
_.each($scope.model.value, function (item) {
41-
if (item.id) {
42-
var entity = _.find(entities, function (e) {
43-
return e.id == item.id;
44-
});
45-
46-
if (entity) {
47-
item.icon = iconHelper.convertFromLegacyIcon(entity.icon);
48-
$scope.renderModel.push(new Link(item, entity.metaData.NodeObjectType !== 'c66ba18e-eaf3-4cff-8a22-41b16d66a972' || entity.metaData.IsPublished));
49-
}
50-
} else {
51-
$scope.renderModel.push(new Link(item, true));
52-
}
53-
});
54-
55-
$scope.$watch(
56-
function () {
57-
return $scope.renderModel.length;
58-
},
59-
function (newVal) {
60-
if ($scope.renderModel.length) {
61-
$scope.model.value = $scope.renderModel;
62-
} else {
63-
$scope.model.value = null;
64-
}
65-
66-
if ($scope.cfg.minNumberOfItems && +$scope.cfg.minNumberOfItems > $scope.renderModel.length) {
67-
$scope.multiUrlPickerForm.minCount.$setValidity('minCount', false);
68-
} else {
69-
$scope.multiUrlPickerForm.minCount.$setValidity('minCount', true);
70-
}
71-
if ($scope.cfg.maxNumberOfItems && +$scope.cfg.maxNumberOfItems < $scope.renderModel.length) {
72-
$scope.multiUrlPickerForm.maxCount.$setValidity('maxCount', false);
73-
} else {
74-
$scope.multiUrlPickerForm.maxCount.$setValidity('maxCount', true);
75-
}
76-
}
77-
);
78-
});
79-
80-
if ($scope.model.config) {
81-
$scope.cfg = angular.extend($scope.cfg, $scope.model.config);
8+
if ($scope.preview) {
9+
return
8210
}
8311

84-
if ($scope.cfg.maxNumberOfItems <= 0) {
85-
delete $scope.cfg.maxNumberOfItems;
86-
}
87-
if ($scope.cfg.minNumberOfItems <= 0) {
88-
$scope.cfg.minNumberOfItems = 0;
89-
}
12+
$scope.model.value.forEach(function (link) {
13+
link.icon = iconHelper.convertFromLegacyIcon(link.icon)
14+
this.renderModel.push(link)
15+
}.bind(this))
9016

91-
$scope.openLinkPicker = function () {
92-
dialogService.linkPicker({ callback: $scope.onContentSelected });
93-
};
17+
$scope.$on('formSubmitting', function () {
18+
$scope.model.value = this.renderModel
19+
}.bind(this))
9420

95-
$scope.edit = function (index) {
96-
var link = $scope.renderModel[index];
21+
$scope.$watch(function () {
22+
return this.renderModel.length
23+
}.bind(this), function () {
24+
$scope.multiUrlPickerForm.minCount.$setValidity('minCount', $scope.model.config && $scope.model.config.minNumberOfItems && +$scope.model.config.minNumberOfItems <= this.renderModel.length)
25+
$scope.multiUrlPickerForm.maxCount.$setValidity("maxCount", $scope.model.config && $scope.model.config.maxNumberOfItems && +$scope.model.config.maxNumberOfItems >= this.renderModel.length)
9726

98-
// store the current edited media id
99-
if (link.isMedia && link.id !== null) {
100-
$scope.editedMediaId = link.id;
101-
}
27+
this.sortableOptions.disabled = this.renderModel.length === 1
28+
}.bind(this))
10229

103-
dialogService.linkPicker({
104-
currentTarget: {
105-
id: link.isMedia ? null : link.id, // the linkPicker breaks if it get an id for media
106-
index: index,
107-
name: link.name,
108-
url: link.url,
109-
target: link.target,
110-
isMedia: link.isMedia,
111-
},
112-
callback: $scope.onContentSelected
113-
});
114-
};
115-
116-
$scope.remove = function (index) {
117-
$scope.renderModel.splice(index, 1);
118-
$scope.model.value = $scope.renderModel;
119-
};
120-
121-
$scope.$on("formSubmitting", function (ev, args) {
122-
if ($scope.renderModel.length) {
123-
$scope.model.value = $scope.renderModel;
124-
} else {
125-
$scope.model.value = null;
126-
}
127-
});
30+
this.sortableOptions = {
31+
distance: 10,
32+
tolerance: 'pointer',
33+
scroll: true,
34+
zIndex: 6000
35+
}
12836

37+
this.remove = function ($index) {
38+
this.renderModel.splice($index, 1)
12939

130-
$scope.onContentSelected = function (e) {
131-
var link = new Link(e, true);
40+
angularHelper.getCurrentForm($scope).$setDirty();
41+
}
13242

133-
if (e.index !== undefined && e.index !== null) {
134-
if (link.isMedia && link.id === null) {
135-
// we can assume the existing media item is changed and no new file has been selected
136-
// so we can restorte the existing id
137-
link.id = $scope.editedMediaId;
138-
}
139-
$scope.renderModel[e.index] = link;
140-
} else {
141-
$scope.renderModel.push(link);
142-
}
43+
this.openLinkPicker = function (link, $index) {
44+
var target = link ? {
45+
name: link.name,
46+
// the linkPicker breaks if it get an id or udi for media
47+
id: link.isMedia ? null : link.id,
48+
udi: link.isMedia ? null : link.udi,
49+
url: link.url,
50+
target: link.target
51+
} : null
52+
53+
54+
this.linkPickerOverlay = {
55+
view: 'linkpicker',
56+
currentTarget: target,
57+
show: true,
58+
submit: function (model) {
59+
if (model.target.url) {
60+
if (link) {
61+
if (link.isMedia && link.url === model.target.url) {
62+
// we can assume the existing media item is changed and no new file has been selected
63+
// so we don't need to update the id, udi and isMedia fields
64+
} else {
65+
link.id = model.target.id
66+
link.udi = model.target.udi
67+
link.isMedia = model.target.isMedia
68+
}
69+
70+
link.name = model.target.name || model.target.url
71+
link.target = model.target.target
72+
link.url = model.target.url
73+
} else {
74+
link = {
75+
id: model.target.id,
76+
isMedia: model.target.isMedia,
77+
name: model.target.name || model.target.url,
78+
target: model.target.target,
79+
udi: model.target.udi,
80+
url: model.target.url
81+
}
82+
this.renderModel.push(link)
83+
}
84+
85+
if (link.udi) {
86+
var entityType = link.isMedia ? 'media' : 'document'
87+
88+
entityResource.getById(link.udi, entityType)
89+
.then(function (data) {
90+
link.icon = iconHelper.convertFromLegacyIcon(data.icon)
91+
link.published = !(data.metaData && data.metaData.IsPublished === false && entityType === 'document')
92+
})
93+
} else {
94+
link.published = true
95+
link.icon = 'icon-link'
96+
}
97+
98+
angularHelper.getCurrentForm($scope).$setDirty();
99+
}
143100

144-
if (link.id && link.id > 0) {
145-
entityResource.getById(link.id, link.isMedia ? 'Media' : 'Document').then(entityLoaded);
101+
this.linkPickerOverlay.show = false
102+
this.linkPickerOverlay = null
103+
}.bind(this)
146104
}
147-
148-
$scope.model.value = $scope.renderModel;
149-
$scope.editedMediaId = -1;
150-
dialogService.close();
151-
};
152-
153-
function Link(link, published) {
154-
this.id = link.id;
155-
this.name = link.name || link.url;
156-
this.url = link.url;
157-
this.target = link.target;
158-
this.isMedia = link.isMedia;
159-
this.icon = link.icon || 'icon-link';
160-
this.published = published;
161105
}
162-
});
163-
})(window.angular, window._);
106+
}
107+
108+
angular.module('umbraco')
109+
.controller('RJP.MultiUrlPickerController', MultiUrlPickerController)
110+
})()

0 commit comments

Comments
 (0)