mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-21 04:39: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 [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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 });
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user