ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: корректная обработка русских Voice Tasker задач

This commit is contained in:
DCCONSTRUCTIONS
2026-04-26 14:35:16 +03:00
parent 8b230d2670
commit ee8b5123d8
3 changed files with 258 additions and 45 deletions
@@ -98,6 +98,23 @@ function getVoiceTaskWarnings(result: TVoiceTaskUploadResult) {
);
}
type TVoiceTaskResolutionWithAssignees = NonNullable<TVoiceTaskUploadResult["resolution"]> & {
assignees?: NonNullable<TVoiceTaskUploadResult["resolution"]>["assignee"][];
};
function getVoiceTaskAssigneesLabel(result: TVoiceTaskUploadResult) {
const resolution = result.resolution as TVoiceTaskResolutionWithAssignees | undefined;
const resolvedAssignees = resolution?.assignees?.length
? resolution.assignees
: resolution?.assignee
? [resolution.assignee]
: [];
if (resolvedAssignees.length > 0)
return resolvedAssignees.flatMap((assignee) => (assignee ? [assignee.name] : [])).join(", ");
return result.draft?.assignee_hint || "не распознано";
}
type Props = {
workspaceSlug: string;
};
@@ -310,34 +327,31 @@ export function VoiceTaskerGlobalControl({ workspaceSlug }: Props) {
}
};
const refreshVisibleIssueStores = useCallback(
async () => {
const refreshes: Promise<unknown>[] = [];
const refreshVisibleIssueStores = useCallback(async () => {
const refreshes: Promise<unknown>[] = [];
if (activeProjectId) {
refreshes.push(refreshProjectIssues(workspaceSlug, activeProjectId, "mutation"));
if (activeProjectViewId) {
refreshes.push(refreshProjectViewIssues(workspaceSlug, activeProjectId, activeProjectViewId, "mutation"));
}
if (activeProjectId) {
refreshes.push(refreshProjectIssues(workspaceSlug, activeProjectId, "mutation"));
if (activeProjectViewId) {
refreshes.push(refreshProjectViewIssues(workspaceSlug, activeProjectId, activeProjectViewId, "mutation"));
}
}
if (activeGlobalViewId) {
refreshes.push(refreshGlobalIssues(workspaceSlug, activeGlobalViewId, "mutation"));
}
if (activeGlobalViewId) {
refreshes.push(refreshGlobalIssues(workspaceSlug, activeGlobalViewId, "mutation"));
}
if (!refreshes.length) return;
await Promise.allSettled(refreshes);
},
[
activeGlobalViewId,
activeProjectId,
activeProjectViewId,
refreshGlobalIssues,
refreshProjectIssues,
refreshProjectViewIssues,
workspaceSlug,
]
);
if (!refreshes.length) return;
await Promise.allSettled(refreshes);
}, [
activeGlobalViewId,
activeProjectId,
activeProjectViewId,
refreshGlobalIssues,
refreshProjectIssues,
refreshProjectViewIssues,
workspaceSlug,
]);
const commitVoiceTask = async () => {
if (!parseResult?.voice_session_id || !parseResult.draft) return;
@@ -389,7 +403,7 @@ export function VoiceTaskerGlobalControl({ workspaceSlug }: Props) {
<button
type="button"
className={cn(
"pointer-events-auto flex size-11 items-center justify-center border-0 bg-transparent p-0 shadow-none outline-none transition",
"pointer-events-auto flex size-11 items-center justify-center border-0 bg-transparent p-0 shadow-none transition outline-none",
isAvailable
? "text-[rgb(var(--nodedc-accent-rgb))] hover:text-[rgb(var(--nodedc-card-active-rgb))]"
: "cursor-not-allowed text-tertiary"
@@ -456,7 +470,7 @@ export function VoiceTaskerGlobalControl({ workspaceSlug }: Props) {
{parseResult.transcript && (
<div>
<div className="text-11 font-medium text-tertiary uppercase">Транскрипт</div>
<p className="mt-1 whitespace-pre-wrap break-words text-12 leading-5 text-secondary">
<p className="mt-1 text-12 leading-5 break-words whitespace-pre-wrap text-secondary">
{parseResult.transcript}
</p>
</div>
@@ -504,9 +518,7 @@ export function VoiceTaskerGlobalControl({ workspaceSlug }: Props) {
</div>
<div>
<div className="text-11 font-medium text-tertiary uppercase">Исполнитель</div>
<div className="mt-0.5 text-primary">
{parseResult.resolution?.assignee?.name || parseResult.draft.assignee_hint || "не распознано"}
</div>
<div className="mt-0.5 text-primary">{getVoiceTaskAssigneesLabel(parseResult)}</div>
</div>
<div>
<div className="text-11 font-medium text-tertiary uppercase">Срок</div>
@@ -524,7 +536,7 @@ export function VoiceTaskerGlobalControl({ workspaceSlug }: Props) {
{parseResult.draft.description && (
<div>
<div className="text-11 font-medium text-tertiary uppercase">Описание</div>
<p className="mt-1 whitespace-pre-wrap break-words text-12 leading-5 text-secondary">
<p className="mt-1 text-12 leading-5 break-words whitespace-pre-wrap text-secondary">
{parseResult.draft.description}
</p>
</div>