feat: чат по заявке — только в обходном листе, лимит файлов до 20
Остальным восьми типам заявок чат пока не нужен: сужаем область до одной формы (isChatEnabledFor), не включая сразу везде. Лимит файлов на сообщение поднят с 5 до 20 — пяти оказалось мало для реальной переписки по обходному листу.
This commit is contained in:
@@ -3,7 +3,7 @@ import type { WebPartContext } from '@microsoft/sp-webpart-base';
|
|||||||
import styles from './ApproveFeature.module.scss';
|
import styles from './ApproveFeature.module.scss';
|
||||||
import { getViewComponent } from '../../forms/viewRegistry';
|
import { getViewComponent } from '../../forms/viewRegistry';
|
||||||
import { isConfirmedStaleListId } from '../../shared/approval';
|
import { isConfirmedStaleListId } from '../../shared/approval';
|
||||||
import { RequestChat } from '../../shared/chat';
|
import { RequestChat, isChatEnabledFor } from '../../shared/chat';
|
||||||
|
|
||||||
export interface IApproveFeatureProps {
|
export interface IApproveFeatureProps {
|
||||||
context: WebPartContext;
|
context: WebPartContext;
|
||||||
@@ -44,8 +44,11 @@ const ApproveFeature: React.FC<IApproveFeatureProps> = ({ context, formKey, item
|
|||||||
</React.Suspense>
|
</React.Suspense>
|
||||||
{/* Доступно всем, кто может открыть заявку: автору, всем согласующим
|
{/* Доступно всем, кто может открыть заявку: автору, всем согласующим
|
||||||
(и уже решившим, и ещё ждущим своей очереди) и исполнителям —
|
(и уже решившим, и ещё ждущим своей очереди) и исполнителям —
|
||||||
в отличие от панели решения, которая видна только текущему шагу. */}
|
в отличие от панели решения, которая видна только текущему шагу.
|
||||||
|
Пока включено только для «Обходного листа» — см. isChatEnabledFor. */}
|
||||||
|
{isChatEnabledFor(formKey) && (
|
||||||
<RequestChat context={context} formKey={formKey} itemId={itemId} listId={listId} />
|
<RequestChat context={context} formKey={formKey} itemId={itemId} listId={listId} />
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className={styles.state}>Для формы «{formKey}» режим согласования пока не настроен.</div>
|
<div className={styles.state}>Для формы «{formKey}» режим согласования пока не настроен.</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { getFormComponent } from '../../forms/registry';
|
|||||||
import { REQUEST_TYPES } from '../../data/requests';
|
import { REQUEST_TYPES } from '../../data/requests';
|
||||||
import { emitRequestsChanged } from '../../shared/requestEvents';
|
import { emitRequestsChanged } from '../../shared/requestEvents';
|
||||||
import { isConfirmedStaleListId } from '../../shared/approval';
|
import { isConfirmedStaleListId } from '../../shared/approval';
|
||||||
import { RequestChat } from '../../shared/chat';
|
import { RequestChat, isChatEnabledFor } from '../../shared/chat';
|
||||||
|
|
||||||
export interface IEditFeatureProps {
|
export interface IEditFeatureProps {
|
||||||
context: WebPartContext;
|
context: WebPartContext;
|
||||||
@@ -69,8 +69,11 @@ const EditFeature: React.FC<IEditFeatureProps> = ({ context, formKey, itemId, li
|
|||||||
</React.Suspense>
|
</React.Suspense>
|
||||||
{/* Обсуждение — то же самое, что видят согласующие (комментарии к строке
|
{/* Обсуждение — то же самое, что видят согласующие (комментарии к строке
|
||||||
заявки). Здесь оно особенно нужно: заявку правят как раз после
|
заявки). Здесь оно особенно нужно: заявку правят как раз после
|
||||||
возврата на доработку, и уточнить причину логично не уходя с формы. */}
|
возврата на доработку, и уточнить причину логично не уходя с формы.
|
||||||
|
Пока включено только для «Обходного листа» — см. isChatEnabledFor. */}
|
||||||
|
{isChatEnabledFor(formKey) && (
|
||||||
<RequestChat context={context} formKey={formKey} itemId={itemId} listId={listId} />
|
<RequestChat context={context} formKey={formKey} itemId={itemId} listId={listId} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { isChatEnabledFor } from './chatEnabled';
|
||||||
|
|
||||||
|
describe('isChatEnabledFor', () => {
|
||||||
|
it('включён для «Обходного листа»', () => {
|
||||||
|
expect(isChatEnabledFor('clearance-form')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('выключен для остальных типов заявок', () => {
|
||||||
|
expect(isChatEnabledFor('hr-vacation')).toBe(false);
|
||||||
|
expect(isChatEnabledFor('it-1c-ticket')).toBe(false);
|
||||||
|
expect(isChatEnabledFor('recruiting-hire')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('незнакомый ключ — тоже выключен, а не бросает', () => {
|
||||||
|
expect(isChatEnabledFor('что-то-новое')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { RequestTypeId } from '../../models/types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Типы заявок, для которых показывается чат (shared/chat).
|
||||||
|
*
|
||||||
|
* Пилот: только «Обходной лист» (forms/Clearance, FORM_ID = 'clearance-form').
|
||||||
|
* Остальным формам чат пока не нужен — решение сузить область до одного типа,
|
||||||
|
* а не включать сразу на все девять.
|
||||||
|
*
|
||||||
|
* Ключ — строковый литерал, а не импорт FORM_ID из forms/Clearance/model:
|
||||||
|
* shared/* не должен зависеть от forms/* (зависимость идёт в обратную сторону
|
||||||
|
* — формы берут общее из shared), а RequestTypeId — обычная строка, не enum,
|
||||||
|
* так что литерал здесь не менее надёжен, чем в LIST_TITLE_BASE
|
||||||
|
* (shared/listTitles.ts), где тем же приёмом перечислены все типы заявок.
|
||||||
|
*/
|
||||||
|
const CHAT_ENABLED_FORM_IDS: ReadonlySet<RequestTypeId> = new Set<RequestTypeId>(['clearance-form']);
|
||||||
|
|
||||||
|
/** Показывать ли чат по заявке для этого типа. Проверяется ДО монтирования
|
||||||
|
* RequestChat — иначе хук useRequestChat опрашивал бы SharePoint (загрузка +
|
||||||
|
* автообновление раз в 17с) и для заявок, где чат не включён. */
|
||||||
|
export function isChatEnabledFor(formKey: RequestTypeId): boolean {
|
||||||
|
return CHAT_ENABLED_FORM_IDS.has(formKey);
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ import { fileStamp, storedFileName } from './chatFileNames';
|
|||||||
export const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
export const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
||||||
|
|
||||||
/** Сколько файлов можно приложить к одному сообщению. */
|
/** Сколько файлов можно приложить к одному сообщению. */
|
||||||
export const MAX_FILES_PER_MESSAGE = 5;
|
export const MAX_FILES_PER_MESSAGE = 20;
|
||||||
|
|
||||||
// Адрес библиотеки в пределах сессии не меняется, а нужен при каждой загрузке
|
// Адрес библиотеки в пределах сессии не меняется, а нужен при каждой загрузке
|
||||||
// переписки с файлами. Ошибку НЕ кешируем: не отвечавший на холодном старте
|
// переписки с файлами. Ошибку НЕ кешируем: не отвечавший на холодном старте
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Единая точка импорта чата по заявке.
|
// Единая точка импорта чата по заявке.
|
||||||
export { RequestChat } from './ui/RequestChat';
|
export { RequestChat } from './ui/RequestChat';
|
||||||
|
export { isChatEnabledFor } from './chatEnabled';
|
||||||
export { useRequestChat } from './useRequestChat';
|
export { useRequestChat } from './useRequestChat';
|
||||||
export type { IRequestChat } from './useRequestChat';
|
export type { IRequestChat } from './useRequestChat';
|
||||||
export { getChatMessages, addChatMessage } from './requestChat.service';
|
export { getChatMessages, addChatMessage } from './requestChat.service';
|
||||||
|
|||||||
Reference in New Issue
Block a user