diff --git a/src/components/ClaimReview/ClaimReviewHeader.tsx b/src/components/ClaimReview/ClaimReviewHeader.tsx
index a7816d64a..ed16d99e7 100644
--- a/src/components/ClaimReview/ClaimReviewHeader.tsx
+++ b/src/components/ClaimReview/ClaimReviewHeader.tsx
@@ -74,10 +74,10 @@ const ClaimReviewHeader = ({
/>
{showTopicInput && (
)}
diff --git a/src/components/VerificationRequest/CreateVerificationRequest/ImpactAreaSelect.tsx b/src/components/VerificationRequest/CreateVerificationRequest/ImpactAreaSelect.tsx
index f1dca1ed5..dac8d0a51 100644
--- a/src/components/VerificationRequest/CreateVerificationRequest/ImpactAreaSelect.tsx
+++ b/src/components/VerificationRequest/CreateVerificationRequest/ImpactAreaSelect.tsx
@@ -1,30 +1,25 @@
-import * as React from "react";
-import { useEffect, useState} from "react";
+import React, { useState, useEffect } from "react";
import MultiSelectAutocomplete from "../../topics/TopicOrImpactSelect";
+import { IImpactAreaSelect, ManualTopic } from "../../../types/Topic";
-
-interface ImpactAreaSelectProps {
- onChange: (value: string) => void;
- placeholder?: string;
-}
-
-const ImpactAreaSelect: React.FC = ({
+const ImpactAreaSelect = ({
onChange,
placeholder,
-}) => {
- const [value, setValue] = useState("");
+}: IImpactAreaSelect) => {
+ const [value, setValue] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
- onChange(value || undefined);
+ onChange(value);
}, []);
+
return (
);
diff --git a/src/components/VerificationRequest/VerificationRequestDetailDrawer.tsx b/src/components/VerificationRequest/VerificationRequestDetailDrawer.tsx
index d76e17ac2..13dacabd9 100644
--- a/src/components/VerificationRequest/VerificationRequestDetailDrawer.tsx
+++ b/src/components/VerificationRequest/VerificationRequestDetailDrawer.tsx
@@ -460,12 +460,12 @@ const VerificationRequestDetailDrawer: React.FC
diff --git a/src/components/topics/TagDisplay.tsx b/src/components/topics/TagDisplay.tsx
index 05b57f646..c9c268345 100644
--- a/src/components/topics/TagDisplay.tsx
+++ b/src/components/topics/TagDisplay.tsx
@@ -6,12 +6,7 @@ import TagsList from "./TagsList";
import { useAtom } from "jotai";
import { isUserLoggedIn } from "../../atoms/currentUser";
import TagDisplayStyled from "./TagDisplay.style";
-
-interface ITagDisplay {
- handleClose: (removedTopicValue: any) => Promise;
- tags: any[];
- setShowTopicsForm: (topicsForm: any) => void;
-}
+import { ITagDisplay } from "../../types/Topic";
const TagDisplay = ({ handleClose, tags, setShowTopicsForm }: ITagDisplay) => {
const [isLoggedIn] = useAtom(isUserLoggedIn);
@@ -31,7 +26,7 @@ const TagDisplay = ({ handleClose, tags, setShowTopicsForm }: ITagDisplay) => {
color: colors.primary,
}}
>
- {tags.length ? : }
+ {tags.length ? : }
)}
diff --git a/src/components/topics/TopicDisplay.tsx b/src/components/topics/TopicDisplay.tsx
index cada1c89f..e2a902b3a 100644
--- a/src/components/topics/TopicDisplay.tsx
+++ b/src/components/topics/TopicDisplay.tsx
@@ -7,51 +7,57 @@ import TagDisplay from "./TagDisplay";
import SentenceApi from "../../api/sentenceApi";
import verificationRequestApi from "../../api/verificationRequestApi";
import { ReviewTaskTypeEnum } from "../../machines/reviewTask/enums";
+import { ITopicDisplay } from "../../types/Topic";
const TopicDisplay = ({
data_hash,
topics,
reviewTaskType,
contentModel = null,
-}) => {
+}: ITopicDisplay) => {
const [showTopicsForm, setShowTopicsForm] = useState(false);
const [topicsArray, setTopicsArray] = useState(topics);
- const [inputValue, setInputValue] = useState([]);
+ const [selectedTags, setSelectedTags] = useState([]);
const [tags, setTags] = useState([]);
const { t } = useTranslation();
useEffect(() => {
- const inputValueFormatted = inputValue.map((inputValue) =>
- inputValue?.value
+ const formattedSelectedTags = selectedTags.map((selectedTag) =>
+ selectedTag?.value
? {
- label: inputValue?.label,
- value: inputValue?.value,
- aliases: inputValue?.aliases || [],
- matchedAlias: inputValue?.matchedAlias || null,
+ label: selectedTag?.label,
+ value: selectedTag?.value,
+ aliases: selectedTag?.aliases || [],
+ matchedAlias: selectedTag?.matchedAlias || null,
}
- : inputValue
+ : selectedTag
);
- const filterValues = inputValueFormatted.filter(
- (inputValue) =>
+ const filterSelectedTags = formattedSelectedTags.filter(
+ (selectedTag) =>
!topicsArray.some(
(topic) =>
(topic?.value || topic) ===
- (inputValue?.value || inputValue)
+ (selectedTag?.value || selectedTag)
)
);
- setTags(topicsArray?.concat(filterValues) || []);
- }, [inputValue, topicsArray]);
+ setTags(topicsArray?.concat(filterSelectedTags) || []);
+ }, [selectedTags, topicsArray]);
+
+ console.log(topicsArray,selectedTags)
const handleClose = async (removedTopicValue: any) => {
+ // NOTE: Filtering logic differs due to inconsistent data structures across collections:
+ // 1. topicsArray: May contain persisted topics from VerificationRequest, requiring 'wikidataId' as an identifier.
+ // 2. selectedTags: Follows the 'ManualTopic' UI schema, which consistently uses 'value'.
const newTopicsArray = topicsArray.filter(
- (topic) => (topic?.value || topic) !== removedTopicValue
+ (topic) => (topic?.value || topic?.wikidataId || topic) !== removedTopicValue
);
- const newInputValue = inputValue.filter(
+ const newSelectedTag = selectedTags.filter(
(topic) => (topic?.value || topic) !== removedTopicValue
);
setTopicsArray(newTopicsArray);
- setInputValue(newInputValue);
+ setSelectedTags(newSelectedTag);
if (reviewTaskType === ReviewTaskTypeEnum.VerificationRequest) {
return await verificationRequestApi.deleteVerificationRequestTopic(
@@ -84,7 +90,7 @@ const TopicDisplay = ({
data_hash={data_hash}
topicsArray={topicsArray}
setTopicsArray={setTopicsArray}
- setInputValue={setInputValue}
+ setSelectedTags={setSelectedTags}
tags={tags}
reviewTaskType={reviewTaskType}
/>
diff --git a/src/components/topics/TopicForm.tsx b/src/components/topics/TopicForm.tsx
index 8c0f538a2..acce8e387 100644
--- a/src/components/topics/TopicForm.tsx
+++ b/src/components/topics/TopicForm.tsx
@@ -5,26 +5,16 @@ import AletheiaButton from "../Button";
import TopicInputErrorMessages from "./TopicInputErrorMessages";
import { useTranslation } from "next-i18next";
import TopicsApi from "../../api/topicsApi";
-import { ContentModelEnum } from "../../types/enums";
import MultiSelectAutocomplete from "./TopicOrImpactSelect";
import verificationRequestApi from "../../api/verificationRequestApi";
-
-interface ITopicForm {
- contentModel: ContentModelEnum;
- data_hash: string;
- topicsArray: any[];
- setTopicsArray: (topicsArray) => void;
- setInputValue: (inputValue) => void;
- tags: any[];
- reviewTaskType: string;
-}
+import { ITopicForm } from "../../types/Topic";
const TopicForm = ({
contentModel,
data_hash,
topicsArray,
setTopicsArray,
- setInputValue,
+ setSelectedTags,
tags,
reviewTaskType,
}: ITopicForm) => {
@@ -92,7 +82,7 @@ const TopicForm = ({
onChange={onChange}
setIsLoading={setIsLoading}
isLoading={isLoading}
- setInputValue={setInputValue}
+ setSelectedTags={setSelectedTags}
/>
)}
/>
diff --git a/src/components/topics/TopicOrImpactSelect.tsx b/src/components/topics/TopicOrImpactSelect.tsx
index 470de7839..54a97898e 100644
--- a/src/components/topics/TopicOrImpactSelect.tsx
+++ b/src/components/topics/TopicOrImpactSelect.tsx
@@ -8,15 +8,16 @@ import {
import { useDispatch } from "react-redux";
import TopicsApi from "../../api/topicsApi";
import { useTranslation } from "react-i18next";
+import { IMultiSelectAutocomplete } from "../../types/Topic";
const MultiSelectAutocomplete = ({
isMultiple = true,
onChange,
isLoading,
placeholder,
- setInputValue,
+ setSelectedTags,
setIsLoading,
-}) => {
+}: IMultiSelectAutocomplete) => {
const { t } = useTranslation();
const [options, setOptions] = useState([]);
const dispatch = useDispatch();
@@ -77,9 +78,9 @@ const MultiSelectAutocomplete = ({
size="small"
options={options}
onInputChange={(_, value) => fetchOptions(value)}
- onChange={(_, selectedValues) => {
- onChange(selectedValues);
- setInputValue(selectedValues);
+ onChange={(_, inputTag) => {
+ onChange(inputTag);
+ setSelectedTags(inputTag);
}}
getOptionLabel={(option) =>
option.displayLabel || option.label || ""
diff --git a/src/types/Topic.ts b/src/types/Topic.ts
index 4d9cbbf28..650ef18ac 100644
--- a/src/types/Topic.ts
+++ b/src/types/Topic.ts
@@ -1,3 +1,6 @@
+import React from "react";
+import { ReviewTaskTypeEnum } from "../machines/reviewTask/enums";
+import { ContentModelEnum } from "./enums";
export interface Topic {
_id: string;
name: string;
@@ -5,3 +8,50 @@ export interface Topic {
slug: string;
language: string;
}
+
+export interface ManualTopic {
+ id?: string;
+ aliases?: string[];
+ displayLabel?: string;
+ label: string;
+ matchedAlias?: string | null;
+ value: string;
+}
+
+export type UnifiedTopic = Topic | ManualTopic;
+export interface ITagDisplay {
+ handleClose: (removedTopicValue: string) => Promise;
+ tags: ManualTopic[];
+ setShowTopicsForm: React.Dispatch>;
+}
+
+export interface ITopicForm {
+ contentModel: ContentModelEnum;
+ data_hash: string;
+ topicsArray: UnifiedTopic[];
+ setTopicsArray: React.Dispatch>;
+ setSelectedTags: React.Dispatch>;
+ tags: ManualTopic[];
+ reviewTaskType: ReviewTaskTypeEnum;
+}
+
+export interface ITopicDisplay {
+ data_hash: string;
+ topics: UnifiedTopic[];
+ reviewTaskType: ReviewTaskTypeEnum;
+ contentModel?: ContentModelEnum | null;
+}
+
+export interface IImpactAreaSelect {
+ onChange: (value: ManualTopic[]) => void;
+ placeholder?: string;
+}
+
+export interface IMultiSelectAutocomplete {
+ isMultiple?: boolean;
+ onChange: (value: ManualTopic[]) => void;
+ isLoading: boolean;
+ placeholder: string;
+ setSelectedTags: React.Dispatch>;
+ setIsLoading: React.Dispatch>;
+}