@xuda.io/account_module 1.2.2300 → 1.2.2301
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +74 -19
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -55,6 +55,18 @@ const module_path = path.join(process.env.XUDA_HOME, 'cpi') + (!_conf.is_debug ?
|
|
|
55
55
|
|
|
56
56
|
const db_module = await import(`${module_path}/db_module/index.mjs`);
|
|
57
57
|
|
|
58
|
+
// Sort keys for the dashboard list tabs, per docType. Each entry is a fallback
|
|
59
|
+
// chain (first defined value wins) because doc shapes differ. A profile keeps
|
|
60
|
+
// its display name under profile_name, a contact under name. See
|
|
61
|
+
// db_module.find_app_couch_sorted_page.
|
|
62
|
+
const LIST_SORT_PATHS = {
|
|
63
|
+
contact: { created: ['date_created_ts', 'date_created', 'ts'], updated: ['ts', 'date_created_ts'], name: ['name', 'contact_name', 'email'] },
|
|
64
|
+
account_profile: { created: ['date_created_ts', 'date_created', 'ts'], updated: ['ts', 'date_created_ts'], name: ['profile_name', 'name'] },
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Dashboard list tabs whose sort preference is remembered per profile.
|
|
68
|
+
const LIST_SORT_TABS = ['ai_chats', 'apps', 'contacts', 'ai_agents', 'account_profiles'];
|
|
69
|
+
|
|
58
70
|
const ai_ms = await import(`${module_path}/ai_module/index_ms.mjs`);
|
|
59
71
|
const drive_ms = await import(`${module_path}/drive_module/index_ms.mjs`);
|
|
60
72
|
|
|
@@ -370,7 +382,7 @@ export const update_account_info = async function (req, job_id, headers) {
|
|
|
370
382
|
return save_ret;
|
|
371
383
|
};
|
|
372
384
|
export const update_account_preferences = async function (req) {
|
|
373
|
-
const { uid, hide_create_button, default_dashboard, sidebar_style, enable_thumbnail_avatar_generation, sidenav_mode, newsletter_opt_in } = req;
|
|
385
|
+
const { uid, hide_create_button, default_dashboard, sidebar_style, enable_thumbnail_avatar_generation, sidenav_mode, newsletter_opt_in, dashboard_sort } = req;
|
|
374
386
|
try {
|
|
375
387
|
let account_doc = await db_module.get_couch_doc_native('xuda_accounts', uid);
|
|
376
388
|
account_doc.ts = Date.now();
|
|
@@ -386,6 +398,32 @@ export const update_account_preferences = async function (req) {
|
|
|
386
398
|
// flag via router /newsletter/unsubscribe. Only touched when the caller sends it.
|
|
387
399
|
if (newsletter_opt_in !== undefined) account_doc.preferences.newsletter_opt_in = !!newsletter_opt_in;
|
|
388
400
|
|
|
401
|
+
// Dashboard list sort, remembered per PROFILE and per tab so switching
|
|
402
|
+
// profiles brings back that profile's own order:
|
|
403
|
+
// preferences.dashboard_sort[<account_profile_id>][<tab>] = { by, dir }
|
|
404
|
+
// Callers send one tab at a time ({ tab, sort_by, sort_dir, profile_id })
|
|
405
|
+
// and the merge below is surgical, so saving the Contacts order can never
|
|
406
|
+
// drop the one saved for AI Chats or for another profile. Sending
|
|
407
|
+
// sort_by:null clears that tab back to the default order.
|
|
408
|
+
if (dashboard_sort !== undefined) {
|
|
409
|
+
const { tab, sort_by, sort_dir } = dashboard_sort || {};
|
|
410
|
+
if (LIST_SORT_TABS.includes(tab)) {
|
|
411
|
+
const profile_info = await get_active_account_profile_info(uid, dashboard_sort?.profile_id);
|
|
412
|
+
const profile_key = profile_info?.account_profile_id || 'default';
|
|
413
|
+
const all = { ...(account_doc.preferences.dashboard_sort || {}) };
|
|
414
|
+
const for_profile = { ...(all[profile_key] || {}) };
|
|
415
|
+
|
|
416
|
+
if (['date', 'updated', 'name'].includes(sort_by)) {
|
|
417
|
+
for_profile[tab] = { by: sort_by, dir: sort_dir === 'asc' ? 'asc' : 'desc' };
|
|
418
|
+
} else {
|
|
419
|
+
delete for_profile[tab];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
all[profile_key] = for_profile;
|
|
423
|
+
account_doc.preferences.dashboard_sort = all;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
389
427
|
const save_ret = await db_module.save_couch_doc('xuda_accounts', account_doc);
|
|
390
428
|
if (save_ret.code < 0) {
|
|
391
429
|
throw new Error(save_ret.data);
|
|
@@ -5466,17 +5504,25 @@ export const get_contacts = async function (req, job_id, headers) {
|
|
|
5466
5504
|
let contacts = { docs: [], total_docs: 0 };
|
|
5467
5505
|
|
|
5468
5506
|
if (filter_type !== 'pending') {
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5507
|
+
// User-picked order from the dashboard list controls, see
|
|
5508
|
+
// db_module.find_app_couch_sorted_page. Null when none was asked for,
|
|
5509
|
+
// which leaves the default newest-first path below untouched.
|
|
5510
|
+
const sorted = contact_id ? null : await db_module.find_app_couch_sorted_page(account_profile_info.app_id, opt, req, LIST_SORT_PATHS.contact);
|
|
5511
|
+
if (sorted) {
|
|
5512
|
+
contacts = sorted;
|
|
5472
5513
|
} else {
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5514
|
+
contacts = await find_contact_query(account_profile_info.uid, opt);
|
|
5515
|
+
if (!limit || contact_id) {
|
|
5516
|
+
contacts.total_docs = contacts.docs.length;
|
|
5517
|
+
} else {
|
|
5518
|
+
delete opt.sort;
|
|
5519
|
+
delete opt.skip;
|
|
5520
|
+
opt.limit = 9999;
|
|
5521
|
+
opt.fields = ['_id'];
|
|
5477
5522
|
|
|
5478
|
-
|
|
5479
|
-
|
|
5523
|
+
const counter = await find_contact_query(account_profile_info.uid, opt);
|
|
5524
|
+
contacts.total_docs = counter.docs.length;
|
|
5525
|
+
}
|
|
5480
5526
|
}
|
|
5481
5527
|
}
|
|
5482
5528
|
|
|
@@ -6157,17 +6203,26 @@ export const get_account_profiles = async function (req) {
|
|
|
6157
6203
|
let profiles = { docs: [], total_docs: 0 };
|
|
6158
6204
|
|
|
6159
6205
|
if (filter_type !== 'pending') {
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6206
|
+
// User-picked order from the dashboard list controls, see
|
|
6207
|
+
// db_module.find_app_couch_sorted_page. Null when none was asked for,
|
|
6208
|
+
// which leaves the default newest-first path below untouched. The main
|
|
6209
|
+
// profile is still floated to the top of the page after enrichment.
|
|
6210
|
+
const sorted = profile_id ? null : await db_module.find_app_couch_sorted_page(app_id, opt, req, LIST_SORT_PATHS.account_profile);
|
|
6211
|
+
if (sorted) {
|
|
6212
|
+
profiles = sorted;
|
|
6163
6213
|
} else {
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6214
|
+
profiles = await db_module.find_app_couch_query(app_id, opt);
|
|
6215
|
+
if (!limit || profile_id) {
|
|
6216
|
+
profiles.total_docs = profiles.docs.length;
|
|
6217
|
+
} else {
|
|
6218
|
+
delete opt.sort;
|
|
6219
|
+
delete opt.skip;
|
|
6220
|
+
opt.limit = 9999;
|
|
6221
|
+
opt.fields = ['_id'];
|
|
6168
6222
|
|
|
6169
|
-
|
|
6170
|
-
|
|
6223
|
+
const counter = await db_module.find_app_couch_query(app_id, opt);
|
|
6224
|
+
profiles.total_docs = counter.docs.length;
|
|
6225
|
+
}
|
|
6171
6226
|
}
|
|
6172
6227
|
}
|
|
6173
6228
|
|