feat: отметки «@» в чате заявки и письма через поток Power Automate
В поле ввода чата «@» открывает подсказку с участниками заявки (инициатор и все из маршрута). Отметка — обычный текст «@ФИО», без штатного упоминания SharePoint, чтобы не уходило его собственное письмо. После отправки сообщения портал вызывает поток FLOW_CHAT_NOTIFY_URL: отмеченным — «Вас упомянули», инициатору — «Новое сообщение по вашей заявке». О своих сообщениях писем нет; для проверки это включается свойством веб-части «Чат: уведомлять о своих сообщениях» (по умолчанию выключено) — тогда же можно отметить себя. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
buildParticipants,
|
||||
extractMentionedEmails,
|
||||
filterParticipants,
|
||||
findMentionQuery,
|
||||
insertMention
|
||||
} from './chatMentions';
|
||||
|
||||
const ivanov = { name: 'Иван Иванов', email: 'ivanov@tnsu.kz' };
|
||||
const petrova = { name: 'Анна Петрова', email: 'petrova@tnsu.kz' };
|
||||
|
||||
describe('buildParticipants', () => {
|
||||
it('убирает повторы, пустые адреса и самого пишущего', () => {
|
||||
const result = buildParticipants(
|
||||
[ivanov, { name: 'Иван Иванов', email: 'IVANOV@tnsu.kz' }, { name: 'Без почты', email: '' }, undefined, petrova],
|
||||
'petrova@tnsu.kz'
|
||||
);
|
||||
expect(result).toEqual([ivanov]);
|
||||
});
|
||||
|
||||
it('без ФИО показывает почту', () => {
|
||||
expect(buildParticipants([{ email: 'x@tnsu.kz' }], '')).toEqual([{ name: 'x@tnsu.kz', email: 'x@tnsu.kz' }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findMentionQuery', () => {
|
||||
it('находит отметку в начале и после пробела', () => {
|
||||
expect(findMentionQuery('@Ив', 3)).toEqual({ start: 0, query: 'Ив' });
|
||||
expect(findMentionQuery('Привет @Иван Ив', 15)).toEqual({ start: 7, query: 'Иван Ив' });
|
||||
});
|
||||
|
||||
it('не считает отметкой адрес почты и перенос строки', () => {
|
||||
expect(findMentionQuery('mail@tnsu', 9)).toBeUndefined();
|
||||
expect(findMentionQuery('@Иван\nдалее', 11)).toBeUndefined();
|
||||
expect(findMentionQuery('без отметки', 5)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterParticipants', () => {
|
||||
it('ищет по началу слов ФИО и по почте', () => {
|
||||
expect(filterParticipants([ivanov, petrova], 'пет')).toEqual([petrova]);
|
||||
expect(filterParticipants([ivanov, petrova], 'иван ив')).toEqual([ivanov]);
|
||||
expect(filterParticipants([ivanov, petrova], 'petrova@')).toEqual([petrova]);
|
||||
expect(filterParticipants([ivanov, petrova], '')).toEqual([ivanov, petrova]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertMention', () => {
|
||||
it('заменяет набранное на ФИО и ставит курсор за пробелом', () => {
|
||||
const text = 'Привет @Ив, глянь';
|
||||
const result = insertMention(text, { start: 7, query: 'Ив' }, 10, ivanov);
|
||||
expect(result.text).toBe('Привет @Иван Иванов , глянь');
|
||||
expect(result.caret).toBe('Привет @Иван Иванов '.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractMentionedEmails', () => {
|
||||
it('берёт отметки из текста без повторов', () => {
|
||||
expect(extractMentionedEmails('@Иван Иванов и @Анна Петрова, @Иван Иванов', [ivanov, petrova])).toEqual([
|
||||
'ivanov@tnsu.kz',
|
||||
'petrova@tnsu.kz'
|
||||
]);
|
||||
});
|
||||
|
||||
it('стёртая отметка не считается, короткое ФИО не цепляется за длинное', () => {
|
||||
const ivan = { name: 'Иван', email: 'ivan@tnsu.kz' };
|
||||
expect(extractMentionedEmails('@Иван Иванов, привет', [ivan, ivanov])).toEqual(['ivanov@tnsu.kz']);
|
||||
expect(extractMentionedEmails('Иван Иванов, привет', [ivanov])).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user