fix selection and more assignments

This commit is contained in:
Sara
2023-12-11 19:12:37 +01:00
parent 6d44cdab9f
commit 369a16b4a5
4 changed files with 184 additions and 42 deletions

View File

@@ -28,7 +28,6 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
const [selectedTime, setSelectedTime] = useState<TimeSlice>(); const [selectedTime, setSelectedTime] = useState<TimeSlice>();
const [topicTime, setTopicTime] = useState<TimeSlice>(); const [topicTime, setTopicTime] = useState<TimeSlice>();
const api = getApi();
const participants = useParticipants(transcriptId); const participants = useParticipants(transcriptId);
const stateSelectedSpeaker = useState<number>(); const stateSelectedSpeaker = useState<number>();
@@ -66,7 +65,13 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
topicTime={topicTime} topicTime={topicTime}
/> />
<ParticipantList <ParticipantList
{...{ transcriptId, participants, selectedTime, topicWithWords }} {...{
transcriptId,
participants,
selectedTime,
topicWithWords,
stateSelectedSpeaker,
}}
/> />
</div> </div>
</div> </div>

View File

@@ -1,35 +1,36 @@
import { faSpinner } from "@fortawesome/free-solid-svg-icons"; import { faArrowTurnDown, faSpinner } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { Participant } from "../../../../api"; import { Participant } from "../../../../api";
import getApi from "../../../../lib/getApi"; import getApi from "../../../../lib/getApi";
import { UseParticipants } from "../../useParticipants";
import { unescapeLeadingUnderscores } from "typescript";
type ParticipantList = {
participants: UseParticipants;
transcriptId: string;
selectedTime: any;
topicWithWords: any;
stateSelectedSpeaker: any;
};
const ParticipantList = ({ const ParticipantList = ({
transcriptId, transcriptId,
participants, participants,
selectedTime, selectedTime,
topicWithWords, topicWithWords,
}) => { stateSelectedSpeaker,
}: ParticipantList) => {
const api = getApi(); const api = getApi();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [participantInput, setParticipantInput] = useState(""); const [participantInput, setParticipantInput] = useState("");
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [selectedSpeaker, setSelectedSpeaker] = stateSelectedSpeaker;
const createParticipant = () => { const [action, setAction] = useState<
if (!loading) { "Create" | "Create to rename" | "Create and assign" | "Rename" | null
setLoading(true); >(null);
api const [oneMatch, setOneMatch] = useState<Participant>();
?.v1TranscriptAddParticipant({
createParticipant: { name: participantInput, speaker: 99 },
transcriptId,
})
.then((participant) => {
participants.refetch();
assignTo(participant)();
});
}
};
useEffect(() => { useEffect(() => {
if (loading) { if (loading) {
@@ -38,10 +39,111 @@ const ParticipantList = ({
}, [participants.loading]); }, [participants.loading]);
useEffect(() => { useEffect(() => {
if (selectedTime) { if (participants.response) {
if (selectedSpeaker !== undefined) {
inputRef.current?.focus(); inputRef.current?.focus();
const participant = participants.response.find(
(p) => p.speaker == selectedSpeaker,
);
if (participant) {
setParticipantInput(participant.name);
inputRef.current?.focus();
setAction("Rename");
} else {
setParticipantInput("");
inputRef.current?.focus();
setAction("Create to rename");
} }
}, [selectedTime]); }
if (selectedTime) {
setParticipantInput("");
inputRef.current?.focus();
setAction("Create and assign");
}
}
}, [selectedTime, selectedSpeaker]);
useEffect(() => {
if (participants.response && action == "Create and assign") {
if (
participants.response.filter((p) => p.name.startsWith(participantInput))
.length == 1
) {
setOneMatch(
participants.response.find((p) =>
p.name.startsWith(participantInput),
),
);
} else {
setOneMatch(undefined);
}
}
}, [participantInput]);
useEffect(() => {
document.onkeyup = (e) => {
if (e.key === "Enter" && e.ctrlKey) {
if (oneMatch) {
assignTo(oneMatch)();
setOneMatch(undefined);
setParticipantInput("");
}
}
};
});
const doAction = (e) => {
if (!participants.response) return;
if (action == "Rename") {
const participant = participants.response.find(
(p) => p.speaker == selectedSpeaker,
);
if (participant && participant.name !== participantInput) {
api
?.v1TranscriptUpdateParticipant({
participantId: participant.id,
transcriptId,
updateParticipant: {
name: participantInput,
},
})
.then(() => {
participants.refetch();
});
}
} else if (action == "Create to rename") {
setLoading(true);
console.log(participantInput, selectedSpeaker);
api
?.v1TranscriptAddParticipant({
createParticipant: {
name: participantInput,
speaker: selectedSpeaker,
},
transcriptId,
})
.then(() => {
participants.refetch();
});
} else if (action == "Create and assign") {
setLoading(true);
api
?.v1TranscriptAddParticipant({
createParticipant: {
name: participantInput,
speaker: Math.floor(Math.random() * 100 + 10),
},
transcriptId,
})
.then((participant) => {
assignTo(participant)();
participants.refetch();
});
}
e.preventDefault();
console.log(e);
console.log(action);
};
const deleteParticipant = (participantId) => () => { const deleteParticipant = (participantId) => () => {
if (!loading) { if (!loading) {
@@ -75,13 +177,25 @@ const ParticipantList = ({
topicWithWords.refetch(); topicWithWords.refetch();
}); });
}; };
const selectParticipant = (participant) => (e) => {
console.log(participant, e);
setSelectedSpeaker(participant.speaker);
};
return ( return (
<> <>
<form onSubmit={doAction}>
<input <input
ref={inputRef} ref={inputRef}
onChange={(e) => setParticipantInput(e.target.value)} onChange={(e) => setParticipantInput(e.target.value)}
value={participantInput}
/> />
<button onClick={createParticipant}>Create</button> <button type="submit">
<FontAwesomeIcon icon={faArrowTurnDown} className="rotate-90 mr-2" />
{action}
</button>
</form>
{participants.loading && ( {participants.loading && (
<FontAwesomeIcon <FontAwesomeIcon
icon={faSpinner} icon={faSpinner}
@@ -91,17 +205,41 @@ const ParticipantList = ({
{participants.response && ( {participants.response && (
<ul> <ul>
{participants.response.map((participant: Participant) => ( {participants.response.map((participant: Participant) => (
<li className="flex flex-row justify-between" key={participant.id}> <li
<span>{participant.name}</span> onClick={selectParticipant(participant)}
<div>
<button
className={ className={
selectedTime && !loading ? "bg-blue-400" : "bg-gray-400" "flex flex-row justify-between " +
(participantInput.length > 0 &&
selectedTime &&
participant.name.startsWith(participantInput)
? "bg-blue-100 "
: "") +
(participant.speaker == selectedSpeaker
? "border-blue-400 border"
: "")
} }
onClick={assignTo(participant)} key={participant.id}
> >
<span>{participant.name}</span>
<div>
{selectedTime && !loading && (
<button onClick={assignTo(participant)}>
{oneMatch &&
participant.name.startsWith(participantInput) && (
<>
{" "}
<span>CTRL + </span>{" "}
<FontAwesomeIcon
icon={faArrowTurnDown}
className="rotate-90 mr-2"
/>{" "}
</>
)}{" "}
Assign Assign
</button> </button>
)}
<button onClick={deleteParticipant(participant.id)}> <button onClick={deleteParticipant(participant.id)}>
Delete Delete
</button> </button>

View File

@@ -97,6 +97,7 @@ const topicWords = ({
) { ) {
setSelectedSpeaker(focusNode.parentElement?.dataset["speaker"]); setSelectedSpeaker(focusNode.parentElement?.dataset["speaker"]);
setSelectedTime(undefined); setSelectedTime(undefined);
selection.empty();
console.log("Unset Time : selected Speaker"); console.log("Unset Time : selected Speaker");
return; return;
} }
@@ -111,9 +112,7 @@ const topicWords = ({
selection.focusNode.parentElement?.parentElement selection.focusNode.parentElement?.parentElement
?.previousElementSibling?.lastElementChild as any ?.previousElementSibling?.lastElementChild as any
)?.dataset["end"]; )?.dataset["end"];
const reverse = parseFloat(anchorStart) > parseFloat(focusEnd);
const reverse = anchorStart > focusEnd;
setSelectedTime(undefined);
if (!reverse) { if (!reverse) {
setSelectedTime({ start: anchorStart, end: focusEnd }); setSelectedTime({ start: anchorStart, end: focusEnd });

View File

@@ -8,11 +8,11 @@ import { shouldShowError } from "../../lib/errorUtils";
type ErrorParticipants = { type ErrorParticipants = {
error: Error; error: Error;
loading: false; loading: false;
response: any; response: null;
}; };
type LoadingParticipants = { type LoadingParticipants = {
response: any; response: Participant[] | null;
loading: true; loading: true;
error: false; error: false;
}; };
@@ -30,7 +30,7 @@ export type UseParticipants = (
) & { refetch: () => void }; ) & { refetch: () => void };
const useParticipants = (transcriptId: string): UseParticipants => { const useParticipants = (transcriptId: string): UseParticipants => {
const [response, setResponse] = useState<GetTranscript | null>(null); const [response, setResponse] = useState<Participant[] | null>(null);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [error, setErrorState] = useState<Error | null>(null); const [error, setErrorState] = useState<Error | null>(null);
const { setError } = useError(); const { setError } = useError();