Чат заявки: отметки «@» и оповещения через поток (#26)
Tests / frontend-test (push) Successful in 2m1s
Tests / frontend-test (push) Successful in 2m1s
## Что сделано **Чат заявки: отметки и оповещения** - В поле ввода «@» открывает подсказку с участниками заявки: инициатор, согласующие и исполнители из маршрута, а также те, кому открыты «Все заявки» этого типа (список из request-type-access). - Отметка — обычный текст «@ФИО», без штатного упоминания SharePoint, чтобы не уходило его письмо. - После отправки сообщения портал вызывает поток Power Automate (`FLOW_CHAT_NOTIFY_URL`): отмеченным — «Вас упомянули», инициатору — «Новое сообщение по вашей заявке». Сбой потока не мешает отправке. - В письмо добавляется строка «Прикреплены файлы: …», чтобы сообщение из одного файла не приходило пустым. - Свойство веб-части «Чат: уведомлять о своих сообщениях (для теста)», по умолчанию выключено: письма и о своих сообщениях, можно отметить себя. - Когда пишет сам инициатор с отметками, в `initiatorEmail` уходит первый отмеченный — поток шлёт инициатору всегда, если его нет среди отмеченных, и иначе он получил бы письмо о своём же сообщении. **Чат включён для:** Обходной лист, заявка на подбор, заявка на приём, заявка в отдел 1С. **Исправление:** редактор маршрута может удалять исполнителей в Обходном листе, Командировке и заявке в 1С (не передавалось `canRemoveRow`). **Прочее:** убраны 4 предупреждения линтера (`no-new-null`, `no-script-url`). ## Не проверено на тенанте - Ответ потока 200 через AadHttpClient и доставка писем. - Права согласующих на комментарии и на запись в библиотеку «Файлы чата». - Папки в «Файлы чата» наследуют права библиотеки, а не закрыты на заявку — для подбора и приёма это важно решить до выкладки. - Если поток вставляет `messageText` в HTML-письмо, перенос строки перед «Прикреплены файлы» может не отобразиться. --------- Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/26
This commit was merged in pull request #26.
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