@qnote/q-ai-note 1.0.21 → 1.0.22

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.
Files changed (2) hide show
  1. package/dist/web/app.js +92 -25
  2. package/package.json +1 -1
package/dist/web/app.js CHANGED
@@ -1209,20 +1209,27 @@ function renderWorkTree() {
1209
1209
  if (fromIdx < 0) return;
1210
1210
  const toIdx = fromIdx + delta;
1211
1211
  if (toIdx < 0 || toIdx >= siblings.length) return;
1212
- const peers = siblings.filter((item) => item.id !== nodeId);
1213
- const left = peers[toIdx - 1] || null;
1214
- const right = peers[toIdx] || null;
1212
+ const reordered = [...siblings];
1213
+ const [movedNode] = reordered.splice(fromIdx, 1);
1214
+ reordered.splice(toIdx, 0, movedNode);
1215
+ const left = reordered[toIdx - 1] || null;
1216
+ const right = reordered[toIdx + 1] || null;
1215
1217
  const nextOrderKey = rankBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'));
1216
- if (nextOrderKey === getNodeOrderKey(node, 'order_key')) return;
1217
- await apiRequest(`${API_BASE}/items/${nodeId}`, {
1218
- method: 'PUT',
1219
- body: JSON.stringify({
1220
- extra_data: {
1221
- ...(node.extra_data || {}),
1222
- order_key: nextOrderKey,
1223
- },
1224
- }),
1225
- });
1218
+ const canDirectUpdate = nextOrderKey !== getNodeOrderKey(node, 'order_key')
1219
+ && isOrderKeyBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'), nextOrderKey);
1220
+ if (canDirectUpdate) {
1221
+ await apiRequest(`${API_BASE}/items/${nodeId}`, {
1222
+ method: 'PUT',
1223
+ body: JSON.stringify({
1224
+ extra_data: {
1225
+ ...(node.extra_data || {}),
1226
+ order_key: nextOrderKey,
1227
+ },
1228
+ }),
1229
+ });
1230
+ } else {
1231
+ await persistSiblingOrderByList(reordered, parentId);
1232
+ }
1226
1233
  await loadSandbox(state.currentSandbox.id);
1227
1234
  },
1228
1235
  onReorderSiblings: treeReadonly ? undefined : async (dragNodeId, targetNodeId, position) => {
@@ -1243,19 +1250,30 @@ function renderWorkTree() {
1243
1250
  const targetIndex = siblings.findIndex((item) => item.id === targetNodeId);
1244
1251
  if (targetIndex < 0) return;
1245
1252
  const insertIndex = position === 'after' ? targetIndex + 1 : targetIndex;
1246
- const left = siblings[insertIndex - 1] || null;
1247
- const right = siblings[insertIndex] || null;
1253
+ const reordered = [...siblings];
1254
+ reordered.splice(insertIndex, 0, dragNode);
1255
+ const left = reordered[insertIndex - 1] || null;
1256
+ const right = reordered[insertIndex + 1] || null;
1248
1257
  const nextOrderKey = rankBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'));
1249
- await apiRequest(`${API_BASE}/items/${dragNodeId}`, {
1250
- method: 'PUT',
1251
- body: JSON.stringify({
1252
- parent_id: nextParentId,
1253
- extra_data: {
1254
- ...(dragNode.extra_data || {}),
1255
- order_key: nextOrderKey,
1256
- },
1257
- }),
1258
- });
1258
+ const canDirectUpdate = isOrderKeyBetween(getNodeOrderKey(left, 'order_key'), getNodeOrderKey(right, 'order_key'), nextOrderKey)
1259
+ && (
1260
+ nextOrderKey !== getNodeOrderKey(dragNode, 'order_key')
1261
+ || (dragNode.parent_id || null) !== nextParentId
1262
+ );
1263
+ if (canDirectUpdate) {
1264
+ await apiRequest(`${API_BASE}/items/${dragNodeId}`, {
1265
+ method: 'PUT',
1266
+ body: JSON.stringify({
1267
+ parent_id: nextParentId,
1268
+ extra_data: {
1269
+ ...(dragNode.extra_data || {}),
1270
+ order_key: nextOrderKey,
1271
+ },
1272
+ }),
1273
+ });
1274
+ } else {
1275
+ await persistSiblingOrderByList(reordered, nextParentId, dragNodeId);
1276
+ }
1259
1277
  await loadSandbox(state.currentSandbox.id);
1260
1278
  },
1261
1279
  onReorderLanes: treeReadonly ? undefined : async (dragRootId, targetRootId, position = 'before') => {
@@ -1409,6 +1427,55 @@ function rankBetween(left, right) {
1409
1427
  return `${prefix}${ORDER_ALPHABET[Math.floor(ORDER_BASE / 2)]}`;
1410
1428
  }
1411
1429
 
1430
+ function encodeOrderIndex(index, width = 6) {
1431
+ let value = Number.isFinite(index) ? Math.max(0, Math.floor(index)) : 0;
1432
+ let encoded = '';
1433
+ do {
1434
+ const digit = value % ORDER_BASE;
1435
+ encoded = `${ORDER_ALPHABET[digit]}${encoded}`;
1436
+ value = Math.floor(value / ORDER_BASE);
1437
+ } while (value > 0);
1438
+ return encoded.padStart(width, ORDER_ALPHABET[0]);
1439
+ }
1440
+
1441
+ function isOrderKeyBetween(leftKey, rightKey, candidateKey) {
1442
+ const left = String(leftKey || '');
1443
+ const right = String(rightKey || '');
1444
+ const candidate = String(candidateKey || '');
1445
+ if (!candidate) return false;
1446
+ if (left && candidate <= left) return false;
1447
+ if (right && candidate >= right) return false;
1448
+ return true;
1449
+ }
1450
+
1451
+ async function persistSiblingOrderByList(orderedItems, nextParentId = null, movedNodeId = '') {
1452
+ const items = Array.isArray(orderedItems) ? orderedItems : [];
1453
+ for (let index = 0; index < items.length; index += 1) {
1454
+ const item = items[index];
1455
+ if (!item?.id) continue;
1456
+ const targetKey = encodeOrderIndex((index + 1) * 1024);
1457
+ const currentKey = getNodeOrderKey(item, 'order_key');
1458
+ const isMovedNode = Boolean(movedNodeId) && String(item.id) === String(movedNodeId);
1459
+ const currentParentId = item.parent_id || null;
1460
+ const needsParentUpdate = isMovedNode && currentParentId !== nextParentId;
1461
+ const needsOrderUpdate = currentKey !== targetKey;
1462
+ if (!needsParentUpdate && !needsOrderUpdate) continue;
1463
+ const body = {
1464
+ extra_data: {
1465
+ ...(item.extra_data || {}),
1466
+ order_key: targetKey,
1467
+ },
1468
+ };
1469
+ if (needsParentUpdate) {
1470
+ body.parent_id = nextParentId;
1471
+ }
1472
+ await apiRequest(`${API_BASE}/items/${item.id}`, {
1473
+ method: 'PUT',
1474
+ body: JSON.stringify(body),
1475
+ });
1476
+ }
1477
+ }
1478
+
1412
1479
  function getNodeOrderKey(item, keyName = 'order_key') {
1413
1480
  return String(item?.extra_data?.[keyName] || '').trim();
1414
1481
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qnote/q-ai-note",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "type": "module",
5
5
  "description": "AI-assisted personal work sandbox and diary system",
6
6
  "main": "dist/server/index.js",