diff --git a/.gitignore b/.gitignore index ab5ea70..25120aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ node_modules/ lib/ +lib-commonjs/ dist/ +release/ +jest-output/ temp/ *.sppkg .heft/ diff --git a/docs/CT-PORT.md b/docs/CT-PORT.md new file mode 100644 index 0000000..927354a --- /dev/null +++ b/docs/CT-PORT.md @@ -0,0 +1,174 @@ +# CT — перенос в ct-forms-portal (Фаза 3) + +Порядок (утверждён): **Этап 1 перенос 1:1 → Этап 2 декомпозиция под структуру KPS → Этап 3 перекраска на ui-kit.** +Правило: сохранить 100% поведения; build после каждого этапа. Эталон структуры — `forms/kps/`. +Связано: `docs/REPAINT-MAP.md` (перекраска), `docs/BEHAVIORS.md`. + +Источник: `ct-create-form/src/webparts/ctCreateForm/`. CT = 6953 стр, god-компоненты. + +## Этап 1 — перенос 1:1 — ✅ ЗАВЕРШЁН (heft build зелёный) +1. ✅ Скопированы `components/` и `services/` → `forms/ct/{components,services}/` (17 файлов, 1:1). +2. ✅ Правки для сборки в портале (минимум, поведение не менялось): + - `CtService`: конструктор `(context, siteUrl?)`, `baseUrl = siteUrl ?? absoluteUrl` (как KPS). + `kpFolder` тоже параметризован через `siteUrl` (было жёстко на `context.pageContext.web.serverRelativeUrl`). + - `ICtCreateFormProps` + `siteUrl?`; `CtCreateForm` → `new CtService(context, siteUrl)`. + - Web-part-специфичных зависимостей (loc strings) в components/services не было — ничего убирать не пришлось. +3. ✅ Обвязка портала: + - `ctDocumentConfig.ts`: `inPortal: true` + `buildInPortalParams: (row) => ({ [row.status==='Черновик'?'ctId':'ctid']: row.id })` + (сверено с `useCtForm.ts` — читает именно `ctId`/`ctid`, совпало 1:1). siteUrl уже `/sites/sed`. + - `CtFormsPortal.tsx`: ветка `form==='ct'` → `` + «← К реестру» (по образцу KPS-ветки). +4. ✅ `heft build` зелёный. + +**Открытие при переносе:** CT уже частично зависел от `@tnsu/ui-kit@^0.4.0` — 3 файла +(`Step1PositionSelection.tsx`, `Step2CommercialOffers.tsx`, `CurrencyRatesForm.tsx`) уже используют +`Button`/`Alert` из кита. API совпадает 1:1 с текущим `0.11.0` (variant="secondary"/"accent", Alert +variant="err") — конфликтов не было, работает как есть. Ускорит Этап 3. + +## Этап 2 — декомпозиция (карта резки god-компонентов) + +**Статус:** [x] Step2CommercialOffers ✅ | [x] Step4Approval ✅ | [~] Step3ComparisonTable (в работе) + +### [~] Step3ComparisonTable (2217) — В РАБОТЕ, по чекпоинтам +- ✅ **CP1 согласование** (build ок): `useStep3Approval.ts` (голосование/делегат, 1:1) + `InlineApprovalChain.tsx` + (вью цепочки + диалоги решение/делегат + баннер notifyWarning; хелперы APPROVAL_STATUS_*). Контейнер 2217→1918. +- ✅ **CP2 AI/PDF** (build ок): `useAiComment.ts` (aiComment/isAiLoading/aiError/isPdfLoading/showAiPromptDialog + + handleAiComment/handleGeneratePdfReport/handleDeleteAiComment + loadCtComment-effect + decodeHtmlEntities, + buildPayload передаётся аргументом из контейнера — матричные данные не копируются в хук) + `AiCommentBlock.tsx` + (только блок отображения, диалог-промпт остался в контейнере — как у KPS). PDF-ошибка идёт через колбэк + `onPdfError` в общий `saveError` (сохранили родной баннер). +- ✅ **CP3 хелперы/типы** (build ок): типы (ExtraSupplier/ExtraPosition/PositionRow/CellEdit/EditableOffers) → + `matrixTypes.ts`; константы (SUPPLIER_STATUS_OPTIONS/DELIVERY_TYPE_OPTIONS) + чистые ф-ции + (formatKzt/Num/Qty/round2Str/getSubCols/computeOffer/buildOfferKey) → `matrixHelpers.ts`. + `extraIdCounter` (мутабельный) оставлен в контейнере — уедет вместе с CP4. +- **Контейнер после CP1-3: 2217 → 1735 строк (−22%).** +- ✅ **CP4 ядро матрицы** (build ок): весь стейт/рефы(~15)/эффекты(loadCriteria/loadOffers/refs-sync/beforeunload/ + unmount-persist)/мемо(suppliersWithOffer/allPositions/supplierCurrencies/computedOffers/minTotalByPosition/ + recommendedSupplierId)/все update*/add*/delete*-хендлеры/handleSave → `useStep3Matrix.ts` (856, перенос + ВЕРБАТИМ). В контейнере — **деструктуризация** результата, поэтому render (984) НЕ менялся. `CriteriaEntry` + переехал в matrixTypes (общий). approval+ai хуки остались в контейнере (берут значения из деструктуризации). +- **Контейнер: 2217 → 984 строки (−56%). Логика матрицы вся в хуке. Этап 2 для CT ЗАВЕРШЁН.** +- ✅ **CP4 happy-path проверен в workbench**: полный проход по всем 4 шагам (создание СТ → загрузка КП → матрица → + согласование) прошёл без ошибок. Основной риск (грубый регресс/краш) снят. + ⚠️ Не проверены детально: bundle-строки (комплект), перевод ед. изм. (тумблер), доп.расходы/логистика, + F5 (beforeunload-persist), критерии/AI-комментарий, делегат/замена в согласовании. Смотреть при случае, + не блокирует дальнейшую работу. +- ⏭️ **CP4 матрица-ядро** (САМЫЙ РИСК): ~15 рефов + эффекты (loadCriteria/loadOffers/beforeunload/unmount-persist) + + мемо (suppliersWithOffer/allPositions/supplierCurrencies/computedOffers/minTotalByPosition/recommendedSupplierId) + + все update*/add*/delete*-хендлеры + handleSave → `useStep3Matrix.ts` (перенос ВЕРБАТИМ, не переписывать!). + ⚠️ Клубок рефов; компилятор не ловит регресс поведения. ЖЕЛАТЕЛЬНО делать при возможности workbench-теста + (после провижининга списков). Рендер таблицы (thead/tbody/итоги/критерии) дробить на ComparisonMatrix/ + MatrixRowView/OfferCells/CriteriaTable/AddExtraRow — на Этапе 3 вместе с перекраской. +Метод: чисто механический перенос блоков (логику не трогать), Fluent оставляем (перекраска — Этап 3), +build после каждого god-компонента. +**Уточнённая граница Этап2/Этап3:** Этап 2 = вынос ЛОГИКИ (хуки/persist), «раз-god-ивание». Финальное +дробление оставшейся ВЬЮХИ на под-компоненты (диалоги/списки) + размеры <200 — на Этапе 3 вместе с +перекраской (диалоги всё равно → ui-kit Dialog), чтобы не трогать файлы дважды. + +### ✅ Step4Approval (886) — СДЕЛАНО (build ок) +886 → `useStep4Approval.ts` (вся логика: chain-ops, add/delete/replace, handleActionConfirm, send/incore/restart, +производные флаги + удобные методы selectAddSuggestion/cancelAddRow/openReplace/…) + view `Step4Approval.tsx` +(~370, только разметка + helpers STATUS_LABELS/getStatusClass/formatDate; Fluent). Вьюху добьём на Этапе 3. + +### ✅ Step2CommercialOffers (597) — СДЕЛАНО (build ок, 2 чекпоинта) +597 → контейнер `Step2CommercialOffers.tsx` (~155) + `kpTypes.ts` + `useKpProcessing.ts` (конвейер Syntex/Flow) ++ `step2Persist.ts` (handleSave→функция, возвращает patch) + вьюхи `SuppliersWithoutKp.tsx` (владеет add-стейтом) +/ `UploadedKpList.tsx`. Одно семантич. уточнение: в persist `formDataRef.current`→`formData` (в момент save совпадают). + + +### Step3ComparisonTable.tsx (2217) → по образцу `Step3BuildCt/*` + отдать approval в Step4 +| Секции CT (строки) | Куда (аналог KPS) | +|---|---| +| 25–179 типы/хелперы/формат | `types/domain.ts`, `utils/format.ts`, `useStep3Matrix.ts` | +| 196–435 стейт матрицы | `useStep3Matrix.ts` | +| 285–394 approval-хендлеры | → Step4 `useStep4Approval.ts` | +| 396–405, 947–1017 AI/PDF | `useAiComment.ts` + `AiCommentBlock.tsx` | +| 439–604 useEffect загрузка/persist | `step3Persist.ts` + `useStep3Matrix.ts` | +| 606–706 useMemo производные | `useStep3Matrix.ts` | +| 708–789 редактируемые ячейки | `OfferCells.tsx` | +| 791–945 хендлеры строк | `AddExtraRow.tsx` + `useStep3Matrix.ts` | +| 1019–1193 handleSave | `step3Persist.ts` | +| 1197–1239 тулбар + тумблер ед.изм. | `Step3BuildCt.tsx` (+ доменное `unitConversion`) | +| 1241–1337 thead | `ComparisonMatrix.tsx` | +| 1339–1806 tbody + итоги | `MatrixRowView.tsx` + `OfferCells.tsx` + `ComparisonMatrix.tsx` | +| 1807–1864 инлайн-добавление | `AddExtraRow.tsx` | +| 1865–2029 критерии + AI + PDF | `CriteriaTable.tsx` + `AiCommentBlock.tsx` | +| 2030–2114 инлайн-цепочка (Teams) | → Step4 `InlineApprovalChain.tsx` | +| 2115–2211 диалоги (делегирование/решение) | ui-kit `Dialog` в `Step4Approval.tsx` | + +### Step4Approval.tsx (886) → `useStep4Approval.ts` + `Step4Approval.tsx` + `InlineApprovalChain.tsx` +(стейт+манипуляции цепочкой 94–352, handleActionConfirm/Send/Incore/Restart 239–474 → хук; render 476–763; диалоги 764–885 → ui-kit Dialog) + +### Step2CommercialOffers.tsx (597) → `useKpProcessing.ts`/`kpPipeline.ts`/`kpOffers.ts`/`step2Persist.ts` + view (`Step2LoadKp`,`KpFileList`,`CurrencyRatesForm`,`SuppliersWithoutKp`,`UploadedKpList`) + +### CtService.ts (1532) — ввести `siteUrl?` (крит.) + при желании обобщённые CRUD-примитивы как в KPS. Создать `common/*` (StepShell/FormHeader/Pill) + единый `StepProps`. + +## Доменные отличия CT (НЕ терять при декомпозиции!) +- Шаг 1 — из **SP-списка** (`fetchRequests(days)`), не из TNSU API (KPS). +- Колонки позиций: **disciplineCode (марка), smrType (SMR), agskCode**, uniqueCode, organization. +- `CT.number` — строковый, `generateCtNumber(projectName)` (per-project). +- `utils/unitConversion.ts` — пересчёт в ед. изм. заявки (тумблер) — нет в KPS. +- `SUPPLIER_STATUS_OPTIONS` (Завод/Дистрибьютор…) — нет в KPS. +- CurrencyRate/SupplierOffer — иные поля (rateToKzt; deliveryCostKzt/additionalCostsKzt/totalWithExtraKzt/pricePerUnitKzt). +- `getCurrentUserCompany()==='astel-k'` → `isRestrictedView` (скрытие цен). + +## Этап 3 — перекраска (карта A/B/C из REPAINT-MAP) +Fluent в CT: PrimaryButton/DefaultButton→Button, TextField→TextInput/TextArea, MessageBar→Alert, +IconButton/Icon, Spinner→Spinner, Dialog→ui-kit Dialog, Checkbox→Checkbox, статусы→Pill/Badge. +Особые: **Toggle** (пересчёт ед.изм.) и **NormalPeoplePicker** (делегирование) — прямых аналогов в ките нет: +Toggle → ui-kit Toggle (есть!); people picker → TextInput + searchUsers()+suggestions (как KPS Step4). + +**✅✅ Этап 3 ЗАВЕРШЁН (механическая перекраска) — Fluent полностью удалён из CT (0 импортов @fluentui +во всей `forms/ct/`), heft build ожидается пользователем.** +- Все 12 файлов с Fluent переведены на `@tnsu/ui-kit`: RequestsTable/FileUploadArea/UploadedKpList + (Checkbox/IconButton), SuppliersWithoutKp/CurrencyRatesForm/Step1PositionSelection/ + Step2CommercialOffers/AiCommentBlock (TextInput/Spinner/Alert/IconButton/FormField), + useStep3Approval/InlineApprovalChain/Step4Approval (делегат/замена — NormalPeoplePicker заменён + на паттерн KPS: query+debounce(300ms)+suggestions+select, `useStep4Approval`/`useStep3Approval` + получили `handleAddQueryChange(val)`/`setDelegateQuery(val)` вместо Fluent-сигнатуры (event, val)), + и главный контейнер `Step3ComparisonTable.tsx` (984 строки, вся матрица/критерии/футер/AI-диалог). +- Правило замен применено: `TextField`→`TextInput`/`TextArea` (multiline→TextArea rows=1, автовысоты + нет — принято как в KPS `CriteriaTable`); без `className`→обёрнуто в `
`; `Toggle` без `label`→ + обёрнут в `
-
- - - - - - - - - \ No newline at end of file diff --git a/jest-output/coverage/prettify.css b/jest-output/coverage/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/jest-output/coverage/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/jest-output/coverage/prettify.js b/jest-output/coverage/prettify.js deleted file mode 100644 index b322523..0000000 --- a/jest-output/coverage/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/jest-output/coverage/sort-arrow-sprite.png b/jest-output/coverage/sort-arrow-sprite.png deleted file mode 100644 index 6ed6831..0000000 Binary files a/jest-output/coverage/sort-arrow-sprite.png and /dev/null differ diff --git a/jest-output/coverage/sorter.js b/jest-output/coverage/sorter.js deleted file mode 100644 index 4ed70ae..0000000 --- a/jest-output/coverage/sorter.js +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - - // Try to create a RegExp from the searchValue. If it fails (invalid regex), - // it will be treated as a plain text search - let searchRegex; - try { - searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive - } catch (error) { - searchRegex = null; - } - - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - let isMatch = false; - - if (searchRegex) { - // If a valid regex was created, use it for matching - isMatch = searchRegex.test(row.textContent); - } else { - // Otherwise, fall back to the original plain text search - isMatch = row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()); - } - - row.style.display = isMatch ? '' : 'none'; - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.js b/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.js deleted file mode 100644 index 0b1c45c..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var tslib_1 = require("tslib"); -var React = tslib_1.__importStar(require("react")); -var ReactDom = tslib_1.__importStar(require("react-dom")); -var sp_core_library_1 = require("@microsoft/sp-core-library"); -var sp_property_pane_1 = require("@microsoft/sp-property-pane"); -var sp_webpart_base_1 = require("@microsoft/sp-webpart-base"); -var strings = tslib_1.__importStar(require("CtFormsPortalWebPartStrings")); -var CtFormsPortal_1 = tslib_1.__importDefault(require("./components/CtFormsPortal")); -var CtFormsPortalWebPart = /** @class */ (function (_super) { - tslib_1.__extends(CtFormsPortalWebPart, _super); - function CtFormsPortalWebPart() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._isDarkTheme = false; - _this._environmentMessage = ''; - return _this; - } - CtFormsPortalWebPart.prototype.render = function () { - var element = React.createElement(CtFormsPortal_1.default, { - description: this.properties.description, - isDarkTheme: this._isDarkTheme, - environmentMessage: this._environmentMessage, - hasTeamsContext: !!this.context.sdks.microsoftTeams, - userDisplayName: this.context.pageContext.user.displayName, - context: this.context - }); - ReactDom.render(element, this.domElement); - }; - CtFormsPortalWebPart.prototype.onInit = function () { - var _this = this; - return this._getEnvironmentMessage().then(function (message) { - _this._environmentMessage = message; - }); - }; - CtFormsPortalWebPart.prototype._getEnvironmentMessage = function () { - var _this = this; - if (!!this.context.sdks.microsoftTeams) { // running in Teams, office.com or Outlook - return this.context.sdks.microsoftTeams.teamsJs.app.getContext() - .then(function (context) { - var environmentMessage = ''; - switch (context.app.host.name) { - case 'Office': // running in Office - environmentMessage = _this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOffice : strings.AppOfficeEnvironment; - break; - case 'Outlook': // running in Outlook - environmentMessage = _this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOutlook : strings.AppOutlookEnvironment; - break; - case 'Teams': // running in Teams - case 'TeamsModern': - environmentMessage = _this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment; - break; - default: - environmentMessage = strings.UnknownEnvironment; - } - return environmentMessage; - }); - } - return Promise.resolve(this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment); - }; - CtFormsPortalWebPart.prototype.onThemeChanged = function (currentTheme) { - if (!currentTheme) { - return; - } - this._isDarkTheme = !!currentTheme.isInverted; - var semanticColors = currentTheme.semanticColors; - if (semanticColors) { - this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null); - this.domElement.style.setProperty('--link', semanticColors.link || null); - this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null); - } - }; - CtFormsPortalWebPart.prototype.onDispose = function () { - ReactDom.unmountComponentAtNode(this.domElement); - }; - Object.defineProperty(CtFormsPortalWebPart.prototype, "dataVersion", { - get: function () { - return sp_core_library_1.Version.parse('1.0'); - }, - enumerable: false, - configurable: true - }); - CtFormsPortalWebPart.prototype.getPropertyPaneConfiguration = function () { - return { - pages: [ - { - header: { - description: strings.PropertyPaneDescription - }, - groups: [ - { - groupName: strings.BasicGroupName, - groupFields: [ - (0, sp_property_pane_1.PropertyPaneTextField)('description', { - label: strings.DescriptionFieldLabel - }) - ] - } - ] - } - ] - }; - }; - return CtFormsPortalWebPart; -}(sp_webpart_base_1.BaseClientSideWebPart)); -exports.default = CtFormsPortalWebPart; -//# sourceMappingURL=CtFormsPortalWebPart.js.map \ No newline at end of file diff --git a/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.js.map b/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.js.map deleted file mode 100644 index ef6426a..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"CtFormsPortalWebPart.js","sourceRoot":"","sources":["../../../src/webparts/ctFormsPortal/CtFormsPortalWebPart.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport * as ReactDom from 'react-dom';\nimport { Version } from '@microsoft/sp-core-library';\nimport {\n type IPropertyPaneConfiguration,\n PropertyPaneTextField\n} from '@microsoft/sp-property-pane';\nimport { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';\nimport { IReadonlyTheme } from '@microsoft/sp-component-base';\n\nimport * as strings from 'CtFormsPortalWebPartStrings';\nimport CtFormsPortal from './components/CtFormsPortal';\nimport { ICtFormsPortalProps } from './components/ICtFormsPortalProps';\n\nexport interface ICtFormsPortalWebPartProps {\n description: string;\n}\n\nexport default class CtFormsPortalWebPart extends BaseClientSideWebPart {\n\n private _isDarkTheme: boolean = false;\n private _environmentMessage: string = '';\n\n public render(): void {\n const element: React.ReactElement = React.createElement(\n CtFormsPortal,\n {\n description: this.properties.description,\n isDarkTheme: this._isDarkTheme,\n environmentMessage: this._environmentMessage,\n hasTeamsContext: !!this.context.sdks.microsoftTeams,\n userDisplayName: this.context.pageContext.user.displayName,\n context: this.context\n }\n );\n\n ReactDom.render(element, this.domElement);\n }\n\n protected onInit(): Promise {\n return this._getEnvironmentMessage().then(message => {\n this._environmentMessage = message;\n });\n }\n\n\n\n private _getEnvironmentMessage(): Promise {\n if (!!this.context.sdks.microsoftTeams) { // running in Teams, office.com or Outlook\n return this.context.sdks.microsoftTeams.teamsJs.app.getContext()\n .then(context => {\n let environmentMessage: string = '';\n switch (context.app.host.name) {\n case 'Office': // running in Office\n environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOffice : strings.AppOfficeEnvironment;\n break;\n case 'Outlook': // running in Outlook\n environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOutlook : strings.AppOutlookEnvironment;\n break;\n case 'Teams': // running in Teams\n case 'TeamsModern':\n environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;\n break;\n default:\n environmentMessage = strings.UnknownEnvironment;\n }\n\n return environmentMessage;\n });\n }\n\n return Promise.resolve(this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment);\n }\n\n protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {\n if (!currentTheme) {\n return;\n }\n\n this._isDarkTheme = !!currentTheme.isInverted;\n const {\n semanticColors\n } = currentTheme;\n\n if (semanticColors) {\n this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null);\n this.domElement.style.setProperty('--link', semanticColors.link || null);\n this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null);\n }\n\n }\n\n protected onDispose(): void {\n ReactDom.unmountComponentAtNode(this.domElement);\n }\n\n protected get dataVersion(): Version {\n return Version.parse('1.0');\n }\n\n protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {\n return {\n pages: [\n {\n header: {\n description: strings.PropertyPaneDescription\n },\n groups: [\n {\n groupName: strings.BasicGroupName,\n groupFields: [\n PropertyPaneTextField('description', {\n label: strings.DescriptionFieldLabel\n })\n ]\n }\n ]\n }\n ]\n };\n }\n}\n"]} \ No newline at end of file diff --git a/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.manifest.json b/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.manifest.json deleted file mode 100644 index 0953b2a..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/CtFormsPortalWebPart.manifest.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json", - "id": "459579c7-954c-469e-b707-ca75d808603f", - "alias": "CtFormsPortalWebPart", - "componentType": "WebPart", - - // The "*" signifies that the version should be taken from the package.json - "version": "*", - "manifestVersion": 2, - - // If true, the component can only be installed on sites where Custom Script is allowed. - // Components that allow authors to embed arbitrary script code should set this to true. - // https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f - "requiresCustomScript": false, - "supportedHosts": ["SharePointWebPart", "TeamsPersonalApp", "TeamsTab", "SharePointFullPage"], - "supportsThemeVariants": true, - "supportsFullBleed": true, - - "preconfiguredEntries": [{ - "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Advanced - "group": { "default": "Advanced" }, - "title": { "default": "ct-forms-portal" }, - "description": { "default": "ct-forms-portal description" }, - "officeFabricIconFontName": "Page", - "properties": { - "description": "ct-forms-portal" - } - }] -} diff --git a/lib-commonjs/webparts/ctFormsPortal/assets/welcome-dark.png b/lib-commonjs/webparts/ctFormsPortal/assets/welcome-dark.png deleted file mode 100644 index 42f0b8d..0000000 Binary files a/lib-commonjs/webparts/ctFormsPortal/assets/welcome-dark.png and /dev/null differ diff --git a/lib-commonjs/webparts/ctFormsPortal/assets/welcome-light.png b/lib-commonjs/webparts/ctFormsPortal/assets/welcome-light.png deleted file mode 100644 index 69eb3b4..0000000 Binary files a/lib-commonjs/webparts/ctFormsPortal/assets/welcome-light.png and /dev/null differ diff --git a/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.js b/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.js deleted file mode 100644 index 1d9a69a..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var tslib_1 = require("tslib"); -var React = tslib_1.__importStar(require("react")); -require("@tnsu/ui-kit/styles.css"); -var ui_kit_1 = require("@tnsu/ui-kit"); -var CtFormsPortal_module_scss_1 = tslib_1.__importDefault(require("./CtFormsPortal.module.scss")); -var Dashboard_1 = require("./Dashboard"); -// Корень веб-парта: спрайт иконок (один раз) + дашборд-реестр. -// Импорт CtFormsPortal.module.scss обязателен — в нём :global full-width правила канвы. -var CtFormsPortal = function (props) { return (React.createElement("div", { className: CtFormsPortal_module_scss_1.default.root }, - React.createElement(ui_kit_1.IconSprite, null), - React.createElement(Dashboard_1.Dashboard, { context: props.context }))); }; -exports.default = CtFormsPortal; -//# sourceMappingURL=CtFormsPortal.js.map \ No newline at end of file diff --git a/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.js.map b/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.js.map deleted file mode 100644 index 6084961..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"CtFormsPortal.js","sourceRoot":"","sources":["../../../../src/webparts/ctFormsPortal/components/CtFormsPortal.tsx"],"names":[],"mappings":";;;AAAA,mDAA+B;AAC/B,mCAAiC;AACjC,uCAA0C;AAC1C,kGAAiD;AAEjD,yCAAwC;AAExC,+DAA+D;AAC/D,wFAAwF;AACxF,IAAM,aAAa,GAAkC,UAAC,KAAK,IAAK,OAAA,CAC9D,6BAAK,SAAS,EAAE,mCAAM,CAAC,IAAI;IACzB,oBAAC,mBAAU,OAAG;IACd,oBAAC,qBAAS,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CACjC,CACP,EAL+D,CAK/D,CAAC;AAEF,kBAAe,aAAa,CAAC","sourcesContent":["import * as React from 'react';\nimport '@tnsu/ui-kit/styles.css';\nimport { IconSprite } from '@tnsu/ui-kit';\nimport styles from './CtFormsPortal.module.scss';\nimport type { ICtFormsPortalProps } from './ICtFormsPortalProps';\nimport { Dashboard } from './Dashboard';\n\n// Корень веб-парта: спрайт иконок (один раз) + дашборд-реестр.\n// Импорт CtFormsPortal.module.scss обязателен — в нём :global full-width правила канвы.\nconst CtFormsPortal: React.FC = (props) => (\n
\n \n \n
\n);\n\nexport default CtFormsPortal;\n"]} \ No newline at end of file diff --git a/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.module.scss.css b/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.module.scss.css deleted file mode 100644 index 40019a9..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/components/CtFormsPortal.module.scss.css +++ /dev/null @@ -1,11 +0,0 @@ -:global #workbenchPageContent, -:global #spPageCanvasContent, -:global .SPCanvas-canvas, -:global .CanvasComponent.LCS .CanvasZone, -:global .CanvasZone { - max-width: 100% !important; -} - -.root { - width: 100%; -} \ No newline at end of file diff --git a/lib-commonjs/webparts/ctFormsPortal/components/Dashboard.js b/lib-commonjs/webparts/ctFormsPortal/components/Dashboard.js deleted file mode 100644 index bc5506a..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/components/Dashboard.js +++ /dev/null @@ -1,106 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Dashboard = void 0; -var tslib_1 = require("tslib"); -var React = tslib_1.__importStar(require("react")); -var react_1 = require("react"); -var Dashboard_module_scss_1 = tslib_1.__importDefault(require("./Dashboard.module.scss")); -var ui_kit_1 = require("@tnsu/ui-kit"); -var config_1 = require("./config"); -var useDocumentDashboard_1 = require("./registry/useDocumentDashboard"); -// Иконка сайдбара по типу (kit-иконки; Fluent-иконки из конфигов тут не используем). -var TYPE_ICON = { ct: 'clipboard', oid: 'chart', kps: 'building' }; -// Цвет статуса DashboardRow → вариант нашего Badge (error → danger). -var VARIANT_MAP = { - neutral: 'neutral', - info: 'info', - success: 'success', - error: 'danger' -}; -function formatDate(iso) { - if (!iso) - return ''; - var d = new Date(iso); - var dd = d.getDate() < 10 ? "0".concat(d.getDate()) : "".concat(d.getDate()); - var mm = d.getMonth() + 1 < 10 ? "0".concat(d.getMonth() + 1) : "".concat(d.getMonth() + 1); - return "".concat(dd, ".").concat(mm, ".").concat(d.getFullYear()); -} -// Дашборд-реестр (config-driven, данные из SharePoint). Оболочка и элементы — из @tnsu/ui-kit. -var Dashboard = function (_a) { - var _b; - var context = _a.context; - var _c = (0, useDocumentDashboard_1.useDocumentDashboard)(context, config_1.DOCUMENT_TYPES), myDocs = _c.myDocs, approvedDocs = _c.approvedDocs, pendingDocs = _c.pendingDocs, isLoading = _c.isLoading, error = _c.error; - var _d = (0, react_1.useState)(config_1.DOCUMENT_TYPES[0].typeKey), activeType = _d[0], setActiveType = _d[1]; - var _e = (0, react_1.useState)('pending'), queue = _e[0], setQueue = _e[1]; - var _f = (0, react_1.useState)(false), collapsed = _f[0], setCollapsed = _f[1]; - var _g = (0, react_1.useState)(false), mobileOpen = _g[0], setMobileOpen = _g[1]; - var _h = (0, react_1.useState)(''), search = _h[0], setSearch = _h[1]; - var _j = (0, react_1.useState)(''), status = _j[0], setStatus = _j[1]; - var cfg = config_1.DOCUMENT_TYPES.filter(function (t) { return t.typeKey === activeType; })[0]; - var byType = function (arr) { return arr.filter(function (r) { return r.typeKey === activeType; }); }; - var pendingForType = byType(pendingDocs); - var mineForType = byType(myDocs); - var approvedForType = byType(approvedDocs); - var sidebarItems = config_1.DOCUMENT_TYPES.map(function (t) { - var _a; - return ({ - id: t.typeKey, - title: t.typeLabel, - icon: (_a = TYPE_ICON[t.typeKey]) !== null && _a !== void 0 ? _a : 'document', - count: pendingDocs.filter(function (r) { return r.typeKey === t.typeKey; }).length - }); - }); - var tabs = [ - { id: 'pending', label: 'На согласовании у меня', count: pendingForType.length }, - { id: 'mine', label: 'Инициализированные мной', count: mineForType.length }, - { id: 'approved', label: 'Согласованные мной', count: approvedForType.length } - ]; - var activeRows = queue === 'pending' ? pendingForType : queue === 'mine' ? mineForType : approvedForType; - var statusOptions = Array.from(new Set(activeRows.map(function (r) { return r.statusLabel; }))).map(function (s) { return ({ - value: s, - label: s - }); }); - var rows = activeRows - .filter(function (r) { var _a; return !search || "".concat(r.title, " ").concat((_a = r.subtitle) !== null && _a !== void 0 ? _a : '').toLowerCase().indexOf(search.toLowerCase()) !== -1; }) - .filter(function (r) { return !status || r.statusLabel === status; }); - var renderCell = function (row, key) { - var _a; - if (key === 'status') { - return (React.createElement(ui_kit_1.Badge, { variant: VARIANT_MAP[row.statusVariant], size: "sm" }, row.statusLabel)); - } - if (key === 'created') - return formatDate(row.createdDate); - return String((_a = row[key]) !== null && _a !== void 0 ? _a : ''); - }; - var columns = cfg.columns.map(function (c) { return ({ - key: c.key, - title: c.label, - width: c.minWidth ? "".concat(c.minWidth, "px") : undefined, - render: function (row) { return renderCell(row, c.key); } - }); }); - var selectType = function (id) { - setActiveType(String(id)); - setQueue('pending'); - setSearch(''); - setStatus(''); - }; - return (React.createElement(ui_kit_1.AppLayout, { sidebar: React.createElement(ui_kit_1.Sidebar, { items: sidebarItems, activeId: activeType, onChange: selectType, brand: "\u0414\u043E\u0433\u043E\u0432\u043E\u0440\u0430", collapsed: collapsed, onToggleCollapsed: function () { return setCollapsed(function (c) { return !c; }); }, mobileOpen: mobileOpen, onMobileClose: function () { return setMobileOpen(false); } }), mobileToggle: React.createElement(ui_kit_1.SidebarToggle, { onClick: function () { return setMobileOpen(true); } }) }, - React.createElement("div", { className: Dashboard_module_scss_1.default.head }, - React.createElement("h2", { className: Dashboard_module_scss_1.default.title }, cfg.typeLabel), - cfg.createNewUrl && (React.createElement(ui_kit_1.Button, { variant: "accent", onClick: function () { return window.open(cfg.createNewUrl, '_blank'); } }, (_b = cfg.createNewLabel) !== null && _b !== void 0 ? _b : 'Создать'))), - React.createElement("div", { className: Dashboard_module_scss_1.default.toolbar }, - React.createElement("div", { className: Dashboard_module_scss_1.default.search }, - React.createElement(ui_kit_1.TextInput, { value: search, onChange: setSearch, placeholder: "\u041F\u043E\u0438\u0441\u043A \u043F\u043E \u043D\u043E\u043C\u0435\u0440\u0443 \u0438\u043B\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0443" })), - React.createElement("div", { className: Dashboard_module_scss_1.default.filter }, - React.createElement(ui_kit_1.Select, { value: status, onChange: setStatus, options: statusOptions, placeholder: "\u0412\u0441\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u044B" }))), - React.createElement(ui_kit_1.Tabs, { tabs: tabs, activeId: queue, onChange: function (id) { return setQueue(id); } }), - error && (React.createElement("div", { className: Dashboard_module_scss_1.default.state }, - React.createElement(ui_kit_1.Alert, { variant: "err" }, - "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435: ", - error))), - !error && isLoading && React.createElement("div", { className: Dashboard_module_scss_1.default.state }, "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026"), - !error && !isLoading && (React.createElement("div", { className: Dashboard_module_scss_1.default.tableWrap }, - React.createElement(ui_kit_1.DataTable, { columns: columns, rows: rows, rowKey: function (r) { return "".concat(r.typeKey, "-").concat(r.id); }, onRowClick: function (r) { return window.open(cfg.buildLinkUrl(r), '_blank'); }, emptyText: "\u041D\u0435\u0442 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u0432" }))))); -}; -exports.Dashboard = Dashboard; -//# sourceMappingURL=Dashboard.js.map \ No newline at end of file diff --git a/lib-commonjs/webparts/ctFormsPortal/components/Dashboard.js.map b/lib-commonjs/webparts/ctFormsPortal/components/Dashboard.js.map deleted file mode 100644 index cce6efb..0000000 --- a/lib-commonjs/webparts/ctFormsPortal/components/Dashboard.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../../../src/webparts/ctFormsPortal/components/Dashboard.tsx"],"names":[],"mappings":";;;;AAAA,mDAA+B;AAC/B,+BAAiC;AAEjC,0FAA6C;AAC7C,uCAiBsB;AACtB,mCAA0C;AAC1C,wEAAuE;AAKvE,qFAAqF;AACrF,IAAM,SAAS,GAA6B,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAE/F,qEAAqE;AACrE,IAAM,WAAW,GAAwD;IACvE,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,QAAQ;CAChB,CAAC;AAEF,SAAS,UAAU,CAAC,GAAY;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,IAAM,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,WAAI,CAAC,CAAC,OAAO,EAAE,CAAE,CAAC,CAAC,CAAC,UAAG,CAAC,CAAC,OAAO,EAAE,CAAE,CAAC;IACnE,IAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,WAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,UAAG,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAE,CAAC;IAClF,OAAO,UAAG,EAAE,cAAI,EAAE,cAAI,CAAC,CAAC,WAAW,EAAE,CAAE,CAAC;AAC1C,CAAC;AAED,+FAA+F;AACxF,IAAM,SAAS,GAA0C,UAAC,EAAW;;QAAT,OAAO,aAAA;IAClE,IAAA,KAA0D,IAAA,2CAAoB,EAAC,OAAO,EAAE,uBAAc,CAAC,EAArG,MAAM,YAAA,EAAE,YAAY,kBAAA,EAAE,WAAW,iBAAA,EAAE,SAAS,eAAA,EAAE,KAAK,WAAkD,CAAC;IAExG,IAAA,KAA8B,IAAA,gBAAQ,EAAS,uBAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAxE,UAAU,QAAA,EAAE,aAAa,QAA+C,CAAC;IAC1E,IAAA,KAAoB,IAAA,gBAAQ,EAAW,SAAS,CAAC,EAAhD,KAAK,QAAA,EAAE,QAAQ,QAAiC,CAAC;IAClD,IAAA,KAA4B,IAAA,gBAAQ,EAAU,KAAK,CAAC,EAAnD,SAAS,QAAA,EAAE,YAAY,QAA4B,CAAC;IACrD,IAAA,KAA8B,IAAA,gBAAQ,EAAU,KAAK,CAAC,EAArD,UAAU,QAAA,EAAE,aAAa,QAA4B,CAAC;IACvD,IAAA,KAAsB,IAAA,gBAAQ,EAAS,EAAE,CAAC,EAAzC,MAAM,QAAA,EAAE,SAAS,QAAwB,CAAC;IAC3C,IAAA,KAAsB,IAAA,gBAAQ,EAAS,EAAE,CAAC,EAAzC,MAAM,QAAA,EAAE,SAAS,QAAwB,CAAC;IAEjD,IAAM,GAAG,GAAG,uBAAc,CAAC,MAAM,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,OAAO,KAAK,UAAU,EAAxB,CAAwB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtE,IAAM,MAAM,GAAG,UAAC,GAAmB,IAAqB,OAAA,GAAG,CAAC,MAAM,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,OAAO,KAAK,UAAU,EAAxB,CAAwB,CAAC,EAA3C,CAA2C,CAAC;IACpG,IAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACnC,IAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAE7C,IAAM,YAAY,GAAmB,uBAAc,CAAC,GAAG,CAAC,UAAC,CAAC;;QAAK,OAAA,CAAC;YAC9D,EAAE,EAAE,CAAC,CAAC,OAAO;YACb,KAAK,EAAE,CAAC,CAAC,SAAS;YAClB,IAAI,EAAE,MAAA,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,mCAAI,UAAU;YACxC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,EAAvB,CAAuB,CAAC,CAAC,MAAM;SACjE,CAAC,CAAA;KAAA,CAAC,CAAC;IAEJ,IAAM,IAAI,GAAW;QACnB,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE;QAChF,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE;QAC3E,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE;KAC/E,CAAC;IAEF,IAAM,UAAU,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC;IAE3G,IAAM,aAAa,GAAoB,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,WAAW,EAAb,CAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC;QAC3G,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,CAAC;KACT,CAAC,EAH0G,CAG1G,CAAC,CAAC;IAEJ,IAAM,IAAI,GAAG,UAAU;SACpB,MAAM,CAAC,UAAC,CAAC,YAAK,OAAA,CAAC,MAAM,IAAI,UAAG,CAAC,CAAC,KAAK,cAAI,MAAA,CAAC,CAAC,QAAQ,mCAAI,EAAE,CAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA,EAAA,CAAC;SAC7G,MAAM,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW,KAAK,MAAM,EAAnC,CAAmC,CAAC,CAAC;IAEtD,IAAM,UAAU,GAAG,UAAC,GAAiB,EAAE,GAAW;;QAChD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,OAAO,CACL,oBAAC,cAAK,IAAC,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAC,IAAI,IACtD,GAAG,CAAC,WAAW,CACV,CACT,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1D,OAAO,MAAM,CAAC,MAAC,GAA0C,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAC,CAAC;IACxE,CAAC,CAAC;IAEF,IAAM,OAAO,GAAqC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC;QACxE,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAG,CAAC,CAAC,QAAQ,OAAI,CAAC,CAAC,CAAC,SAAS;QACjD,MAAM,EAAE,UAAC,GAAG,IAAK,OAAA,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAtB,CAAsB;KACxC,CAAC,EALuE,CAKvE,CAAC,CAAC;IAEJ,IAAM,UAAU,GAAG,UAAC,EAAmB;QACrC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1B,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,SAAS,CAAC,EAAE,CAAC,CAAC;QACd,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO,CACL,oBAAC,kBAAS,IACR,OAAO,EACL,oBAAC,gBAAO,IACN,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAC,kDAAU,EAChB,SAAS,EAAE,SAAS,EACpB,iBAAiB,EAAE,cAAM,OAAA,YAAY,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,EAAF,CAAE,CAAC,EAAvB,CAAuB,EAChD,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,cAAM,OAAA,aAAa,CAAC,KAAK,CAAC,EAApB,CAAoB,GACzC,EAEJ,YAAY,EAAE,oBAAC,sBAAa,IAAC,OAAO,EAAE,cAAM,OAAA,aAAa,CAAC,IAAI,CAAC,EAAnB,CAAmB,GAAI;QAEnE,6BAAK,SAAS,EAAE,+BAAM,CAAC,IAAI;YACzB,4BAAI,SAAS,EAAE,+BAAM,CAAC,KAAK,IAAG,GAAG,CAAC,SAAS,CAAM;YAChD,GAAG,CAAC,YAAY,IAAI,CACnB,oBAAC,eAAM,IAAC,OAAO,EAAC,QAAQ,EAAC,OAAO,EAAE,cAAM,OAAA,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAvC,CAAuC,IAC5E,MAAA,GAAG,CAAC,cAAc,mCAAI,SAAS,CACzB,CACV,CACG;QAEN,6BAAK,SAAS,EAAE,+BAAM,CAAC,OAAO;YAC5B,6BAAK,SAAS,EAAE,+BAAM,CAAC,MAAM;gBAC3B,oBAAC,kBAAS,IAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAC,gJAA6B,GAAG,CACvF;YACN,6BAAK,SAAS,EAAE,+BAAM,CAAC,MAAM;gBAC3B,oBAAC,eAAM,IAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAC,+DAAa,GAAG,CAC5F,CACF;QAEN,oBAAC,aAAI,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAC,EAAE,IAAK,OAAA,QAAQ,CAAC,EAAc,CAAC,EAAxB,CAAwB,GAAI;QAEhF,KAAK,IAAI,CACR,6BAAK,SAAS,EAAE,+BAAM,CAAC,KAAK;YAC1B,oBAAC,cAAK,IAAC,OAAO,EAAC,KAAK;;gBAA+B,KAAK,CAAS,CAC7D,CACP;QACA,CAAC,KAAK,IAAI,SAAS,IAAI,6BAAK,SAAS,EAAE,+BAAM,CAAC,KAAK,6DAAiB;QACpE,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,CACvB,6BAAK,SAAS,EAAE,+BAAM,CAAC,SAAS;YAC9B,oBAAC,kBAAS,IACR,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,UAAC,CAAC,IAAK,OAAA,UAAG,CAAC,CAAC,OAAO,cAAI,CAAC,CAAC,EAAE,CAAE,EAAtB,CAAsB,EACrC,UAAU,EAAE,UAAC,CAAC,IAAK,OAAA,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAA1C,CAA0C,EAC7D,SAAS,EAAC,iFAAgB,GAC1B,CACE,CACP,CACS,CACb,CAAC;AACJ,CAAC,CAAC;AA1HW,QAAA,SAAS,aA0HpB","sourcesContent":["import * as React from 'react';\nimport { useState } from 'react';\nimport { WebPartContext } from '@microsoft/sp-webpart-base';\nimport styles from './Dashboard.module.scss';\nimport {\n AppLayout,\n Sidebar,\n SidebarToggle,\n ISidebarItem,\n Tabs,\n ITab,\n DataTable,\n IDataTableColumn,\n Badge,\n BadgeVariant,\n Button,\n TextInput,\n Select,\n ISelectOption,\n Alert,\n IconName\n} from '@tnsu/ui-kit';\nimport { DOCUMENT_TYPES } from './config';\nimport { useDocumentDashboard } from './registry/useDocumentDashboard';\nimport { DashboardRow } from './registry/documentRegistry';\n\ntype QueueKey = 'pending' | 'mine' | 'approved';\n\n// Иконка сайдбара по типу (kit-иконки; Fluent-иконки из конфигов тут не используем).\nconst TYPE_ICON: Record = { ct: 'clipboard', oid: 'chart', kps: 'building' };\n\n// Цвет статуса DashboardRow → вариант нашего Badge (error → danger).\nconst VARIANT_MAP: Record = {\n neutral: 'neutral',\n info: 'info',\n success: 'success',\n error: 'danger'\n};\n\nfunction formatDate(iso?: string): string {\n if (!iso) return '';\n const d = new Date(iso);\n const dd = d.getDate() < 10 ? `0${d.getDate()}` : `${d.getDate()}`;\n const mm = d.getMonth() + 1 < 10 ? `0${d.getMonth() + 1}` : `${d.getMonth() + 1}`;\n return `${dd}.${mm}.${d.getFullYear()}`;\n}\n\n// Дашборд-реестр (config-driven, данные из SharePoint). Оболочка и элементы — из @tnsu/ui-kit.\nexport const Dashboard: React.FC<{ context: WebPartContext }> = ({ context }) => {\n const { myDocs, approvedDocs, pendingDocs, isLoading, error } = useDocumentDashboard(context, DOCUMENT_TYPES);\n\n const [activeType, setActiveType] = useState(DOCUMENT_TYPES[0].typeKey);\n const [queue, setQueue] = useState('pending');\n const [collapsed, setCollapsed] = useState(false);\n const [mobileOpen, setMobileOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [status, setStatus] = useState('');\n\n const cfg = DOCUMENT_TYPES.filter((t) => t.typeKey === activeType)[0];\n\n const byType = (arr: DashboardRow[]): DashboardRow[] => arr.filter((r) => r.typeKey === activeType);\n const pendingForType = byType(pendingDocs);\n const mineForType = byType(myDocs);\n const approvedForType = byType(approvedDocs);\n\n const sidebarItems: ISidebarItem[] = DOCUMENT_TYPES.map((t) => ({\n id: t.typeKey,\n title: t.typeLabel,\n icon: TYPE_ICON[t.typeKey] ?? 'document',\n count: pendingDocs.filter((r) => r.typeKey === t.typeKey).length\n }));\n\n const tabs: ITab[] = [\n { id: 'pending', label: 'На согласовании у меня', count: pendingForType.length },\n { id: 'mine', label: 'Инициализированные мной', count: mineForType.length },\n { id: 'approved', label: 'Согласованные мной', count: approvedForType.length }\n ];\n\n const activeRows = queue === 'pending' ? pendingForType : queue === 'mine' ? mineForType : approvedForType;\n\n const statusOptions: ISelectOption[] = Array.from(new Set(activeRows.map((r) => r.statusLabel))).map((s) => ({\n value: s,\n label: s\n }));\n\n const rows = activeRows\n .filter((r) => !search || `${r.title} ${r.subtitle ?? ''}`.toLowerCase().indexOf(search.toLowerCase()) !== -1)\n .filter((r) => !status || r.statusLabel === status);\n\n const renderCell = (row: DashboardRow, key: string): React.ReactNode => {\n if (key === 'status') {\n return (\n \n {row.statusLabel}\n \n );\n }\n if (key === 'created') return formatDate(row.createdDate);\n return String((row as unknown as Record)[key] ?? '');\n };\n\n const columns: IDataTableColumn[] = cfg.columns.map((c) => ({\n key: c.key,\n title: c.label,\n width: c.minWidth ? `${c.minWidth}px` : undefined,\n render: (row) => renderCell(row, c.key)\n }));\n\n const selectType = (id: string | number): void => {\n setActiveType(String(id));\n setQueue('pending');\n setSearch('');\n setStatus('');\n };\n\n return (\n setCollapsed((c) => !c)}\n mobileOpen={mobileOpen}\n onMobileClose={() => setMobileOpen(false)}\n />\n }\n mobileToggle={ setMobileOpen(true)} />}\n >\n
\n

{cfg.typeLabel}

\n {cfg.createNewUrl && (\n \n )}\n
\n\n
\n
\n \n
\n
\n