feat: bulk delete, team dispatch, calendar views, timeline colors
Deploy / deploy (push) Successful in 11s

- Multi-select bulk delete in all 5 list views (Artefacts, Posts, Tasks,
  Issues, Assets) with cascade deletes and confirmation modals
- Team-based issue dispatch: team picker on public issue form, team filter
  on Issues page, copy public link from Team page and Issues header,
  team assignment in IssueDetailPanel
- Month/Week toggle on PostCalendar and TaskCalendarView
- Month/Week/Day zoom on project and campaign timelines (InteractiveTimeline)
  and ProjectDetail GanttView, with Month as default
- Custom timeline bar colors: clickable color dot with 12-color palette
  popover on project, campaign, and task timeline bars
- Artefacts default view changed to list
- BulkSelectBar reusable component
- i18n keys for all new features (en + ar)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
fahed
2026-03-01 14:55:36 +03:00
parent 20d76dea8b
commit 42a5f17d0b
40 changed files with 3050 additions and 1625 deletions
+4 -2
View File
@@ -2,10 +2,12 @@ import { useState, useEffect } from 'react'
import { Settings as SettingsIcon, Play, CheckCircle, Languages, Coins, Upload } from 'lucide-react'
import { api } from '../utils/api'
import { useLanguage } from '../i18n/LanguageContext'
import { useToast } from '../components/ToastContainer'
import { CURRENCIES } from '../i18n/LanguageContext'
export default function Settings() {
const { t, lang, setLang, currency, setCurrency } = useLanguage()
const toast = useToast()
const [restarting, setRestarting] = useState(false)
const [success, setSuccess] = useState(false)
const [maxSizeMB, setMaxSizeMB] = useState(50)
@@ -25,7 +27,7 @@ export default function Settings() {
setSizeSaved(true)
setTimeout(() => setSizeSaved(false), 2000)
} catch (err) {
alert(err.message || 'Failed to save')
toast.error(err.message || t('settings.saveFailed'))
} finally {
setSizeSaving(false)
}
@@ -42,7 +44,7 @@ export default function Settings() {
}, 1500)
} catch (err) {
console.error('Failed to restart tutorial:', err)
alert('Failed to restart tutorial')
toast.error(t('settings.restartTutorialFailed'))
} finally {
setRestarting(false)
}