Исходный код вики AdminUsersSheet

Редактировал(а) Alexey Semenihin 23.10.2026, 15:12

Последние авторы
1 {{velocity output="false"}}
2 #macro (displayUsersLiveData)
3 #set ($properties = ['name', 'first_name', 'last_name', '_actions'])
4 #set ($sourceParameters = {
5 'template': 'getusers.vm',
6 'translationPrefix': 'xe.admin.users.'
7 })
8 #if (!$xcontext.isMainWiki())
9 #set ($discard = $properties.add(3, 'scope'))
10 #end
11 <div class="medium-avatars">
12 $services.liveData.render({
13 'id': 'userstable',
14 'source': 'liveTable',
15 'properties': $stringtool.join($properties, ','),
16 'sourceParameters': $escapetool.url($sourceParameters)
17 }, {
18 'query': {
19 'filters': [
20 {
21 'property': 'scope',
22 'constraints': [{
23 'operator': 'contains',
24 'value': 'local'
25 }]
26 }
27 ]
28 },
29 'meta': {
30 'propertyDescriptors': [
31 {
32 'id': 'name',
33 'displayer': 'html',
34 'sortable': false,
35 'editable': false
36 },
37 {
38 'id': 'first_name',
39 'sortable': false,
40 'editable': false
41 },
42 {
43 'id': 'last_name',
44 'sortable': false,
45 'editable': false
46 },
47 {
48 'id': 'scope',
49 'sortable': false,
50 'editable': false,
51 'filter': {
52 'id': 'list',
53 'options': [
54 {'value': 'local', 'label': $services.localization.render('rightsmanager.local')},
55 {'value': 'global', 'label': $services.localization.render('rightsmanager.global')},
56 {'value': 'both', 'label': $services.localization.render('rightsmanager.both')}
57 ]
58 }
59 },
60 {
61 'id': '_actions',
62 'displayer': {
63 'id': 'actions',
64 'actions': ['edit', 'disable', 'enable', 'delete']
65 }
66 }
67 ],
68 'actions': [
69 {
70 'id': 'disable',
71 'icon': 'lock',
72 'allowProperty': 'doc.hasdisable',
73 'urlProperty': 'doc.disable_url',
74 'extraIconClasses': 'text-warning'
75 },
76 {
77 'id': 'enable',
78 'icon': 'unlock',
79 'allowProperty': 'doc.hasenable',
80 'urlProperty': 'doc.enable_url',
81 'extraIconClasses': 'text-success'
82 }
83 ]
84 }
85 })
86 </div>
87 <p>
88 <button type="button" class="btn btn-primary" data-toggle="modal" data-target="${escapetool.h}createUserModal"
89 ## Disable the button until the JavaScript code that handles the user creation is ready.
90 disabled="disabled">
91 $escapetool.xml($services.localization.render('rightsmanager.addnewuser'))
92 </button>
93 </p>
94 #end
95
96 #macro (createUserModal)
97 <div class="modal" id="createUserModal" tabindex="-1" role="dialog" aria-labelledby="createUserModal-label"
98 data-backdrop="static" data-keyboard="false">
99 <div class="modal-dialog" role="document">
100 <div class="modal-content">
101 <div class="modal-header">
102 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
103 <span aria-hidden="true">&times;</span>
104 </button>
105 <div class="modal-title" id="createUserModal-label">
106 $escapetool.xml($services.localization.render('rightsmanager.addnewuser'))
107 </div>
108 </div>
109 <div class="modal-body"></div>
110 <div class="modal-footer">
111 <button type="button" class="btn btn-default" data-dismiss="modal">
112 $escapetool.xml($services.localization.render('cancel'))
113 </button>
114 ## The registration form is not present on page load so we can't bind the submit button without triggerig an
115 ## HTML validation error. That's why we set the form attribute from JavaScript instead.
116 <button type="submit" class="btn btn-primary" disabled="disabled">
117 $escapetool.xml($services.localization.render('create'))
118 </button>
119 </div>
120 </div>
121 </div>
122 </div>
123 #end
124
125 #macro (editUserModal)
126 <div class="modal" id="editUserModal" tabindex="-1" role="dialog" aria-labelledby="editUserModal-label"
127 data-backdrop="static" data-keyboard="false" data-live-data="#userstable" data-live-data-action="edit">
128 <div class="modal-dialog modal-lg" role="document">
129 <div class="modal-content">
130 <div class="modal-header">
131 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
132 <span aria-hidden="true">&times;</span>
133 </button>
134 <div class="modal-title" id="editUserModal-label">
135 $escapetool.xml($services.localization.render('xe.admin.users.editUser'))
136 </div>
137 </div>
138 <div class="modal-body"></div>
139 <div class="modal-footer">
140 <button type="button" class="btn btn-default" data-dismiss="modal">
141 $escapetool.xml($services.localization.render('cancel'))
142 </button>
143 <button type="button" class="btn btn-primary" disabled="disabled">
144 $escapetool.xml($services.localization.render('save'))
145 </button>
146 </div>
147 </div>
148 </div>
149 </div>
150 #end
151
152 #macro (deleteUserModal)
153 ## Load the resources needed by the user picker in order to be able to select the new author when deleting users that
154 ## have script or programming rights.
155 #userPicker_import
156 <div class="modal" id="deleteUserModal" tabindex="-1" role="dialog" aria-labelledby="deleteUserModal-label"
157 data-live-data="#userstable" data-live-data-action="delete">
158 <div class="modal-dialog" role="document">
159 <div class="modal-content">
160 <div class="modal-header">
161 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
162 <span aria-hidden="true">&times;</span>
163 </button>
164 <div class="modal-title" id="deleteUserModal-label">
165 $escapetool.xml($services.localization.render('xe.admin.users.deleteUser'))
166 </div>
167 </div>
168 <div class="modal-body loading"></div>
169 <div class="modal-footer">
170 <button type="button" class="btn btn-default" data-dismiss="modal">
171 $escapetool.xml($services.localization.render('cancel'))
172 </button>
173 <button type="button" class="btn btn-danger" data-dismiss="modal">
174 $escapetool.xml($services.localization.render('delete'))
175 </button>
176 </div>
177 </div>
178 </div>
179 </div>
180 #end
181
182 #macro (deleteUserModalContent $userReference)
183 {{html clean="false"}}
184 #set ($userReference = $services.model.resolveDocument($userReference, 'user', $doc.documentReference))
185 <p>$services.localization.render('administration.section.users.deleteUser.confirmationMessage', [
186 "#displayUser($userReference {'useInlineHTML': true})",
187 "<a href='$xwiki.getURL($userReference, 'view', 'category=groups')'>",
188 '</a>'
189 ])</p>
190 ## Check if the user we're about to delete has programming or script rights because in this case deleting the user may
191 ## break the pages where this user was the last (content) author.
192 ##
193 ## Note that we check programming and script rights at the wiki level only, in the wiki where the user is defined.
194 ## This doesn't cover all the cases because script right can be set at page level so it's possible that the user has
195 ## script right only on some pages (and not at the wiki level). Counting the pages that were last modified by this
196 ## user and for which they have script right is costly (we need to check script right separately for each page that
197 ## was last modified by the user, we can't do it in the database query).
198 #set ($wikiPrefsRef = $services.model.createDocumentReference($userReference.wikiReference.name, 'XWiki',
199 'XWikiPreferences'))
200 #if ($services.security.authorization.hasAccess('programming', $userReference, $wikiPrefsRef))
201 #maybeShowDeleteUserWarning($userReference 'programming')
202 #elseif ($services.security.authorization.hasAccess('script', $userReference, $wikiPrefsRef))
203 #maybeShowDeleteUserWarning($userReference 'script')
204 #end
205 {{/html}}
206 #end
207
208 #macro (maybeShowDeleteUserWarning $userReference $right)
209 #countPagesLastModifiedBy($userReference)
210 #if ($pageCount > 0)
211 {{/html}}
212
213 {{error cssClass="xform"}}
214 {{html}}
215 #set ($pageIndexReference = $services.model.createDocumentReference(
216 $userReference.wikiReference.name, 'Main', 'AllDocs'))
217 #set ($pageIndexURL = $xwiki.getURL($pageIndexReference, 'view', "doc.author=${escapetool.url($services.model.serialize($userReference, 'local'))}"))
218 #set ($translationKey = "administration.section.users.deleteUser.${right}RightsWarning")
219 $services.localization.render($translationKey, ["<a href='$pageIndexURL'>", $pageCount, '</a>'])
220 <dl>
221 <dt>
222 <label for="newAuthor">$escapetool.xml($services.localization.render(
223 'administration.section.users.deleteUser.newAuthor'))</label>
224 #set ($translationKey = 'administration.section.users.deleteUser.newAuthor.hint')
225 #set ($rightTranslation = $services.localization.render(
226 "administration.section.users.deleteUser.newAuthor.$right"))
227 <span class="xHint">$escapetool.xml($services.localization.render($translationKey,
228 [$rightTranslation]))</span>
229 </dt>
230 <dd>
231 #set ($userPickerParams = {
232 'id': 'newAuthor',
233 'name': 'newAuthor',
234 'data-required-right': $right
235 })
236 #userPicker(false $userPickerParams)
237 #set ($translationKey = 'administration.section.users.deleteUser.newAuthor.error')
238 <span class="xErrorMsg hidden">$escapetool.xml($services.localization.render($translationKey,
239 [$rightTranslation]))</span>
240 </dd>
241 </dl>
242 {{/html}}
243 {{/error}}
244
245 {{html clean="false"}}
246 #end
247 #end
248
249 #macro (countPagesLastModifiedBy $userReference)
250 #if ($userReference.wikiReference.name == $xcontext.mainWikiName)
251 ## Global user: search everywhere.
252 #set ($wikis = $services.wiki.allIds)
253 #else
254 ## Local user: search only in the wiki where the user is defined.
255 #set ($wikis = [$userReference.wikiReference.name])
256 #end
257 #set ($pageCount = 0)
258 #set ($statement = 'where doc.author = :user or doc.contentAuthor = :user')
259 #foreach ($wiki in $wikis)
260 #if ($userReference.wikiReference.name == $wiki)
261 #set ($userReferenceString = $services.model.serialize($userReference, 'local'))
262 #else
263 #set ($userReferenceString = $services.model.serialize($userReference, 'default'))
264 #end
265 #set ($pageCount = $pageCount + $services.query.xwql($statement).setWiki($wiki).addFilter('unique'
266 ).bindValue('user', $userReferenceString).count())
267 #end
268 #end
269
270 #macro (validateNewAuthor $newAuthorReference $requiredRight)
271 #set ($newAuthorReference = $services.model.resolveDocument($newAuthorReference, 'user', $doc.documentReference))
272 #set ($wikiPrefsRef = $services.model.createDocumentReference($newAuthorReference.wikiReference.name, 'XWiki',
273 'XWikiPreferences'))
274 #jsonResponse({
275 'valid': $services.security.authorization.hasAccess($requiredRight, $newAuthorReference, $wikiPrefsRef)
276 })
277 #end
278
279 #macro (doView)
280 ## We include new settings from the Wiki Manager (only if it is not the main wiki).
281 #set ($wikiManagerUserRef = $services.model.createDocumentReference('', 'WikiManager', 'WikiUsers'))
282 #if (!$xcontext.isMainWiki() && $xwiki.exists($wikiManagerUserRef))
283 {{include reference="WikiManager.WikiUsers" /}}
284 #end
285 ## The Users management is enabled:
286 ## - on the main wiki
287 ## - on a subwiki where local users are enabled
288 ## - on a subwiki if there is no service "$services.wiki.user"
289 #if ($xcontext.isMainWiki() || "$!services.wiki.user" == '' || "$!services.wiki.user.userScope" != 'GLOBAL_ONLY')
290 ##
291 ## Inject needed JS and CSS files
292 ##
293 #set ($discard = $xwiki.ssx.use("XWiki.XWikiUserSheet"))
294 #set ($discard = $xwiki.ssx.use("XWiki.AdminUsersSheet"))
295 #set ($discard = $xwiki.jsx.use("XWiki.AdminUsersSheet"))
296
297 {{html clean="false"}}
298 #displayUsersLiveData()
299 #createUserModal()
300 #editUserModal()
301 #deleteUserModal()
302 {{/html}}
303 #end
304 #end
305 {{/velocity}}
306
307 {{velocity}}
308 #if ($request.data == 'deleteUserModalContent' && "$!request.userReference" != '')
309 #deleteUserModalContent($request.userReference)
310 #elseif ($request.data == 'validateNewAuthor' && "$!request.newAuthor" != '' && "$!request.requiredRight" != '')
311 #validateNewAuthor($request.newAuthor $request.requiredRight)
312 #else
313 #doView
314 #end
315 {{/velocity}}