Show last authors
1 {{velocity wiki="false"}}
2 #if ($xcontext.action == 'get')
3 ##
4 ## Offset = item # at which to start displaying data
5 ##
6 #set ($offset = $numbertool.toNumber($request.get('offset')))
7 ## offset starts from 0 in velocity and 1 in javascript
8 #set ($offset = $offset - 1)
9 #if ($offset < 0)
10 #set ($offset = 0)
11 #end
12 ##
13 ## Limit = # of items to display
14 ##
15 #set ($limit = $numbertool.toNumber($request.get('limit')))
16 #set ($limitOffset = $offset + $limit)
17 ##
18 ## Build the list of NotificationFilterPreference related to the given user.
19 ##
20 #set ($isAccessGranted = false)
21 #if ("$!request.user" != "")
22 #set ($requestedUserDocRef = $services.model.resolveDocument($request.user))
23 #set ($isAccessGranted = ($services.security.authorization.hasAccess('admin', $requestedUserDocRef) || $xcontext.userReference.equals($requestedUserDocRef)))
24 #set ($document = $xwiki.getDocument($requestedUserDocRef))
25 #set ($target = $request.user)
26 #set ($userTarget = true)
27 ## when request user is not given we are sending the list of NotificationFilterPreference of the current wiki.
28 #else
29 #set ($target = $services.wiki.getCurrentWikiReference())
30 #set ($document = $xwiki.getDocument('XWiki.Notifications.Code.NotificationAdministration'))
31 #set ($userTarget = false)
32 #set ($isAccessGranted = true)
33 #end
34 #set ($elements = [])
35 #set ($index = 0)
36
37 ## For backward compatibility reason, we display both system filters and custom filters.
38 #set ($displayCustom = true)
39 #set ($displaySystem = true)
40 ## This is the translation prefix used for filter types in the deprecated macro.
41 #set ($filterTypeTranslationPrefix = "notifications.filters.type.")
42
43 #if ("$!request.type" == "custom")
44 #set ($displaySystem = false)
45 ## Those translations should now be used.
46 #set ($filterTypeTranslationPrefix = "notifications.filters.type.custom.")
47 #elseif ("$!request.type" == "system")
48 #set ($displayCustom = false)
49 #end
50
51 #if ($displaySystem && $isAccessGranted)
52 ## First: get the list of available toggeable filters for the user
53 ## We display them first because we don't want them to be hidden by thousands of page filters the autowatch option
54 ## might have created. It would be not good to have to go to the last page of the livetable to find out these commonly
55 ## used filters.
56 #if ($userTarget)
57 #set ($filters = $services.notification.filters.getToggleableNotificationFilters($target))
58 #else
59 #set ($filters = $services.notification.filters.getWikiToggleableNotificationFilters($target))
60 #end
61 #foreach ($filter in $filters)
62 #set ($index = $index + 1)
63 ## Optimization to render only displayed rows (between $offset and $limitOffset)
64 #if ($index > $offset and $index <= $limitOffset)
65 #set ($checked = $filter.isEnabledByDefault())
66 #set ($objectNumber = '')
67 #set ($obj = $document.getObject('XWiki.Notifications.Code.ToggleableFilterPreferenceClass', 'filterName', $filter.name))
68 #if ($obj)
69 #set ($checked = $obj.getValue('isEnabled') != 0)
70 #set ($objectNumber = $!obj.reference.objectNumber)
71 #end
72 #if ($checked)
73 #set ($checked = 'checked = "checked"')
74 #else
75 #set ($checked = '')
76 #end
77 #set ($checkbox = "<input type='checkbox' class='toggleableFilterPreferenceCheckbox' data-objectNumber='${objectNumber}' data-filtername='${filter.name}' $checked />")
78 #set ($name = $services.localization.render("notifications.filters.name.$filter.name"))
79 #set ($element = {
80 'filterPreferenceId' : $name,
81 'name' : $name,
82 'filterType' : $services.localization.render("notifications.filters.description.$filter.name"),
83 'eventTypes' : "#displayNotificationsEventTypeList($filter.eventTypes)",
84 'notificationFormats' : "#displayNotificationFormatsList($filter.formats)",
85 'isEnabled' : $checkbox,
86 'doc_viewable' : true,
87 'doc_hasdelete' : false
88 })
89 #set ($discard = $elements.add($element))
90 #end
91 #end
92 #set ($elements = $collectiontool.sort($elements, ['name']))
93 #end
94
95 #if ($displayCustom && $isAccessGranted)
96 ## Also get the list of available filters for the user
97 #set ($filters = $collectiontool.arrayList)
98 #if ($userTarget)
99 #set ($discard = $filters.addAll($services.notification.filters.getFilters($target)))
100 #else
101 #set ($discard = $filters.addAll($services.notification.filters.getWikiFilters($target)))
102 #end
103 #set ($filters = $collectiontool.sort($filters, ['name']))
104 #set ($displayHiddenDocument = "$xwiki.getUserPreference('displayHiddenDocuments')" == '1')
105 #foreach ($filter in $filters)
106 #set ($filtersPreferences = $collectiontool.arrayList)
107 #if ($userTarget)
108 #set ($discard = $filtersPreferences.addAll($services.notification.filters.getFilterPreferences($filter, $target)))
109 #else
110 #set ($discard = $filtersPreferences.addAll($services.notification.filters.getWikiFilterPreferences($filter, $target)))
111 #end
112 #set ($filtersPreferences = $collectiontool.sort($filtersPreferences, ['id']))
113 #foreach ($preference in $filtersPreferences)
114 #set ($page = $preference.pageOnly)
115 #set ($space = $preference.page)
116 #if (!$displayHiddenDocument && ($stringtool.isNotBlank($page) && $xwiki.getDocument($page).isHidden()
117 || $stringtool.isNotBlank($space) && $xwiki.getDocument($services.model.resolveSpace($space, 'default')).isHidden()))
118 ## Don't display a preference for an hidden page or space.
119 ## Why? If a user has the autowatch option enabled and create a new hidden document (for example, when she creates an application with AWM, hidden code pages are created as well),
120 ## we don't want to pollute the livetable with these hidden pages that the user don't know about. Moreover, the notifications will filter events concerning hidden pages,
121 ## so even if the filter exists, it has no effect to the user.
122 ## Here we handle only the case where pages.size() == 1 or spaces.size() == 1.
123 ## In the case there are several elements in the lists, they might have different "hidden" properties, and we don't handle it
124 ## Note: in the current implementation of watched entities, it's never the case.
125 ## TODO: handle these cases too in case custom filters need this.
126 #else
127 #set ($index = $index + 1)
128 ## Optimization to render only displayed rows (between $offset and $limitOffset)
129 #if ($index > $offset and $index <= $limitOffset)
130 #set ($display = $services.rendering.render($services.notification.filters.displayFilterPreference($filter, $preference), 'html/5.0'))
131 #set ($isEnabled = '')
132 #set ($isDisabled = '')
133 ## The watchlist bridge does not handle disabling a specific filter
134 #if ($preference.id.startsWith('watchlist_'))
135 #set ($isDisabled = 'disabled = "disabled"')
136 #end
137 #if ($preference.isEnabled())
138 #set ($isEnabled = 'checked = "checked"')
139 #end
140 #set ($isEnabled = "<input type='checkbox' class='notificationFilterPreferenceCheckbox' data-preferenceId='${preference.id}' $isEnabled $isDisabled />")
141
142 #set ($element = {
143 'filterPreferenceId' : $preference.id,
144 'name' : $display,
145 'filterType' : $services.localization.render("$filterTypeTranslationPrefix$!preference.getFilterType().name().toLowerCase()"),
146 'eventTypes' : "#displayNotificationsEventTypeList($preference.eventTypes)",
147 'notificationFormats' : "#displayNotificationFormatsList($preference.notificationFormats)",
148 'isEnabled' : $isEnabled,
149 'doc_viewable' : true
150 })
151 #set ($discard = $elements.add($element))
152 #end
153 #end
154 #end
155 #end
156 #end
157 #if ($isAccessGranted)
158 ##
159 ## JSON.
160 ##
161 #set ($discard = $response.setContentType('application/json'))
162 #set ($offset = $numbertool.toNumber($request.offset))
163 #if (!$offset)
164 #set ($offset = 1)
165 #end
166 $jsontool.serialize({
167 'totalrows' : $index,
168 'reqNo' : $request.reqNo,
169 'returnedrows': $elements.size(),
170 'offset' : $offset,
171 'rows' : $elements
172 })
173 #else
174 #set ($discard = $response.sendError(401))
175 #end
176 #end ## (context action)
177 ##
178 ## MACROS
179 ##
180 #macro (displayNotificationsEventTypeList $list)
181 <ul class="list-unstyled">
182 #if ($list.isEmpty())
183 <li>$escapetool.xml($services.localization.render('notifications.filters.preferences.allEvents'))</li>
184 #else
185 #set ($types = {})
186 #foreach ($descriptor in $services.eventstream.getRecordableEventDescriptors($xcontext.isMainWiki()))
187 #set ($discard = $types.put($descriptor.eventType, "$!services.localization.render($descriptor.description)"))
188 #end
189 #foreach ($eventType in $list)
190 <li>$escapetool.xml($types.get($eventType))</li>
191 #end
192 #end
193 </ul>
194 #end
195 #macro (displayNotificationFormatsList $formatList)
196 #set ($sortedFormatList = $collectiontool.sort($formatList))
197 <ul class="list-unstyled">
198 #foreach ($notificationFormat in $sortedFormatList)
199 <li>$services.localization.render("notifications.format.$!notificationFormat.name().toLowerCase()")</li>
200 #end
201 </ul>
202 #end
203 {{/velocity}}