Files
stroy-bot-monorepo/src/webparts/stroyBot/pages/binder/BinderPage.module.scss
T
Тимур Городецкий 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

248 lines
4.0 KiB
SCSS

@import '../../../../styles/design-tokens';
// Толщина акцентных полос карточек — как в binder.
$accent-bar-width: 3px;
$accent-line-height: 2px;
// На самых узких экранах карточки компактнее — точка перелома из binder (между $bp-xs и $bp-sm).
$compact-card-bp: 480px;
.page {
display: flex;
flex-direction: column;
gap: $sp-4;
width: 100%;
}
.dismissibleAlert {
display: flex;
align-items: flex-start;
gap: $sp-2;
}
.dismissibleAlertBody {
flex: 1;
min-width: 0;
}
.hairline {
@include hairline;
margin: 0;
}
// ---- Карточка проекта SharePoint ----
.projectCard {
position: relative;
overflow: hidden;
width: 100%;
box-sizing: border-box;
padding: $sp-6 $sp-7;
background: $white;
border: 1px solid $gray-200;
border-radius: $r-lg;
box-shadow: $sh-2;
// Navy-линия сверху.
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: $accent-line-height;
background: linear-gradient(90deg, $navy-800, $navy-600 60%, transparent);
}
// Золотая полоса слева.
&::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: $accent-bar-width;
background: $grad-gold-v;
}
}
.projectTitle {
margin: 0;
font-family: $font-serif;
font-size: $fs-form-title;
font-weight: 600;
color: $navy-900;
overflow-wrap: break-word;
}
.projectFields {
display: grid;
grid-template-columns: 1fr 1fr;
gap: $sp-1 $sp-4;
margin-top: $sp-3;
}
.fieldLine {
min-width: 0;
font-size: $fs-label;
color: $gray-500;
overflow-wrap: break-word;
word-break: break-word;
}
.fieldLabel {
font-weight: 600;
color: $gray-700;
}
.bindingRow {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: $sp-2;
margin-top: $sp-3;
padding-top: $sp-3;
border-top: 1px solid $gray-200;
}
.boundInfo {
flex: 1;
min-width: 0;
font-size: $fs-label;
color: $gray-500;
overflow-wrap: break-word;
word-break: break-word;
}
.unbindAction {
margin-top: $sp-2;
}
// ---- Поиск по справочнику ----
.sectionTitle {
margin: 0;
font-family: $font-serif;
font-size: $fs-section-title;
font-weight: 600;
color: $navy-900;
}
.searchBox {
display: flex;
align-items: center;
gap: $sp-1;
}
.searchInput {
flex: 1;
min-width: 0;
}
.emptyResults {
display: block;
padding: $sp-4 0;
font-size: $fs-label;
text-align: center;
color: $gray-400;
}
.results {
display: flex;
flex-direction: column;
gap: $sp-2;
}
.resultItem {
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
gap: $sp-1;
width: 100%;
box-sizing: border-box;
padding: $sp-3 $sp-4;
background: $white;
border: 1px solid $gray-200;
border-radius: $r-md;
box-shadow: $sh-1;
cursor: pointer;
transition: 0.22s;
&::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: $accent-bar-width;
background: $grad-gold-v;
opacity: 0;
transition: 0.22s;
}
&:hover {
box-shadow: $sh-3;
transform: translateY(-2px);
border-color: transparent;
&::before {
opacity: 1;
}
}
}
.resultItemSelected {
background: $gold-50;
border-color: $gold-400;
&::before {
opacity: 1;
}
&:hover {
background: $gold-50;
border-color: $gold-400;
}
}
.resultName {
font-size: $fs-body;
font-weight: 600;
color: $navy-900;
overflow-wrap: break-word;
word-break: break-word;
}
.bindAction {
margin-top: $sp-1;
}
.pagination {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: $sp-2;
}
.pageInfo {
font-size: $fs-label;
color: $gray-500;
}
@include below($bp-sm) {
.projectFields {
grid-template-columns: 1fr;
}
}
@include below($compact-card-bp) {
.projectCard {
padding: $sp-3 $sp-4;
}
.resultItem {
padding: $sp-2 $sp-3;
}
}