PluginProbe ʕ •ᴥ•ʔ
Admin Help Docs / trunk
Admin Help Docs vtrunk
2.0.1.1 trunk 1.4.3.2 2.0.0 2.0.0.1 2.0.0.2 2.0.1
admin-help-docs / inc / tabs / js / documentation.js
admin-help-docs / inc / tabs / js Last commit date
admin-menu.js 3 months ago documentation.js 3 months ago import.js 3 months ago settings.js 3 months ago support.js 3 months ago
documentation.js
238 lines
1 jQuery( document ).ready( function( $ ) {
2
3 const list = $( '#helpdocs-docs-list' );
4 let draggedEl = null;
5 let draggedChildren = $();
6 let placeholder = $( '<li class="drag-placeholder"></li>' );
7
8 list.on( 'dragstart', 'li[draggable="true"]', function( e ) {
9 draggedEl = $( this );
10 const isFolder = draggedEl.data( 'type' ) === 'folder';
11
12 if ( isFolder ) {
13 list.find( 'li[data-type="folder"]' ).removeClass( 'active-folder' );
14 refreshFolderVisibility();
15
16 draggedChildren = list.find( 'li[data-type="item"][data-folder-id="' + draggedEl.data( 'folder-id' ) + '"]' );
17
18 let totalHeight = draggedEl.outerHeight();
19 draggedChildren.each( function() { totalHeight += $( this ).outerHeight(); } );
20 placeholder.css( 'height', totalHeight + 'px' );
21 placeholder.addClass( 'folder-placeholder' );
22 } else {
23 draggedChildren = $();
24 placeholder.css( 'height', draggedEl.outerHeight() + 'px' );
25 placeholder.removeClass( 'folder-placeholder' );
26 }
27
28 draggedEl.addClass( 'dragging' );
29 e.originalEvent.dataTransfer.effectAllowed = 'move';
30 } );
31
32 list.on( 'dragover', function( e ) {
33 e.preventDefault();
34
35 const target = $( e.target ).closest( 'li' );
36 if ( ! target.length || target.is( draggedEl ) || draggedChildren.is( target ) || target.is( placeholder ) ) {
37 return;
38 }
39
40 const draggedType = draggedEl.data( 'type' );
41 const targetType = target.data( 'type' );
42 const divider = list.find( '.invisible-folder' );
43
44 if ( draggedType === 'folder' ) {
45 if ( divider.length && target.index() > divider.index() ) {
46 return;
47 }
48
49 if ( targetType === 'folder' || target.hasClass( 'invisible-folder' ) ) {
50 const relY = e.originalEvent.pageY - target.offset().top;
51 if ( relY < target.outerHeight() / 2 ) {
52 target.before( placeholder );
53 } else {
54 if ( ! target.hasClass( 'invisible-folder' ) ) {
55 target.after( placeholder );
56 }
57 }
58 }
59 return;
60 }
61
62 const relY = e.originalEvent.pageY - target.offset().top;
63 if ( relY < target.outerHeight() / 2 ) {
64 target.before( placeholder );
65 } else {
66 target.after( placeholder );
67 }
68 } );
69
70 list.on( 'dragend', 'li', function() {
71 $( this ).removeClass( 'dragging' );
72 setTimeout( () => {
73 placeholder.detach();
74 }, 100 );
75 } );
76
77 list.on( 'drop', function( e ) {
78 e.preventDefault();
79 e.stopPropagation();
80
81 if ( ! placeholder.parent().length ) return;
82
83 const isFolder = draggedEl.data( 'type' ) === 'folder';
84
85 if ( isFolder ) {
86 placeholder.replaceWith( draggedEl );
87
88 list.find( 'li[data-type="folder"]' ).each( function() {
89 const currentFolder = $( this );
90 const folderId = currentFolder.data( 'folder-id' );
91
92 const folderItems = list.find( 'li[data-type="item"][data-folder-id="' + folderId + '"]' );
93
94 let lastElement = currentFolder;
95 folderItems.each( function() {
96 $( this ).insertAfter( lastElement );
97 lastElement = $( this );
98 } );
99 } );
100
101 const divider = list.find( '.invisible-folder' );
102 if ( divider.length ) {
103 const noFolderItems = list.find( 'li[data-type="item"][data-folder-id="0"]' );
104 let lastEl = divider;
105 noFolderItems.each( function() {
106 $( this ).insertAfter( lastEl );
107 lastEl = $( this );
108 } );
109 }
110 } else {
111 placeholder.replaceWith( draggedEl );
112
113 const divider = list.find( '.invisible-folder' );
114 const prevFolder = draggedEl.prevAll( 'li[data-type="folder"]' ).first();
115
116 const isBelowDivider = divider.length && draggedEl.index() > divider.index();
117
118 if ( isBelowDivider || ! prevFolder.length ) {
119 draggedEl.data( 'folder-id', 0 ).attr( 'data-folder-id', 0 );
120 draggedEl.removeClass( 'in-folder' ).addClass( 'not-in-folder' );
121 } else {
122 const newId = prevFolder.data( 'folder-id' );
123 draggedEl.data( 'folder-id', newId ).attr( 'data-folder-id', newId );
124 draggedEl.removeClass( 'not-in-folder' ).addClass( 'in-folder' );
125 }
126 }
127
128 updateFolderCounts();
129 refreshFolderVisibility();
130 saveOrder();
131 } );
132
133 function saveOrder() {
134 const folders = [];
135 const items = [];
136
137 list.find( 'li[data-type="folder"]' ).each( function() {
138 const fId = $( this ).data( 'folder-id' );
139 if ( fId !== undefined ) {
140 folders.push( fId );
141 }
142 } );
143
144 list.find( 'li[data-type="item"]' ).each( function() {
145 const $el = $( this );
146 items.push( {
147 'id': $el.data( 'item-id' ),
148 'folder': $el.data( 'folder-id' ),
149 'import_id': $el.data( 'import-id' ) || ''
150 } );
151 } );
152
153 console.log( 'Saving order...', { items } );
154
155 $.ajax( {
156 url: ajaxurl,
157 method: 'POST',
158 data: {
159 'action': 'helpdocs_save_docs_order',
160 'folders': folders,
161 'items': items,
162 'nonce': helpdocs_documentation.nonce
163 },
164 success: function( response ) {
165 if ( ! response.success ) {
166 console.error( 'Save failed:', response.data );
167 }
168 }
169 } );
170 }
171
172 function updateFolderCounts() {
173 list.find( 'li[data-type="folder"]' ).each( function() {
174 const folder = $( this );
175 const folderId = folder.data( 'folder-id' );
176 const count = list.find( 'li[data-type="item"]' ).filter( function() {
177 return $( this ).data( 'folder-id' ) === folderId;
178 } ).length;
179 folder.find( '.folder-count' ).text( count );
180 } );
181 }
182
183 function getFolderItems( folder ) {
184 const folderId = folder.data( 'folder-id' );
185 return list.find( 'li[data-type="item"]' ).filter( function() {
186 return $( this ).data( 'folder-id' ) === folderId;
187 } );
188 }
189
190 function refreshFolderVisibility() {
191 list.find( 'li[data-type="folder"]' ).each( function() {
192 const folder = $( this );
193 const folderItems = getFolderItems( folder );
194 if ( folder.hasClass( 'active-folder' ) ) {
195 folderItems.show();
196 } else {
197 folderItems.hide();
198 }
199 } );
200 }
201
202 const activeItem = $( '#helpdocs-docs-list .helpdocs-sidebar-item.active' );
203 if ( activeItem.length ) {
204 const folderId = activeItem.data( 'folder-id' );
205 if ( folderId && folderId !== 0 && folderId !== '0' ) {
206 const folder = $( '#folder-' + folderId );
207 $( '.helpdocs-folder' ).removeClass( 'active-folder' ).addClass( 'hide-in-folder' );
208 folder.addClass( 'active-folder' ).removeClass( 'hide-in-folder' );
209 } else {
210 $( '.helpdocs-folder' ).removeClass( 'active-folder' ).addClass( 'hide-in-folder' );
211 }
212 }
213
214 $( '#helpdocs-docs-list' ).on( 'click', '.helpdocs-folder > a', function( e ) {
215 e.preventDefault();
216 const folder = $( this ).parent();
217 folder.toggleClass( 'active-folder' );
218 refreshFolderVisibility();
219 } );
220
221 $( '#expand-all' ).on( 'click', function( e ) {
222 e.preventDefault();
223 list.find( 'li[data-type="folder"]' ).addClass( 'active-folder' );
224 refreshFolderVisibility();
225 } );
226
227 $( '#collapse-all' ).on( 'click', function( e ) {
228 e.preventDefault();
229 list.find( 'li[data-type="folder"]' ).removeClass( 'active-folder' );
230 refreshFolderVisibility();
231 } );
232
233 // Show expand/collapse links if there are folders
234 if ( list.find( 'li[data-type="folder"]' ).length ) {
235 $( '#helpdocs-header-action-links' ).fadeIn( 'slow' );
236 }
237
238 } );