Skip to content

«Вибрати всі» там, где отмечали по одному: каталог методик с действиями над отмеченными, админы групп, права ролей, отзыв доступа - #226

Merged
4booser merged 8 commits into
mainfrom
select-all
Oct 25, 2026

Conversation

@4booser

@4booser 4booser commented Oct 25, 2026

Copy link
Copy Markdown
Owner

Там, где приходилось отмечать или добавлять по одному, появились «Вибрати всі» и действия над отмеченными.

Каталог методик

  • Отметка строк. Галочка у каждой строки и «выбрать все» в шапке таблицы. Клавиша X отмечает строку.
  • «Вибрати всі N». Отмечает весь вид каталога, а не только страницу: вкладку с её папкой, поиском, группой и направлением. При листании отметка сохраняется, при смене вкладки сбрасывается.
  • Действия над отмеченными:
    • «Призначити». Одним ящиком: людям поимённо или группе пациентов. Методики, которые заполняет фахівець, не назначаются, и ящик называет, сколько таких.
    • «Перемістити». В группу и папку за один шаг. Так методики «поза групами» отдаются отделению. По каждой методике делаются только нужные шаги: смена группы правкой, папка переносом.
    • «Зняти з використання». Окно со списком методик, наборами, где они стоят шагом, и числом прохождений, которые остаются на месте. Подтверждение — набрать число снимаемых. Одну отмеченную методику снимает прежнее окно с подтверждением кодом.
    • «Повернути в роботу» на вкладке снятых.
  • Отказ по одной методике не отменяет остальных. Не прошедшие остаются в ящике поимённо, с причиной.

Другие экраны

Экран Было Стало
Група пацієнтів → «Додати пацієнта» Кнопка у каждого найденного «Додати всіх (N)»: одним запросом всех показанных, кого в группе нет
Ящик «Призначити» Найденный человек добавлялся по одному «Додати всіх знайдених (N)»
Групи методик → адміністратори Список с одним выбором и «Додати», по одному Ящик с галочками, поиском и «Вибрати всіх». Нужен, чтобы раздать группу «Каталог методик» всем врачам
Права → матриця ролей Каждое право отдельным нажатием Галочка в строке раздела ставит или снимает все показанные права раздела у роли
Методика → Доступ «Відкликати» в каждой строке Отметка строк и «Відкликати» для отмеченных
Набір → призначення «Відкликати» в каждой строке Отметка строк и «Відкликати». Пройденные не трогаются
Запрошення «Відкликати» в каждой строке Отметка строк и «Відкликати». Отзываются только действующие
Нормы методики Перемикач «Перевести» у каждой шкалы Галочка «Усі шкали, яким вистачає вибірки»
Конструктор → ключ шкали Номер пункта набирался по одному Одной строкой: «5», «1-35», «1-10, 15, 20»
Пошук по записах Чтобы оставить одного автора, снимали остальных по одному «Усі» над авторами и видами записей
Статистика → питання моделі Варианты ответа по одному «Усі / Жодної», как у смуг шкалы

Чего нет и почему

  • Массовая работа с сигналами риска и подсказками решений. Каждый случай разбирается отдельно: у разбора есть исход и заметка, а подсказка — клиническое решение.
  • Отвергнутые сдачи в офлайн-очереди мобилки. Разбираются поштучно: у каждой своя причина отказа.
  • Аудитория флагов. Её «всем» уже даёт переключатель «Усім».

Как устроено

  • Без новых маршрутов. Действие над отмеченными идёт по одному запросу на запись (eachOf в ui/action.ts), и каждая запись пишется в журнал как раньше. Пачкой ходит только добавление в группу пациентов, у него свой маршрут.
  • Подпись «Вибрати всі». У вещей, например методик, — «Вибрати всі N», у людей по-прежнему «Вибрати всіх N».

Проверки

  • Юнит-тесты:
    • план переноса (смена группы, затем папка, без лишних шагов);
    • «по одному, отказ не обрывает остальных»;
    • разбор номеров ключа: перечни, диапазоны, границы;
    • «Усі / Жодної» у вариантов ответа.
  • Web: 2066 тестов; shared: 249. Typecheck web, test и mobile, lint — проходят.
  • e2e (локально): визуальные эталоны, a11y, экраны, конструктор, клавиши, витрина.
  • Эталон экрана каталога переснят под колонку отметок: macOS локально, Linux в e2e-linux.compose.yml. Ответы API не менялись.

…ми над отмеченными, админы групп, права ролей, отзыв доступа, наборов и приглашений

Каталог методик: отметка строк, «Вибрати всі N» по всему виду каталога, а не странице; над отмеченными — «Призначити», «Перемістити» в группу и папку, «Зняти з використання» (окно со списком и подтверждением числом) и «Повернути в роботу». Отказ по одной методике не отменяет остальных (eachOf в ui/action.ts).

Там же, где добавляли и снимали по одному:
- группа пациентов: «Додати всіх» найденных одним запросом;
- ящик «Призначити»: «Додати всіх знайдених»;
- админы группы методик: ящик с галочками и «Вибрати всіх» вместо селекта на одного;
- матрица прав: галочка раздела у роли ставит или снимает все его показанные права;
- доступ к методике, назначения набора, приглашения: отметка строк и «Відкликати» отмеченным;
- нормы: все шкалы, которым хватает выборки;
- ключ шкалы: номера перечнем и диапазоном («1-35, 41»);
- поиск по записям: «Усі» над авторами и видами;
- статистика: «Усі / Жодної» у вариантов ответа.

Эталон экрана каталога переснят под колонку отметок (macOS).
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T14:48:11.024754Z 640f881 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4f54c396a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1337 to +1339
assignOne={async (userId, due, note) => {
for (const s of assignable) await api.grant(s.id, userId, note ?? undefined, due);
}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Continue bulk assignment after an individual survey fails

If one selected survey is retired or becomes inaccessible after selection, its grant request rejects and this loop skips every subsequent survey for that patient. AssignRecipients catches failures per patient, not per survey, so it reports the patient as wholly unsuccessful even when earlier grants succeeded and provides no indication of which surveys were omitted. The group-assignment loop below has the same problem. Track outcomes per survey and continue after individual failures so one rejected methodology does not prevent the remaining assignments.

Useful? React with 👍 / 👎.

Comment on lines +280 to +282
const plan = movePlan(s, groupId, folderId || null);
if (plan.group) await api.updateSurvey(s.id, { groupId });
if (plan.folder) await api.moveSurvey(s.id, folderId || null);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update retained survey state after a partially completed move

When the group PATCH succeeds but the folder request fails, the survey has already moved to the new group's root, yet left and the parent selection retain its original group and folder. Subsequent attempts compute movePlan from that obsolete state. For example, choosing the original group and root to recover can disable submission as an apparent no-op, or report success without actually restoring the group. Record the successful group change in the retained item, or reload failed items before allowing another move.

Useful? React with 👍 / 👎.

Comment thread apps/web/src/pages/constructor/model.ts Outdated
Comment on lines +607 to +608
for (const part of raw.split(/[\s,;]+/)) {
const m = /^(\d+)(?:[-–—](\d+))?$/.exec(part);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize whitespace around range separators before splitting

When a clinician pastes a range containing spaces, such as 1 – 10, splitting on whitespace first turns it into three tokens and silently adds only items 1 and 10. This produces an incomplete scoring key rather than the requested range, and the missing intermediate entries can change calculated scores without making the key structurally invalid. Normalize spaces around supported dashes before tokenization, or reject the malformed range explicitly instead of accepting its endpoints.

Useful? React with 👍 / 👎.

…еноса — от нового места, номера ключа — без молчаливых потерь

- «Призначити» отмеченным: отказ по одной методике больше не обрывает остальные для того же человека или группы; не прошедшие называются кодом и причиной. Ящик печатает причину отказа рядом с именем (assignEach отдаёт её по id).
- «Перемістити» отмеченные: если группа сменилась, а папка нет, повтор считается от корня новой группы; каталог перечитывается и в этом случае, а строки отмеченных берутся свежими из него.
- Ключ шкалы: «1 – 10» с пробелами — диапазон, а не два номера; неразобранное не добавляется вовсе — поле остаётся открытым и называет, что не так; номер за концом методики не отбрасывается, а показывается янтарём, как набранный по одному.
@4booser

4booser commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0b1cfeff84

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/pages/constructor/model.ts Outdated
Comment on lines +620 to +624
if (!m || from < 1 || to - from >= 1000) {
bad.push(token);
continue;
}
for (let n = from; n <= to; n++) out.add(n);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject unsafe integers before expanding item ranges

If a pasted item number is 9007199254740992 or larger, it can pass the current validation but make this loop run forever: JavaScript cannot reliably increment integers beyond its safe-integer limit, so n++ leaves n unchanged. Since parsing runs synchronously on Enter or blur, this freezes the constructor tab and can lose unsaved edits. Validate both endpoints with Number.isSafeInteger before expanding the range and return unsupported numbers in bad.

Useful? React with 👍 / 👎.

…целых разбор диапазона висел вечно и вешал вкладку конструктора (замечание ревью)
@4booser

4booser commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3cf9c150f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +692 to +696
const assignEachSurvey = async (act: (s: SurveyListItem) => Promise<unknown>) => {
const { failed } = await eachOf(assignable, act);
if (!failed.length) return;
const list = failed.map((f) => `${splitCode(f.item.title).code ?? f.item.title}${f.reason ? `: ${f.reason}` : ""}`).join("; ");
throw new Error(ut(failed.length < assignable.length ? "mc.assignManyPartly" : "mc.assignManyNone").replace("{list}", list));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Retry only failed survey assignments for each recipient

When one survey assignment fails after another succeeds, the drawer retains the recipient, but retrying runs every survey in assignable again. These requests are not idempotent even with the same deadline: apps/api/src/lib/grantAccess.ts resets grantedAt and attemptsUsed on every re-grant. If the patient completes the successful survey before the clinician retries the failed one, that retry grants another attempt and moves the existing response outside the current grant's attempt-counting window. Track successful recipient–survey pairs and retry only failed pairs; the group-assignment path needs the same protection.

Useful? React with 👍 / 👎.

…т × методика» — повторная выдача обнуляет счёт попыток, и пройденная между попытками методика получила бы ещё одну (замечание ревью)
@4booser

4booser commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 97de41b8ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +702 to +705
const of = assignable.map((s) => s.id).join(",");
if (assigned.current.of !== of) assigned.current = { of, pairs: new Set(), recipients: new Map() };
const { failed } = await assignPending(assignable, target, assigned.current.pairs, act);
if (!failed.length) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Expire assignment deduplication after a completed operation

After a bulk assignment succeeds, AssignRecipients resets and closes the drawer, but this cache retains every successful pair until a different survey-ID sequence is submitted. If the clinician subsequently assigns the same selected surveys to the same patient with the same deadline and comment—for example, to authorize another attempt after completion—assignPending skips every request while the drawer still reports success. Reassigning a patient group also skips newly added members in this situation. Scope the successful-pair cache to an unfinished assignment operation, preserving it for partial-failure retries but clearing completed operations.

Useful? React with 👍 / 👎.

…и — адресат, которому дошло всё, забывается, и следующее назначение тем же людям (ещё одна попытка после прохождения, новые участники группы) снова выдаётся (замечание ревью)
@4booser

4booser commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 97f7553b39

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1198 to +1201
onClick={() => {
/* новая операция: пары прошлой, брошенной на полпути, к ней не относятся */
assigned.current = { of: "", pairs: new Set(), recipients: new Map() };
setAssignMany(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve successful pairs when reopening an assignment draft

After a partially successful assignment, closing the drawer and reopening it through the bulk “Assign” button clears the successful-pair cache, so submitting the retained recipient retries surveys that already succeeded. The fresh evidence is that this handler resets assigned.current, while the mounted AssignRecipients preserves its failed recipients, deadline, and comment across closing. As noted in the earlier retry finding, re-granting resets grantedAt and attemptsUsed, potentially authorizing another attempt if the patient completed a successful survey meanwhile. Preserve the cache when resuming that draft; clear it only when the operation completes or the draft is explicitly discarded.

Useful? React with 👍 / 👎.

…— память о прошедших парах живёт вместе с черновиком ящика и стирается, когда адресату дошло всё или ящик снят со страницы, а не при новом нажатии «Призначити» и не при смене набора отмеченных (замечание ревью)
@4booser

4booser commented Oct 25, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 640f8814d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@4booser
4booser merged commit 8b26e45 into main Oct 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant