diff --git a/.playwright-mcp/console-2026-03-16T09-27-00-418Z.log b/.playwright-mcp/console-2026-03-16T09-27-00-418Z.log index a2af043..8402014 100644 --- a/.playwright-mcp/console-2026-03-16T09-27-00-418Z.log +++ b/.playwright-mcp/console-2026-03-16T09-27-00-418Z.log @@ -59,3 +59,87 @@ at commitHookPassiveMountEffects (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:9465:60) at commitPassiveMountOnFiber (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11040:29) at recursivelyTraversePassiveMountEffects (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11010:13) @ http://localhost:5173/src/App.jsx?t=1773661195572:135 +[11275011ms] [ERROR] %o + +%s + +%s + ReferenceError: PortalSelect is not defined + at Artefacts (http://localhost:5173/src/pages/Artefacts.jsx?t=1773664494925:936:11) + at Object.react_stack_bottom_frame (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:18509:20) + at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:5654:24) + at updateFunctionComponent (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7475:21) + at beginWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:8484:199) + at runWithFiberInDEV (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:997:72) + at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12561:98) + at workLoopSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12424:43) + at renderRootSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12408:13) + at performWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11827:37) The above error occurred in the component. React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary. @ http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7000 +[11275012ms] [ERROR] ErrorBoundary caught: ReferenceError: PortalSelect is not defined + at Artefacts (http://localhost:5173/src/pages/Artefacts.jsx?t=1773664494925:936:11) + at Object.react_stack_bottom_frame (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:18509:20) + at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:5654:24) + at updateFunctionComponent (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7475:21) + at beginWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:8484:199) + at runWithFiberInDEV (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:997:72) + at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12561:98) + at workLoopSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12424:43) + at renderRootSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12408:13) + at performWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11827:37) {componentStack: + at Artefacts (http://localhost:5173/src/pages…vite/deps/react-router-dom.js?v=50a373cd:10250:3)} @ http://localhost:5173/src/components/ErrorBoundary.jsx:12 +[11282373ms] [ERROR] %o + +%s + +%s + ReferenceError: PortalSelect is not defined + at Artefacts (http://localhost:5173/src/pages/Artefacts.jsx?t=1773664502312:936:11) + at Object.react_stack_bottom_frame (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:18509:20) + at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:5654:24) + at updateFunctionComponent (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7475:21) + at beginWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:8484:199) + at runWithFiberInDEV (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:997:72) + at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12561:98) + at workLoopSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12424:43) + at renderRootSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12408:13) + at performWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11827:37) The above error occurred in the component. React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary. @ http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7000 +[11282374ms] [ERROR] ErrorBoundary caught: ReferenceError: PortalSelect is not defined + at Artefacts (http://localhost:5173/src/pages/Artefacts.jsx?t=1773664502312:936:11) + at Object.react_stack_bottom_frame (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:18509:20) + at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:5654:24) + at updateFunctionComponent (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7475:21) + at beginWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:8484:199) + at runWithFiberInDEV (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:997:72) + at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12561:98) + at workLoopSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12424:43) + at renderRootSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12408:13) + at performWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11827:37) {componentStack: + at Artefacts (http://localhost:5173/src/pages…vite/deps/react-router-dom.js?v=50a373cd:10250:3)} @ http://localhost:5173/src/components/ErrorBoundary.jsx:12 +[11301530ms] [ERROR] %o + +%s + +%s + ReferenceError: PortalSelect is not defined + at Artefacts (http://localhost:5173/src/pages/Artefacts.jsx?t=1773664521350:936:11) + at Object.react_stack_bottom_frame (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:18509:20) + at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:5654:24) + at updateFunctionComponent (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7475:21) + at beginWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:8484:199) + at runWithFiberInDEV (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:997:72) + at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12561:98) + at workLoopSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12424:43) + at renderRootSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12408:13) + at performWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11827:37) The above error occurred in the component. React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary. @ http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7000 +[11301531ms] [ERROR] ErrorBoundary caught: ReferenceError: PortalSelect is not defined + at Artefacts (http://localhost:5173/src/pages/Artefacts.jsx?t=1773664521350:936:11) + at Object.react_stack_bottom_frame (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:18509:20) + at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:5654:24) + at updateFunctionComponent (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:7475:21) + at beginWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:8484:199) + at runWithFiberInDEV (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:997:72) + at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12561:98) + at workLoopSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12424:43) + at renderRootSync (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:12408:13) + at performWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/react-dom_client.js?v=50a373cd:11827:37) {componentStack: + at Artefacts (http://localhost:5173/src/pages…vite/deps/react-router-dom.js?v=50a373cd:10250:3)} @ http://localhost:5173/src/components/ErrorBoundary.jsx:12 diff --git a/approver-dropdown-test.png b/approver-dropdown-test.png deleted file mode 100644 index 601716e..0000000 Binary files a/approver-dropdown-test.png and /dev/null differ diff --git a/campaign-select-test.png b/campaign-select-test.png deleted file mode 100644 index ce6c877..0000000 Binary files a/campaign-select-test.png and /dev/null differ diff --git a/client/src/components/ArtefactDetailPanel.jsx b/client/src/components/ArtefactDetailPanel.jsx index 994590e..9c3b02c 100644 --- a/client/src/components/ArtefactDetailPanel.jsx +++ b/client/src/components/ArtefactDetailPanel.jsx @@ -6,7 +6,6 @@ import { api } from '../utils/api' import Modal from './Modal' import TabbedModal from './TabbedModal' import { useToast } from './ToastContainer' -import ApproverMultiSelect from './ApproverMultiSelect' import PortalSelect from './PortalSelect' import { ArtefactDetailVersionsTab } from './ArtefactDetailVersionsTab' @@ -25,7 +24,7 @@ const TYPE_ICONS = { other: Sparkles, } -export default function ArtefactDetailPanel({ artefact, onClose, onUpdate, onDelete, projects = [], campaigns = [], assignableUsers = [] }) { +export default function ArtefactDetailPanel({ artefact, onClose, onUpdate, onDelete, assignableUsers = [] }) { const { t } = useLanguage() const { brands } = useContext(AppContext) const toast = useToast() @@ -41,8 +40,6 @@ export default function ArtefactDetailPanel({ artefact, onClose, onUpdate, onDel // Editable fields const [editTitle, setEditTitle] = useState(artefact.title || '') const [editDescription, setEditDescription] = useState(artefact.description || '') - const [editProjectId, setEditProjectId] = useState(artefact.project_id || '') - const [editCampaignId, setEditCampaignId] = useState(artefact.campaign_id || '') const [editApproverIds, setEditApproverIds] = useState( artefact.approvers?.map(a => String(a.id)) || (artefact.approver_ids ? artefact.approver_ids.split(',').map(s => s.trim()).filter(Boolean) : []) ) @@ -67,8 +64,6 @@ export default function ArtefactDetailPanel({ artefact, onClose, onUpdate, onDel useEffect(() => { setEditTitle(artefact.title || '') setEditDescription(artefact.description || '') - setEditProjectId(artefact.project_id || '') - setEditCampaignId(artefact.campaign_id || '') setEditApproverIds( artefact.approvers?.map(a => String(a.id)) || (artefact.approver_ids ? artefact.approver_ids.split(',').map(s => s.trim()).filter(Boolean) : []) ) diff --git a/client/src/components/PortalSelect.jsx b/client/src/components/PortalSelect.jsx index 9af45ea..9ec8bbe 100644 --- a/client/src/components/PortalSelect.jsx +++ b/client/src/components/PortalSelect.jsx @@ -76,6 +76,9 @@ export default function PortalSelect({ value, onChange, options = [], placeholde type="button" onClick={handleOpen} disabled={disabled} + role="combobox" + aria-expanded={open} + aria-haspopup="listbox" className={`flex items-center justify-between gap-1 text-start ${className} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`} > {displayText} @@ -85,6 +88,7 @@ export default function PortalSelect({ value, onChange, options = [], placeholde {open && createPortal(
@@ -94,6 +98,8 @@ export default function PortalSelect({ value, onChange, options = [], placeholde
-
-

{t('translations.approversLabel')}

- -
)} @@ -443,13 +434,28 @@ export default function TranslationDetailPanel({ translation, onClose, onUpdate, {activeTab === 'review' && (
{['draft', 'revision_requested', 'rejected'].includes(translation.status) && ( - + <> +
+

{t('artefacts.reviewer')}

+ { + const ids = val ? [val] : [] + setEditApproverIds(ids) + handleFieldUpdate('approver_ids', val || '') + }} + options={[{ value: '', label: t('artefacts.selectReviewer') }, ...(assignableUsers || []).map(u => ({ value: u.id || u.Id, label: u.name }))]} + className="w-full px-3 py-2 text-sm border border-border rounded-lg bg-surface text-text-primary" + /> +
+ + )} {currentReviewUrl && ( diff --git a/client/src/i18n/ar.json b/client/src/i18n/ar.json index 202d712..a3e501e 100644 --- a/client/src/i18n/ar.json +++ b/client/src/i18n/ar.json @@ -606,6 +606,9 @@ "issues.noIssuesInColumn": "لا توجد مشاكل", "artefacts.details": "التفاصيل", "artefacts.review": "المراجعة", + "artefacts.selectVersionFirst": "اختر إصداراً لعرض التعليقات.", + "artefacts.pendingReviewInfo": "هذا العنصر قيد المراجعة حالياً.", + "artefacts.noReviewInfo": "لا توجد معلومات مراجعة متاحة.", "artefacts.grid": "شبكة", "artefacts.list": "قائمة", "artefacts.allCreators": "جميع المنشئين", diff --git a/client/src/i18n/en.json b/client/src/i18n/en.json index 90e12fc..97026bb 100644 --- a/client/src/i18n/en.json +++ b/client/src/i18n/en.json @@ -606,6 +606,9 @@ "issues.noIssuesInColumn": "No issues", "artefacts.details": "Details", "artefacts.review": "Review", + "artefacts.selectVersionFirst": "Select a version to view comments.", + "artefacts.pendingReviewInfo": "This artefact is currently pending review.", + "artefacts.noReviewInfo": "No review information available.", "artefacts.grid": "Grid", "artefacts.list": "List", "artefacts.allCreators": "All Creators", diff --git a/client/src/pages/Artefacts.jsx b/client/src/pages/Artefacts.jsx index 8fa3d69..1a83dc7 100644 --- a/client/src/pages/Artefacts.jsx +++ b/client/src/pages/Artefacts.jsx @@ -11,7 +11,7 @@ import { useToast } from '../components/ToastContainer' import ArtefactVersionTimeline from '../components/ArtefactVersionTimeline' import { SkeletonCard, SkeletonTable } from '../components/SkeletonLoader' import ArtefactDetailPanel from '../components/ArtefactDetailPanel' -import ApproverMultiSelect from '../components/ApproverMultiSelect' +import PortalSelect from '../components/PortalSelect' const STATUS_COLORS = { draft: 'bg-surface-tertiary text-text-secondary', @@ -56,7 +56,7 @@ export default function Artefacts() { const [searchTerm, setSearchTerm] = useState('') const [showCreateModal, setShowCreateModal] = useState(false) const [selectedArtefact, setSelectedArtefact] = useState(null) - const [newArtefact, setNewArtefact] = useState({ title: '', description: '', type: 'copy', brand_id: '', content: '', project_id: '', campaign_id: '', approver_ids: [] }) + const [newArtefact, setNewArtefact] = useState({ title: '', type: 'copy' }) const [saving, setSaving] = useState(false) // Bulk select @@ -101,12 +101,12 @@ export default function Artefacts() { setSaving(true) try { const created = await api.post('/artefacts', { - ...newArtefact, - approver_ids: newArtefact.approver_ids.length > 0 ? newArtefact.approver_ids.join(',') : null, + title: newArtefact.title, + type: newArtefact.type, }) toast.success(t('artefacts.created')) setShowCreateModal(false) - setNewArtefact({ title: '', description: '', type: 'copy', brand_id: '', content: '', project_id: '', campaign_id: '', approver_ids: [] }) + setNewArtefact({ title: '', type: 'copy' }) loadArtefacts() setSelectedArtefact(created) } catch (err) { @@ -480,7 +480,7 @@ export default function Artefacts() { )} {/* Create Modal */} - setShowCreateModal(false)} title={t('artefacts.createArtefact')} size="md"> + setShowCreateModal(false)} title={t('artefacts.createArtefact')} size="sm">
@@ -490,67 +490,16 @@ export default function Artefacts() { onChange={e => setNewArtefact(f => ({ ...f, title: e.target.value }))} className="w-full px-3 py-2 text-sm border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary" placeholder={t('artefacts.titlePlaceholder')} + autoFocus />
- -
-
- - -
-
- - -
-
- - -
-
- - setNewArtefact(f => ({ ...f, approver_ids: ids }))} - /> -
-
- -