Commit Graph

35 Commits

Author SHA1 Message Date
Тимур Городецкий 76878c7617 docs: record report fixes and the import test blocker
Import tests wait for an estimate in the catalogue: the API returns
totalCount 0 for every project.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:57 +05:00
Тимур Городецкий f05ee3e854 fix: number a new report after the highest number in the project
Counting non-deleted reports reused numbers (and photo folders) after a
soft delete. Deleted reports are now included.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:57 +05:00
Тимур Городецкий f6af34cb0a fix: send the back link to the reports list when there is no history
Reports open from the list in a new tab, where history.back() did nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:56 +05:00
Тимур Городецкий 40a39cf828 fix: show the approved badge right after approving a report
Previously the badge stayed "На утверждении" until a page reload.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:56 +05:00
Тимур Городецкий ae383b5231 fix: show title, unit and plan for a work created from the picker
The new work was not yet in lookups of the current render, so the card
got the full path, an empty unit and plan 0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:56 +05:00
Тимур Городецкий 33f31366cd fix: center the report picker on wide screens and keep the value field inside its card
The bottom sheet stays for phones only, as in the old picker.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:56 +05:00
Тимур Городецкий f0272c2170 fix: check report access with the user id of the lists site
The user id differs per site, so the id from the page context showed
"Нет доступа" in reports when the page was not on /sites/stroy.
The id and the photo folder path now come from settings.siteUrl.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:17:56 +05:00
Тимур Городецкий cb810972c4 feat: searchable unit picker in the work form
Units dictionary has around a hundred entries; typing now filters the
list and Enter picks the first match. Only dictionary values can be
chosen, as before. Generic SearchableSelect lives in shared until the
ui-kit gets one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 10:07:07 +05:00
Тимур Городецкий 7ca71c6b6c fix: reject work finish date earlier than start date
The legacy works form saved any dates. The finish date picker now has
the start date as minimum and saving shows an error. Found in T-WRK.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 10:07:07 +05:00
Тимур Городецкий 3128190b5c fix: retry AAD client creation after a failed token request
The rejected promise was cached, so a single network hiccup while
getting the Dataverse or API token broke every request to that resource
until the page was reloaded. Seen once in T-OBJ-11.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 10:07:07 +05:00
Тимур Городецкий d2852df976 refactor: remove drag and drop from the objects tree
Decided during manual testing: the legacy drop-inside zone had zero
height, so drops only worked before/after a node and moves happened by
accident. Sections are re-parented via Edit, as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 10:07:06 +05:00
Тимур Городецкий 8ed1a02967 fix: prevent duplicate project resource assignments
With two tabs open (or two users) the same profession or company could
be assigned twice, because only the list loaded in the tab was checked.
Before creating an assignment the server is now asked whether it already
exists; if so its id is reused. Found in T-RES-03.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 12:33:38 +05:00
Тимур Городецкий c69a11d167 feat: add clear button to the project search field
Clears only the search text and reopens the list, the selected project
stays. Requested during manual testing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 12:33:38 +05:00
Тимур Городецкий 45c974d0c6 fix: use fresh project status and rights after reload
After F5 without projectId in the address the hub and sidebar showed the
status and edit right saved in sessionStorage, so a project switched to
Архивный or a revoked edit0 right was ignored until the project was
picked again. The fresh list from SharePoint now always wins; the saved
copy is used only while the list is loading. Found in T-HUB-07/09.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 12:33:38 +05:00
Тимур Городецкий 650bce809a docs: align hub status scenarios with real SharePoint choices
Status choices in the Проекты list are Текущий / Архивный, so the legacy
archive rule matches real data; the projects portal writes its own
status to the API catalogue, which StroyBot does not read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 11:45:04 +05:00
Тимур Городецкий bb7093de20 docs: fix session restore scenario, record ui-kit look decision
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:59:36 +05:00
Тимур Городецкий 355a1300ce docs: record verified SharePoint schema for access and objects lists
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:37:03 +05:00
Тимур Городецкий fad0842640 feat: stretch web part to full canvas width
Enable supportsFullBleed so the web part can sit in full-width sections,
and lift the SharePoint canvas max-width so it also fills a regular
one-column section (workbench and live page).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:14:09 +05:00
Тимур Городецкий 1532017c0b docs: add step-by-step manual test plan
Scenarios per section with expected results, role switching with one
account, side-by-side comparison with the legacy pages and a bug report
template, so the workbench check can be done systematically.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:13:15 +05:00
Тимур Городецкий 92b578d806 feat: wire report form page, remove section placeholder
All eight sections of the old stroy-bot-* web parts are now reachable
from the app. Unknown routes fall back to the hub.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:08:07 +05:00
Тимур Городецкий 072d246eed test: cover report form rules, save order and SharePoint calls
Checked line by line against stroy-bot-report: form modes, validation
texts and order, payloads, delete-children-first then recreate save
sequence, photo upload, access lookup and dictionary fallbacks. The fake
HTTP client can now answer per call so created rows get distinct ids.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 10:08:07 +05:00
Тимур Городецкий 673ace2ba6 feat: port stroy-bot-works as works page
Tree table of an object's works from Dataverse with add / add child /
edit / delete, "save and add more", units dictionary and parent
re-binding, 1:1 with the legacy web part. Reuses the tree widgets from
the objects page; the parent navigation property lookup is cached as a
single promise so concurrent saves don't race.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 09:55:54 +05:00
Тимур Городецкий bfb3eb7b75 wip: add report form page (not wired yet)
Ported stroy-bot-report form saved before tests are written. Not
reachable from the app until save/mode tests cover the delete-and-
recreate algorithm.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 09:48:06 +05:00
Тимур Городецкий e12fce6032 feat: port stroy-bot-objects as objects page
Project object tree with add/edit/delete, drag & drop re-parenting,
context menu and Excel export, 1:1 with the legacy web part. The tree
widgets live in pages/_tree so the works page can reuse them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 09:48:04 +05:00
Тимур Городецкий 99a7631b65 feat: wire reports and import pages into the app
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:58:17 +05:00
Тимур Городецкий 1c568ef81c fix: make HttpError detectable with instanceof
SPFx compiles to ES5, where subclasses of Error lose their prototype, so
`instanceof HttpError` was always false and the hub export showed the
generic message instead of "Ошибка API: {status} {statusText}".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:58:17 +05:00
Тимур Городецкий c41df77c09 feat: port stroy-bot-import-works as import page
Moves estimate work import into the app as ?page=import&projectId=.
Behaviour is kept 1:1 with the legacy web part: project lookup with
UniqueId0 check, project objects query, works paging by 200 with the
progress text, 250 ms debounced search over the same fields, 100 rows
per page, select-all over all filtered not-imported works, duplicate
protection via cree9_comment, the same Dataverse POST body, import into
the selected object and import with object creation (find or create
root and child in «Объекты», cached per pair), toasts and all texts.

The object picker still shows only the first 100 matches (legacy bug).
HTTP-response errors are detected by their status field instead of
instanceof HttpError, which does not survive the ES5 build target.
Deviations are listed in docs/MIGRATION-CHECKLIST.md section 6.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:57:02 +05:00
Тимур Городецкий 704d5ce329 feat: port stroy-bot-report-list as reports page
Moves the project report list into the app as ?page=reports&projectId=.
Behaviour is kept 1:1 with the legacy web part: the same «Доступы» query
(lookup user/Id + project/Id), «Компании»/«Объекты» reference loads,
Dataverse cree9_reports query with the date filter and ordering, client
side sort and search, permission rules for send/copy/delete, soft delete
via PATCH cree9_deleted=true and all user-facing texts.

Known bugs are ported as-is (no Dataverse paging, default week in UTC).
Links to SendReport.aspx now point to the in-app report form route; the
report and copy links still open in a new tab. Deviations are listed in
docs/MIGRATION-CHECKLIST.md section 4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:57:02 +05:00
Тимур Городецкий 660e059842 feat: wire resources and binder pages into the app
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:47:22 +05:00
Тимур Городецкий e7527081b4 feat: port stroy-bot-projects-binder as binder page
Add the "binder" section (?page=binder&projectId=): links a SharePoint
project to the TNSU API project catalogue by writing UniqueId0/UniqueName
to the "Проекты" list.

The class component is rewritten as function components with hooks while
keeping the legacy behaviour and texts: the same project GET with
odata=nometadata and empty odata-version, MERGE with IF-MATCH * for
bind/unbind (no confirmation), catalogue search with 400 ms debounce and
20-per-page paging, card select/deselect, status colours, ru-RU dates and
HTML-entity decoding of the address. Fluent UI is replaced with ui-kit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:46:08 +05:00
Тимур Городецкий 55ce772eaa feat: port stroy-bot-project-assigner as resources page
Add the "resources" section (?page=resources&projectId=): professions and
companies assigned to a project, with the same lists, fields, texts and
optimistic add/remove with rollback as the legacy web part.

PnPjs is replaced by SharePoint REST through the app's IHttpClient so the
bundle needs no new dependency: the same $select/$expand/$filter, PnP paging
replaced by following odata.nextLink, adds as POST to items with the same
body, deletes as POST with X-HTTP-Method DELETE and IF-MATCH *. Known legacy
edge cases (temporary negative id) are kept and listed in the checklist.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 08:46:08 +05:00
Тимур Городецкий 11bf491095 docs: add porting guide and shared Dataverse helpers
Common rules for moving the remaining stroy-bot-* sections into the
monorepo, so every section follows the same structure and keeps 1:1
behaviour with its old web part.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 16:50:54 +05:00
Тимур Городецкий bed230f045 feat: port stroy-bot-main as the hub page
Project picker, section cards and the period Excel export now live on the
app's home page. The selected project is shared app state, so the sidebar
hides sections with the same rules main used to disable its cards
(archived, finished, no edit0 right).

Queries are 1:1 with stroy-bot-main and covered by tests against a fake
HTTP client. Behaviour differences are listed in the migration checklist.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 16:49:32 +05:00
Тимур Городецкий b868e8012d feat: add StroyBot app shell with URL routing
One web part replaces the separate stroy-bot-* web parts. The section and
its parameters live in the page query string (?page=objects&projectId=5),
so links can be copied, opened in a new tab and the browser Back button works.

- shared config: site/Dataverse/API addresses, list and table names
- HTTP layer behind IHttpClient so repositories can be unit-tested
- ui-kit AppLayout + Sidebar, placeholder for sections not ported yet
- migration checklist with every feature of the old web parts
- design tokens mirrored from ui-kit instead of 8 copies

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 16:42:37 +05:00
Тимур Городецкий 5418da3bdc chore: scaffold SPFx solution with ui-kit
Clean SPFx 1.22 (heft) web part template with @tnsu/ui-kit wired in.
Starting point for merging the stroy-bot-* repositories.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 16:26:15 +05:00