mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
fix selection and more assignments
This commit is contained in:
@@ -28,7 +28,6 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
|
||||
|
||||
const [selectedTime, setSelectedTime] = useState<TimeSlice>();
|
||||
const [topicTime, setTopicTime] = useState<TimeSlice>();
|
||||
const api = getApi();
|
||||
const participants = useParticipants(transcriptId);
|
||||
const stateSelectedSpeaker = useState<number>();
|
||||
|
||||
@@ -66,7 +65,13 @@ export default function TranscriptCorrect(details: TranscriptCorrect) {
|
||||
topicTime={topicTime}
|
||||
/>
|
||||
<ParticipantList
|
||||
{...{ transcriptId, participants, selectedTime, topicWithWords }}
|
||||
{...{
|
||||
transcriptId,
|
||||
participants,
|
||||
selectedTime,
|
||||
topicWithWords,
|
||||
stateSelectedSpeaker,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 { useEffect, useRef, useState } from "react";
|
||||
import { Participant } from "../../../../api";
|
||||
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 = ({
|
||||
transcriptId,
|
||||
participants,
|
||||
selectedTime,
|
||||
topicWithWords,
|
||||
}) => {
|
||||
stateSelectedSpeaker,
|
||||
}: ParticipantList) => {
|
||||
const api = getApi();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [participantInput, setParticipantInput] = useState("");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const createParticipant = () => {
|
||||
if (!loading) {
|
||||
setLoading(true);
|
||||
api
|
||||
?.v1TranscriptAddParticipant({
|
||||
createParticipant: { name: participantInput, speaker: 99 },
|
||||
transcriptId,
|
||||
})
|
||||
.then((participant) => {
|
||||
participants.refetch();
|
||||
assignTo(participant)();
|
||||
});
|
||||
}
|
||||
};
|
||||
const [selectedSpeaker, setSelectedSpeaker] = stateSelectedSpeaker;
|
||||
const [action, setAction] = useState<
|
||||
"Create" | "Create to rename" | "Create and assign" | "Rename" | null
|
||||
>(null);
|
||||
const [oneMatch, setOneMatch] = useState<Participant>();
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
@@ -38,10 +39,111 @@ const ParticipantList = ({
|
||||
}, [participants.loading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTime) {
|
||||
if (participants.response) {
|
||||
if (selectedSpeaker !== undefined) {
|
||||
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) => () => {
|
||||
if (!loading) {
|
||||
@@ -75,13 +177,25 @@ const ParticipantList = ({
|
||||
topicWithWords.refetch();
|
||||
});
|
||||
};
|
||||
|
||||
const selectParticipant = (participant) => (e) => {
|
||||
console.log(participant, e);
|
||||
setSelectedSpeaker(participant.speaker);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<form onSubmit={doAction}>
|
||||
<input
|
||||
ref={inputRef}
|
||||
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 && (
|
||||
<FontAwesomeIcon
|
||||
icon={faSpinner}
|
||||
@@ -91,17 +205,41 @@ const ParticipantList = ({
|
||||
{participants.response && (
|
||||
<ul>
|
||||
{participants.response.map((participant: Participant) => (
|
||||
<li className="flex flex-row justify-between" key={participant.id}>
|
||||
<span>{participant.name}</span>
|
||||
<div>
|
||||
<button
|
||||
<li
|
||||
onClick={selectParticipant(participant)}
|
||||
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
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button onClick={deleteParticipant(participant.id)}>
|
||||
Delete
|
||||
</button>
|
||||
|
||||
@@ -97,6 +97,7 @@ const topicWords = ({
|
||||
) {
|
||||
setSelectedSpeaker(focusNode.parentElement?.dataset["speaker"]);
|
||||
setSelectedTime(undefined);
|
||||
selection.empty();
|
||||
console.log("Unset Time : selected Speaker");
|
||||
return;
|
||||
}
|
||||
@@ -111,9 +112,7 @@ const topicWords = ({
|
||||
selection.focusNode.parentElement?.parentElement
|
||||
?.previousElementSibling?.lastElementChild as any
|
||||
)?.dataset["end"];
|
||||
|
||||
const reverse = anchorStart > focusEnd;
|
||||
setSelectedTime(undefined);
|
||||
const reverse = parseFloat(anchorStart) > parseFloat(focusEnd);
|
||||
|
||||
if (!reverse) {
|
||||
setSelectedTime({ start: anchorStart, end: focusEnd });
|
||||
|
||||
@@ -8,11 +8,11 @@ import { shouldShowError } from "../../lib/errorUtils";
|
||||
type ErrorParticipants = {
|
||||
error: Error;
|
||||
loading: false;
|
||||
response: any;
|
||||
response: null;
|
||||
};
|
||||
|
||||
type LoadingParticipants = {
|
||||
response: any;
|
||||
response: Participant[] | null;
|
||||
loading: true;
|
||||
error: false;
|
||||
};
|
||||
@@ -30,7 +30,7 @@ export type UseParticipants = (
|
||||
) & { refetch: () => void };
|
||||
|
||||
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 [error, setErrorState] = useState<Error | null>(null);
|
||||
const { setError } = useError();
|
||||
|
||||
Reference in New Issue
Block a user