Skip to content

טוסט ביטול פעולות בכמות - #2886

Open
amirbiron wants to merge 8 commits into
mainfrom
cursor/-bc-5216e0e5-88c5-4f09-92df-cd79e4c719e6-1f8f
Open

טוסט ביטול פעולות בכמות#2886
amirbiron wants to merge 8 commits into
mainfrom
cursor/-bc-5216e0e5-88c5-4f09-92df-cd79e4c719e6-1f8f

Conversation

@amirbiron

@amirbiron amirbiron commented Jan 23, 2026

Copy link
Copy Markdown
Owner

✨ תיאור קצר

  • יצרנו מדריך מקיף למימוש פיצ'ר "Toast עם כפתור בטל" (Undo Toast) עבור פעולות Bulk כמו מחיקה, תיוג והעברה.
  • המדריך נועד לשפר את חווית המשתמש ולאפשר ביטול מהיר של פעולות קריטיות, ובכך להפחית טעויות.

📦 שינויים עיקריים

  • קוד (Backend) - המדריך כולל דוגמאות קוד ל-API חדשים.
  • בוט טלגרם
  • מסד נתונים/מיגרציות
  • תיעוד (docs/) - יצירת קובץ מדריך חדש.
  • DevOps/CI/CD

פירוט נקודות:

  • יצירת קובץ מדריך חדש: GUIDES/UNDO_TOAST_IMPLEMENTATION_GUIDE.md.
  • המדריך מפרט ארכיטקטורה (Soft Delete, Deferred Action), מימוש Frontend (מחלקת UndoToastManager ב-JavaScript ו-CSS), ומימוש Backend (API לשחזור קבצים, שמירת/הגדרת תגיות).
  • המדריך כולל דוגמאות קוד מפורטות, שיקולי UX/ביצועים/אבטחה, וצ'קליסט למימוש.

🧪 בדיקות

  • המדריך עצמו כולל דוגמאות ל-Unit Tests ב-JavaScript ו-Integration Tests ב-Python עבור הפונקציונליות המתוארת.
  • Unit (המדריך מספק דוגמאות)
  • Integration (המדריך מספק דוגמאות)
  • Manual (המדריך מספק צ'קליסט לבדיקה ידנית)

🧪 בדיקות נדרשות ב‑PR

  • 🔍 Code Quality & Security
  • Unit Tests (3.11)
  • Unit Tests (3.12)

📝 סוג שינוי

  • docs: שינוי תיעוד בלבד

✅ צ'קליסט

  • הקוד עוקב אחרי הסגנון (Black/isort/flake8/mypy)
  • בדיקות רצות ועוברות
  • תיעוד עודכן (README/Docs)
  • אם נוספו ג'ובים חדשים (Background Jobs) – וודא שהם רשומים ב-services/register_jobs.py (כולל Callback/Trigger להפעלה ידנית — למשל callback_name/trigger_func לפי המבנה) כדי שיופיעו בדשבורד
  • אם נוספו/שונו משתני סביבה – עודכן docs/environment-variables.rst וגם services/config_inspector_service.py
  • אם נוספו/השתנו טוקנים – עודכן גם docs/webapp/theming_and_css.rst + FEATURE_SUGGESTIONS/theme_matrix.md
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות/פעולות על root (ראו .cursorrules)
  • הודעת הקומיט תואמת Conventional Commits (ע"פ הטבלה)
  • CHANGELOG עודכן אם נדרש
  • כל ה‑Required Checks לעיל ירוקים
  • צילום/וידאו UI מצורף אם רלוונטי

🧩 השפעות/סיכונים

  • הוספת המדריך עצמו אינה טומנת בחובה סיכונים ישירים. הסיכונים וההשפעות יתממשו בעת יישום המדריך בפועל.

🔗 קישורים

🧯 סיכון / החזרה לאחור (Rollback)

  • סיכון נמוך מאוד. במקרה תקלה, ניתן למחוק את קובץ המדריך.

Open in Cursor Open in Web


Note

Introduces a comprehensive guide for implementing an Undo-enabled toast after bulk operations.

  • New GUIDES/UNDO_TOAST_IMPLEMENTATION_GUIDE.md with architecture (soft delete/deferred action), UX/security considerations, and a rollout checklist
  • Frontend: UndoToastManager (JS) with safe rendering, timers, and optimistic UI flows for deleteSelected and addTags; accompanying CSS for themes, RTL, and mobile
  • Backend examples: POST /api/files/bulk-restore, POST /api/files/get-tags, POST /api/files/bulk-set-tags with Mongo updates and validation
  • Config hints (UNDO_TOAST_DURATION, SOFT_DELETE_TTL) and example unit/integration tests

Written by Cursor Bugbot for commit f4c2e93. This will update automatically on new commits. Configure here.

- Complete guide for implementing Toast with Undo button
- Includes frontend JavaScript (UndoToastManager class)
- Includes CSS styles with theme support and RTL
- Includes backend Python API endpoints
- Covers Bulk Delete, Tag, and Move operations
- Testing examples and implementation checklist

Co-authored-by: amirbiron <amirbiron@gmail.com>
@cursor

cursor Bot commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@github-actions

github-actions Bot commented Jan 23, 2026

Copy link
Copy Markdown

🧯 Dangerous deletes guard report

Policy: see .cursorrules — dangerous deletions are blocked unless wrapped safely.

Summary:

  • Flagged findings (blocking): 0
    0
  • Excluded matches (not blocking): 15
  • Total matches (all files): 125

Flagged findings (file:line:snippet):
(none)

Excluded matches (by path pattern)
./Dockerfile:42:    rm -rf /var/lib/apt/lists/*
./Dockerfile:121:    rm -rf /var/lib/apt/lists/*
./webapp/static/js/md_preview.bundle.js.map:4:  "sourcesContent": ["// Markdown-it plugin to render GitHub-style task lists; see\n//\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-t … [truncated]
./README.md:842:find . -name "__pycache__" -exec rm -rf {} +
./docs/DOCUMENTATION_GUIDE.md:453:rm -rf _build
./docs/Makefile:24:	rm -rf $(BUILDDIR)
./node_modules/mermaid/dist/chunks/mermaid.core/chunk-KS23V3DP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence  … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequen … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs:1:var r={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graph … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm/chunk-2M32CCKP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence d … [truncated]
./node_modules/mermaid/dist/mermaid.min.js:1524:`,"getStyles"),c1e=RQe});var h1e={};dr(h1e,{diagram:()=>NQe});var NQe,f1e=N(()=>{"use strict";$ge();a1e();l1e();u1e();NQe={parser:Fge,db:n1e,renderer:o1e,styles:c1e}});var m1e,g1e=N(()=>{"use  … [truncated]
./node_modules/mermaid/dist/mermaid.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values for tr … [truncated]
./node_modules/mermaid/dist/mermaid.min.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values fo … [truncated]
./node_modules/katex/package.json:153:    "build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
./node_modules/katex/src/fonts/Makefile:139:	rm -rf pfa ff otf ttf woff woff2

@github-actions

github-actions Bot commented Jan 23, 2026

Copy link
Copy Markdown

⏱️ Performance report

(No performance test durations collected. Mark tests with @pytest.mark.performance.)

@sentry

sentry Bot commented Jan 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@amirbiron
amirbiron marked this pull request as ready for review January 23, 2026 02:13
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

cursor[bot]

This comment was marked as outdated.

Security fixes:
- Add XSS protection with escapeHtml() and sanitizeIconName()
- Sanitize user input before innerHTML injection

Code quality fixes:
- Add parameter validation in show() method
- Add null safety with optional chaining in addTags()
- Replace deprecated substr() with slice()
- Remove unused variables (originalMessage, fileNames)
- Replace bare except clauses with specific exceptions
- Add type validation for file_ids (must be list)
- Add InvalidId import note for Python code

Co-authored-by: amirbiron <amirbiron@gmail.com>
@amirbiron
amirbiron marked this pull request as draft January 23, 2026 02:26
@amirbiron
amirbiron marked this pull request as ready for review January 23, 2026 02:26
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

cursor[bot]

This comment was marked as outdated.

- Add updateMessage() helper with null safety for DOM elements
- Fix get-tags API to return proper error status (500) instead of 200
- Add success field to get-tags response for explicit error checking
- Update getFilesTags() to throw on API failure
- Handle getFilesTags() failure gracefully - continue without undo
- Show regular notification instead of undo toast when no previous state

Co-authored-by: amirbiron <amirbiron@gmail.com>
@amirbiron
amirbiron marked this pull request as draft January 23, 2026 02:35
@amirbiron
amirbiron marked this pull request as ready for review January 23, 2026 02:35
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

- Add pendingDelete flag set immediately (before animation timeout)
- Store timeout IDs in Map to allow cancellation
- Cancel pending hide timeout when restore is called quickly
- Check both hiddenByDelete and pendingDelete in restore
- Clear both flags on restore to handle all states

Co-authored-by: amirbiron <amirbiron@gmail.com>
@amirbiron
amirbiron marked this pull request as draft January 23, 2026 02:45
- Check response.ok before calling response.json()
- Wrap JSON parsing in try/catch for non-JSON responses
- Provide clear error messages for each failure type

Co-authored-by: amirbiron <amirbiron@gmail.com>
@amirbiron
amirbiron marked this pull request as ready for review January 23, 2026 02:45
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

cursor[bot]

This comment was marked as outdated.

- Add isUndoing flag to toast data
- Set flag when handleUndo starts processing
- Check flag in dismiss() to skip onExpire when undoing
- Prevents incorrect state updates when undo completes

Co-authored-by: amirbiron <amirbiron@gmail.com>
@amirbiron
amirbiron marked this pull request as draft January 23, 2026 02:54
@amirbiron
amirbiron marked this pull request as ready for review January 23, 2026 02:54
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

1. Extract generateOperationId() as shared helper (DRY)
2. Clear existing timeout before creating new in hideFilesFromUI
3. Handle partial restore - only restore files that succeeded
4. Prevent double-click on undo with isUndoing check at entry
5. Track cleanup timeouts in handleUndo
6. Track and clear all timeouts in remove()
7. Add response.ok checks before JSON parsing in all fetch calls
8. Add RTL support for mobile close button position
9. Wrap onExpire callback in try/catch in dismiss()

Co-authored-by: amirbiron <amirbiron@gmail.com>
@amirbiron
amirbiron marked this pull request as draft January 23, 2026 03:11
@amirbiron
amirbiron marked this pull request as ready for review January 23, 2026 03:11
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

cursor[bot]

This comment was marked as outdated.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

// בטל כל ה-timeouts הפעילים
clearTimeout(timeout);
if (cleanupTimeout) clearTimeout(cleanupTimeout);
if (fallbackTimeout) clearTimeout(fallbackTimeout);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code attempts to clear nonexistent timeout

Low Severity

The remove method destructures fallbackTimeout from toastData and attempts to clear it, but fallbackTimeout is never stored in the toastData object. It's only created after the map entry is deleted. The clearTimeout(fallbackTimeout) on line 326 never executes because fallbackTimeout is always undefined from the destructuring.

Fix in Cursor Fix in Web

const {
operationId,
message,
duration = 5000,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duration parameter lacks validation for invalid values

Medium Severity

The duration parameter in the show method accepts any value without validation. Non-numeric values (e.g., "hello") are coerced by setTimeout to NaN, which is treated as 0, causing the toast to dismiss immediately. Negative values produce invalid CSS transitions and near-instant dismissal. Users would be unable to see the message or click the undo button, defeating the entire purpose of the toast.

Additional Locations (1)

Fix in Cursor Fix in Web

// סגור אחרי שנייה - שמור reference ל-timeout
const cleanupTimeout = setTimeout(() => {
this.remove(operationId);
}, 1500);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition in handleUndo removes wrong toast

Medium Severity

After handleUndo awaits the async onUndo() callback, it calls this.remove(operationId) to remove the toast. During the await, if show() is called with the same operationId, the original toast is dismissed and a new one is created with that ID. When the original handleUndo resumes, it removes the new toast instead of the old one, causing the wrong toast to disappear unexpectedly.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants