0 Votes

Changes for page Todolist Macro

Last modified by Ryan C on 2025/04/30 07:54

From version 30.1
edited by Ryan C
on 2025/04/30 07:54
Change comment: Migrated property [featureMandatory] from class [XWiki.WikiMacroParameterClass]
To version 26.1
edited by Ryan C
on 2025/04/24 11:19
Change comment: There is no comment for this version

Summary

Details

XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,333 +1,302 @@
1 1  requirejs.config({
2 2   baseUrl: '${xwiki.getDocument("TodoLists.TodoListMacro").getURL("download")}/',
3 3   paths: {
4 - 'jquery-1.10.2': 'https://code.jquery.com/jquery-1.10.2.min'
4 + 'jquery': 'https://code.jquery.com/jquery-3.6.0.min' // Updated jQuery version
5 5   },
6 6   shim: {
7 7   'ember-data': {
8 - deps: ['ember']
8 + deps: ['ember', 'jquery']
9 9   },
10 10   'ember': {
11 - deps: ['jquery-1.10.2']
11 + deps: ['jquery']
12 12   }
13 13   }
14 14  });
15 15  
16 -// Load jQuery 1.10.2 specifically for Ember, using noConflict mode
17 -require(['jquery-1.10.2'], function(jQuery) {
18 - // Store the original jQuery and $ if they exist
19 - var originalJQuery = window.jQuery;
20 - var original$ = window.$;
21 -
22 - // Create a new jQuery instance in noConflict mode
23 - var emberJQuery = jQuery.noConflict(true);
24 -
25 - // Now load Ember with our specific jQuery
26 - require(['handlebars-v1.2.1', 'ember-data', 'ember'], function() {
27 - // Make emberJQuery available to Ember
28 - window.jQuery = emberJQuery;
29 - window.$ = emberJQuery;
30 -
31 - // Initialize Ember app
32 - initializeEmberApp(emberJQuery);
33 -
34 - // Restore original jQuery and $ when done
35 - window.jQuery = originalJQuery;
36 - window.$ = original$;
16 +require(['jquery', 'handlebars-v1.2.1', 'ember-data', 'ember'], function($) {
17 + // Create app
18 + window.Todos = Ember.Application.create({
19 + rootElement: '#todoappdiv'
37 37   });
38 -
39 - function initializeEmberApp(jQuery) {
40 - // Create app with specific jQuery instance
41 - window.Todos = Ember.Application.create({
42 - rootElement: '#todoappdiv',
43 - jQuery: jQuery
44 - });
45 45  
46 - // Define the todolist store that will write to the TodoListsService
47 - Todos.ApplicationAdapter = DS.Adapter.extend({
48 - serialize: function(record, options) {
49 - var serialized = record.record.toJSON();
50 - if (options && options.includeId) {
51 - serialized.id = record.id;
52 - }
53 - return serialized;
54 - },
22 + // Define the todolist store that will write to the TodoListsService
23 + Todos.ApplicationAdapter = DS.Adapter.extend({
24 + namespace: 'api', // Moved inside the adapter definition
25 +
26 + createRecord: function(store, type, record) {
27 + console.log("createRecord");
28 + var data = this.serialize(record, { includeId: true });
29 + var query = { create: "1", content: JSON.stringify(data) };
55 55  
56 - createRecord: function(store, type, record) {
57 - console.log("createRecord");
58 - var serialized = this.serialize(record, { includeId: true });
59 - var query = { create: "1", content: JSON.stringify(serialized) };
31 + return new Ember.RSVP.Promise(function(resolve, reject) {
32 + var url = "${xwiki.getURL('TodoLists.TodoListsService')}?page=" +
33 + XWiki.currentSpace + "." + XWiki.currentPage +
34 + "&xpage=plain&outputSyntax=plain";
35 + console.log("Creating record, URL:", url);
60 60  
61 - return new Ember.RSVP.Promise(function(resolve, reject) {
62 - var url = "${xwiki.getURL('TodoLists.TodoListsService')}?page=" +
63 - XWiki.currentSpace + "." + XWiki.currentPage +
64 - "&xpage=plain&outputSyntax=plain";
65 - console.log("Creating record, URL:", url);
66 -
67 - jQuery.getJSON(url, query).then(function(data) {
68 - console.log("Create success:", data);
69 - Ember.run(function() {
70 - resolve(data);
71 - });
72 - }, function(jqXHR) {
73 - console.error("Create error:", jqXHR);
74 - Ember.run(function() {
75 - reject(jqXHR);
76 - });
37 + jQuery.getJSON(url, query).then(function(data) {
38 + console.log("Create success:", data);
39 + Ember.run(function() {
40 + resolve(data);
77 77   });
42 + }, function(jqXHR) {
43 + console.error("Create error:", jqXHR);
44 + Ember.run(function() {
45 + reject(jqXHR);
46 + });
78 78   });
79 - },
48 + });
49 + },
50 +
51 + deleteRecord: function(store, type, record) {
52 + console.log("deleteRecord");
53 + var recordArrays = store.recordArrayManager.recordArraysForRecord(record);
54 + if (recordArrays && recordArrays.list && recordArrays.list[0]) {
55 + return this.saveAll(recordArrays.list[0].content);
56 + }
57 + return Ember.RSVP.resolve();
58 + },
59 +
60 + find: function(store, type, id) {
61 + console.log("find");
62 + return Ember.RSVP.resolve();
63 + },
64 +
65 + findAll: function(store, type, sinceToken) {
66 + console.log("findAll");
67 + var query = { since: sinceToken };
80 80  
81 - deleteRecord: function(store, type, record) {
82 - console.log("deleteRecord");
83 - var recordArrays = store.recordArrayManager.recordArraysForRecord(record);
84 - if (recordArrays && recordArrays.list && recordArrays.list[0]) {
85 - return this.saveAll(recordArrays.list[0].content);
86 - }
87 - return Ember.RSVP.resolve();
88 - },
89 -
90 - find: function(store, type, id) {
91 - console.log("find");
92 - return Ember.RSVP.resolve();
93 - },
94 -
95 - findAll: function(store, type, sinceToken) {
96 - console.log("findAll");
97 - var query = { since: sinceToken };
69 + return new Ember.RSVP.Promise(function(resolve, reject) {
70 + var url = "${xwiki.getURL('TodoLists.TodoListsService')}?page=" +
71 + XWiki.currentSpace + "." + XWiki.currentPage +
72 + "&xpage=plain&outputSyntax=plain";
73 + console.log("Finding all records, URL:", url);
98 98  
99 - return new Ember.RSVP.Promise(function(resolve, reject) {
100 - var url = "${xwiki.getURL('TodoLists.TodoListsService')}?page=" +
101 - XWiki.currentSpace + "." + XWiki.currentPage +
102 - "&xpage=plain&outputSyntax=plain";
103 - console.log("Finding all records, URL:", url);
104 -
105 - jQuery.getJSON(url, query).then(function(data) {
106 - console.log("FindAll success:", data);
107 - Ember.run(function() {
108 - resolve(data);
109 - });
110 - }, function(jqXHR) {
111 - console.error("FindAll error:", jqXHR);
112 - Ember.run(function() {
113 - reject(jqXHR);
114 - });
75 + jQuery.getJSON(url, query).then(function(data) {
76 + console.log("FindAll success:", data);
77 + Ember.run(function() {
78 + resolve(data);
115 115   });
80 + }, function(jqXHR) {
81 + console.error("FindAll error:", jqXHR);
82 + Ember.run(function() {
83 + reject(jqXHR);
84 + });
116 116   });
117 - },
86 + });
87 + },
88 +
89 + updateRecord: function(store, type, record) {
90 + console.log("updateRecord");
91 + var recordArrays = store.recordArrayManager.recordArraysForRecord(record);
92 + if (recordArrays && recordArrays.list && recordArrays.list[0]) {
93 + return this.saveAll(recordArrays.list[0].content);
94 + }
95 + return Ember.RSVP.resolve();
96 + },
97 +
98 + saveAll: function(alldata) {
99 + console.log("saveAll");
100 + var query = { save: "1", content: JSON.stringify(alldata) };
118 118  
119 - updateRecord: function(store, type, record) {
120 - console.log("updateRecord");
121 - var recordArrays = store.recordArrayManager.recordArraysForRecord(record);
122 - if (recordArrays && recordArrays.list && recordArrays.list[0]) {
123 - return this.saveAll(recordArrays.list[0].content);
124 - }
125 - return Ember.RSVP.resolve();
126 - },
127 -
128 - saveAll: function(alldata) {
129 - console.log("saveAll");
130 - var query = { save: "1", content: JSON.stringify(alldata) };
102 + return new Ember.RSVP.Promise(function(resolve, reject) {
103 + var currentPage = XWiki.currentSpace + "." + XWiki.currentPage;
104 + var url = "${xwiki.getURL('TodoLists.TodoListsService')}?page=" +
105 + currentPage + "&xpage=plain&outputSyntax=plain";
106 + console.log("Saving all records, URL:", url, "Page:", currentPage);
131 131  
132 - return new Ember.RSVP.Promise(function(resolve, reject) {
133 - var currentPage = XWiki.currentSpace + "." + XWiki.currentPage;
134 - var url = "${xwiki.getURL('TodoLists.TodoListsService')}?page=" +
135 - currentPage + "&xpage=plain&outputSyntax=plain";
136 - console.log("Saving all records, URL:", url, "Page:", currentPage);
137 -
138 - jQuery.getJSON(url, query).then(function(data) {
139 - console.log("SaveAll success:", data);
140 - Ember.run(function() {
141 - resolve(data);
142 - });
143 - }, function(jqXHR) {
144 - console.error("SaveAll error:", jqXHR);
145 - Ember.run(function() {
146 - reject(jqXHR);
147 - });
108 + jQuery.getJSON(url, query).then(function(data) {
109 + console.log("SaveAll success:", data);
110 + Ember.run(function() {
111 + resolve(data);
148 148   });
113 + }, function(jqXHR) {
114 + console.error("SaveAll error:", jqXHR);
115 + Ember.run(function() {
116 + reject(jqXHR);
117 + });
149 149   });
150 - }
151 - });
152 -
153 - // Routing
154 - Todos.Router.map(function() {
155 - this.resource('todos', { path: '' }, function() {
156 - this.route('active');
157 - this.route('completed');
158 158   });
159 - });
120 + }
121 + });
160 160  
161 - Todos.TodosRoute = Ember.Route.extend({
162 - model: function() {
163 - return this.store.find('todo');
164 - }
123 + // Routing
124 + Todos.Router.map(function() {
125 + this.resource('todos', { path: '' }, function() {
126 + this.route('active');
127 + this.route('completed');
165 165   });
129 + });
166 166  
167 - Todos.TodosIndexRoute = Ember.Route.extend({
168 - model: function() {
169 - return this.modelFor('todos');
170 - }
171 - });
131 + Todos.TodosRoute = Ember.Route.extend({
132 + model: function() {
133 + return this.store.find('todo');
134 + }
135 + });
172 172  
173 - Todos.TodosActiveRoute = Ember.Route.extend({
174 - model: function() {
175 - return this.store.filter('todo', function(todo) {
176 - return !todo.get('isCompleted');
177 - });
178 - },
179 - renderTemplate: function(controller) {
180 - this.render('todos/index', { controller: controller });
181 - }
182 - });
137 + Todos.TodosIndexRoute = Ember.Route.extend({
138 + model: function() {
139 + return this.modelFor('todos');
140 + }
141 + });
183 183  
184 - Todos.TodosCompletedRoute = Ember.Route.extend({
185 - model: function() {
186 - return this.store.filter('todo', function(todo) {
187 - return todo.get('isCompleted');
188 - });
189 - },
190 - renderTemplate: function(controller) {
191 - this.render('todos/index', { controller: controller });
192 - }
193 - });
143 + Todos.TodosActiveRoute = Ember.Route.extend({
144 + model: function() {
145 + return this.store.filter('todo', function(todo) {
146 + return !todo.get('isCompleted');
147 + });
148 + },
149 + renderTemplate: function(controller) {
150 + this.render('todos/index', { controller: controller });
151 + }
152 + });
194 194  
195 - // Data model
196 - Todos.Todo = DS.Model.extend({
197 - title: DS.attr('string'),
198 - priority: DS.attr('string'),
199 - assignee: DS.attr('string'),
200 - isCompleted: DS.attr('boolean')
201 - });
154 + Todos.TodosCompletedRoute = Ember.Route.extend({
155 + model: function() {
156 + return this.store.filter('todo', function(todo) {
157 + return todo.get('isCompleted');
158 + });
159 + },
160 + renderTemplate: function(controller) {
161 + this.render('todos/index', { controller: controller });
162 + }
163 + });
202 202  
203 - // Controller
204 - Todos.TodoController = Ember.ObjectController.extend({
205 - actions: {
206 - editTodo: function() {
207 - this.set('isEditing', true);
208 - },
209 - acceptChanges: function() {
210 - this.set('isEditing', false);
165 + // Data model
166 + Todos.Todo = DS.Model.extend({
167 + title: DS.attr('string'),
168 + priority: DS.attr('string'),
169 + assignee: DS.attr('string'),
170 + isCompleted: DS.attr('boolean')
171 + });
211 211  
212 - if (Ember.isEmpty(this.get('model.title'))) {
213 - this.send('removeTodo');
214 - } else {
215 - this.get('model').save();
216 - }
217 - },
218 - removeTodo: function() {
219 - var todo = this.get('model');
220 - todo.deleteRecord();
221 - todo.save();
222 - }
173 + // Controller
174 + Todos.TodoController = Ember.ObjectController.extend({
175 + actions: {
176 + editTodo: function() {
177 + this.set('isEditing', true);
223 223   },
179 + acceptChanges: function() {
180 + this.set('isEditing', false);
224 224  
225 - isEditing: false,
226 -
227 - isCompleted: function(key, value) {
228 - var model = this.get('model');
229 -
230 - if (value === undefined) {
231 - // Property being used as a getter
232 - return model.get('isCompleted');
182 + if (Ember.isEmpty(this.get('model.title'))) {
183 + this.send('removeTodo');
233 233   } else {
234 - // Property being used as setter
235 - model.set('isCompleted', value);
236 - model.save();
237 - return value;
185 + this.get('model').save();
238 238   }
239 - }.property('model.isCompleted')
240 - });
187 + },
188 + removeTodo: function() {
189 + var todo = this.get('model');
190 + todo.deleteRecord();
191 + todo.save();
192 + }
193 + },
241 241  
242 - Todos.TodosController = Ember.ArrayController.extend({
243 - actions: {
244 - createTodo: function() {
245 - // Get the todo title set by the "New Todo" text field
246 - var title = this.get('newTitle');
247 - if (!title || !title.trim()) { return; }
195 + isEditing: false,
248 248  
249 - console.log("Creating new todo with title:", title);
197 + isCompleted: function(key, value) {
198 + var model = this.get('model');
250 250  
251 - // Create the new Todo model
252 - var todo = this.store.createRecord('todo', {
253 - title: title,
254 - priority: "P3",
255 - assignee: "all",
256 - isCompleted: false
257 - });
200 + if (value === undefined) {
201 + // Property being used as a getter
202 + return model.get('isCompleted');
203 + } else {
204 + // Property being used as setter
205 + model.set('isCompleted', value);
206 + model.save();
207 + return value;
208 + }
209 + }.property('model.isCompleted')
210 + });
258 258  
259 - // Clear the "New Todo" text field
260 - this.set('newTitle', '');
212 + Todos.TodosController = Ember.ArrayController.extend({
213 + actions: {
214 + createTodo: function() {
215 + // Get the todo title set by the "New Todo" text field
216 + var title = this.get('newTitle');
217 + if (!title || !title.trim()) { return; }
261 261  
262 - // Save the new model
263 - todo.save().then(function(savedTodo) {
264 - console.log("Todo saved successfully:", savedTodo);
265 - // Force a refresh of the list after saving
266 - Ember.run.later(function() {
267 - console.log("Refreshing todo list");
268 - Todos.store.find('todo');
269 - }, 100);
270 - }, function(error) {
271 - console.error("Failed to save todo:", error);
272 - });
273 - },
274 -
275 - clearCompleted: function() {
276 - var completed = this.filter(function(todo) {
277 - return todo.get('isCompleted');
278 - });
279 -
280 - completed.forEach(function(todo) {
281 - todo.deleteRecord();
282 - todo.save();
283 - });
284 - }
285 - },
219 + console.log("Creating new todo with title:", title);
286 286  
287 - remaining: function() {
288 - return this.filter(function(todo) {
289 - return !todo.get('isCompleted');
290 - }).get('length');
291 - }.property('@each.isCompleted'),
221 + // Create the new Todo model
222 + var todo = this.store.createRecord('todo', {
223 + title: title,
224 + priority: "P3",
225 + assignee: "all",
226 + isCompleted: false
227 + });
292 292  
293 - inflection: function() {
294 - var remaining = this.get('remaining');
295 - return remaining === 1 ? 'item' : 'items';
296 - }.property('remaining'),
297 -
298 - hasCompleted: function() {
299 - return this.get('completed') > 0;
300 - }.property('completed'),
229 + // Clear the "New Todo" text field
230 + this.set('newTitle', '');
301 301  
302 - completed: function() {
303 - return this.filter(function(todo) {
232 + // Save the new model
233 + todo.save().then(function(savedTodo) {
234 + console.log("Todo saved successfully:", savedTodo);
235 + // Force a refresh of the list after saving
236 + Ember.run.later(function() {
237 + console.log("Refreshing todo list");
238 + Todos.store.find('todo');
239 + }, 100);
240 + }, function(error) {
241 + console.error("Failed to save todo:", error);
242 + });
243 + },
244 +
245 + clearCompleted: function() {
246 + var completed = this.filter(function(todo) {
304 304   return todo.get('isCompleted');
305 - }).get('length');
306 - }.property('@each.isCompleted'),
248 + });
249 +
250 + completed.forEach(function(todo) {
251 + todo.deleteRecord();
252 + todo.save();
253 + });
254 + }
255 + },
307 307  
308 - allAreDone: function(key, value) {
309 - if (value === undefined) {
310 - return this.get('length') > 0 && this.every(function(todo) {
311 - return todo.get('isCompleted');
312 - });
313 - } else {
314 - this.forEach(function(todo) {
315 - todo.set('isCompleted', value);
316 - todo.save();
317 - });
318 - return value;
319 - }
320 - }.property('@each.isCompleted')
321 - });
257 + remaining: function() {
258 + return this.filter(function(todo) {
259 + return !todo.get('isCompleted');
260 + }).get('length');
261 + }.property('@each.isCompleted'),
322 322  
323 - // Editing
324 - Todos.EditTodoView = Ember.TextField.extend({
325 - didInsertElement: function() {
326 - this.$().focus();
263 + inflection: function() {
264 + var remaining = this.get('remaining');
265 + return remaining === 1 ? 'item' : 'items';
266 + }.property('remaining'),
267 +
268 + hasCompleted: function() {
269 + return this.get('completed') > 0;
270 + }.property('completed'),
271 +
272 + completed: function() {
273 + return this.filter(function(todo) {
274 + return todo.get('isCompleted');
275 + }).get('length');
276 + }.property('@each.isCompleted'),
277 +
278 + allAreDone: function(key, value) {
279 + if (value === undefined) {
280 + return this.get('length') > 0 && this.every(function(todo) {
281 + return todo.get('isCompleted');
282 + });
283 + } else {
284 + this.forEach(function(todo) {
285 + todo.set('isCompleted', value);
286 + todo.save();
287 + });
288 + return value;
327 327   }
328 - });
290 + }.property('@each.isCompleted')
291 + });
329 329  
330 - Ember.Handlebars.helper('edit-todo', Todos.EditTodoView);
331 - }
293 + // Editing
294 + Todos.EditTodoView = Ember.TextField.extend({
295 + didInsertElement: function() {
296 + this.$().focus();
297 + }
298 + });
299 +
300 + Ember.Handlebars.helper('edit-todo', Todos.EditTodoView);
332 332  });
333 333