From 40a53f7d99ef265127184c3dd987df34141f5cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D1=81=D1=8C=D0=BC=D0=B0=D0=BA=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=81?= Date: Wed, 26 Feb 2020 13:37:50 +0300 Subject: [PATCH] new buttons with perm and disp --- .../RejectTasks/RejectTasks.module.scss | 145 +++------- .../components/RejectTasks/RejectTasks.tsx | 265 ++++++++---------- .../SummaryContainer/SummaryContainer.scss | 3 + .../SummaryContainer/SummaryContainer.tsx | 11 +- .../SummaryGlobalComponent.module.scss | 10 +- .../components/SummaryWebPart.tsx | 53 ++-- .../TaskStatusesChart/TaskStatusesChart.tsx | 2 +- .../interfaces/IDeviationTasks.ts | 4 +- 8 files changed, 211 insertions(+), 282 deletions(-) create mode 100644 src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.scss diff --git a/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.module.scss b/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.module.scss index 3216882..425cfb2 100644 --- a/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.module.scss +++ b/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.module.scss @@ -1,123 +1,64 @@ .commonTable { - /* min-width: 361px; - max-width: 361px; - width: 361px; */ width: 100%; - border-bottom: 1px solid #c8c8c8; - .thead { - display: flex; - .th { - padding: 6px; - border-top: 1px solid #c8c8c8; - border-left: 1px solid #c8c8c8; - font-family: "Segoe UI Web (West European)",Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif; - width: 100%; - color: #767676; - font-size: 13px; - font-weight: bold; - transition: 0.5s; - - cursor: pointer; - - &:hover { - background: #f4f4f4; - color: #666666; - transition: 0.5s; - } - } - .Departments { - min-width: 123px !important; - } - .Managers { - min-width: 116px !important; - } - .Members { - min-width: 116px !important; + min-width: 350px; + border-collapse:collapse; + caption-side:bottom; + table-layout: fixed; + overflow: hidden; + white-space: nowrap; + thead { + tr { + th{ + padding: 6px; + border: 1px solid #c8c8c8; + font-family: "Segoe UI Web (West European)",Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif; + color: #767676; + font-size: 13px; + font-weight: bold; + transition: 0.5s; + white-space: normal; + word-break: break-all; + cursor: pointer; + &:hover { + background: #f4f4f4; + color: #666666; + transition: 0.5s; + } + } } - .count { - min-width: 46px !important; - max-width: 46px !important; - border-right: 1px solid #c8c8c8; - } } - .tbody { - display: flex; - - .td { - border-top: 1px solid #c8c8c8; - border-left: 1px solid #c8c8c8; - color: #767676; - background: #ffffff; - font-size: 13px; - width: 100%; - - font-family: "Segoe UI Web (West European)",Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif; - transition: 0.5s; - cursor: pointer; - - - .cell { - padding: 3px 5px; + .commonTbody { + tr { + td { + padding: 6px; + border: 1px solid #c8c8c8; + font-family: "Segoe UI Web (West European)",Segoe UI,-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif; color: #767676; - border-bottom: 1px solid #c8c8c8; - display: flex; - align-items: center; - justify-content: center; - - /* max-width: 100px; */ + font-size: 13px; + transition: 0.5s; + cursor: pointer; &:hover { background: #f4f4f4; color: #666666; transition: 0.5s; } - span { - /* white-space: nowrap; */ + div { + width: 99%; overflow: hidden; text-overflow: ellipsis; - display: block; } - } - .Departments { - width: 124px !important; - margin-left: 1px; - } - .Managers { - min-width: 106px !important; - } - .Members { - min-width: 106px !important; + } .isCrit { - background: #ff000042; - &:hover { - background: #ff0000ab; - color: #4b4b4b; - transition: 0.5s; + background: #ff000042; + &:hover { + background: #ff0000ab; + color: #4b4b4b; + transition: .5s; } } - .count { - min-width: 47px !important; - } - .cell:last-child { - border-bottom: none; - } - div { - text-align: center; - vertical-align: center; - } - .dividingLine{ - border-bottom: 1px solid #c8c8c8; - } } - .MembersTaskCount { - width: 58px; - max-width: 58px !important; - min-width: 58px !important; - border-right: 1px solid #c8c8c8; - } } } -.dividingLine{ - border-bottom: 1px solid #c8c8c8; -} \ No newline at end of file + diff --git a/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.tsx b/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.tsx index 6b2d3c1..751a7af 100644 --- a/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.tsx +++ b/src/webparts/summaryWebPart/components/RejectTasks/RejectTasks.tsx @@ -1,203 +1,160 @@ import * as React from 'react'; -/* import styles from '../SummaryGlobalComponent/SummaryGlobalComponent.module.scss' */ -import { DetailsList, SelectionMode, DetailsListLayoutMode } from 'office-ui-fabric-react/lib/DetailsList'; import { DeviationTasks } from '../../interfaces/IDeviationTasks'; import styles from '../RejectTasks/RejectTasks.module.scss' - export interface IComponentProps { structureData: DeviationTasks[] } - export interface IComponentState { } -export default class TrafficLight extends React.Component { +export default class DeviationTaskTable extends React.Component { - private _renderHeaderCell(): JSX.Element { - + private _renderHeaderTable(): JSX.Element { return ( -
-
- Подразделение -
-
- Руководитель -
-
- Участник -
-
- Кол-во задач -
-
+ + + + Подразделение + + + Руководитель + + + Участник + + + Кол-во задач + + + ) } - - private _cell(value:string,length:any,className:string,crit?:boolean,): JSX.Element { - // 7 px это 1px border и padding 3px - - var height = 'calc('+ 100/length + '% - 7px)' - var critClassName = '' - if(crit) { - critClassName = 'isCrit' - } - - return ( -
{value}
- ) - - - } - - private _renderCell(structureData:any,i:number): JSX.Element { + private _renderBodyTable(structureData:any): JSX.Element { - var Departments = [] //Подразделения - var Managers = [] //Руководители - var Members = [] //Участники - var MembersTaskCount = [] //Кол-во задач - + var structureTable = [] //В этом массив пушиться вся структура таблицы (tr td) + + // Прохожусь по всему приходящему массиву. Через функции _cell() и _customCell пушу ячеейки в structureTable. Так же в этой фунции определяться rowSpan и сокращаеться value до ФИО if(structureData){ if(structureData.Departments.length){ - - // пушу в массив Departments ячейки - Departments.push(this._cell(structureData.Departments[i].Name,1 , 'Departments')) - if(structureData.Departments[i].Managers){ - for (let index = 0; index < structureData.Departments[i].Managers.length; index++) { - let menagers = structureData.Departments[i].Managers[index].Name - if(menagers){ - //Сокращаю Имена и Отчества Пример Масловский Артем Андреевич Масловский А.А. - let ManagersName = structureData.Departments[i].Managers[index].Name.split(' ') - let name = ManagersName[1].split('')[0] + '.' - let surname = ManagersName[0] + + for (let i = 0; i < structureData.Departments.length; i++) { + // Формула rowSpan + let rowSpan = 0; + + structureData.Departments[i].Managers.forEach(function(e) { + rowSpan = rowSpan + (e.Members.length+1); + }) + + // Конец формуле + structureTable.push(this._cell(structureData.Departments[i].Name, rowSpan+1 , 'Departments',true)) + + if(structureData.Departments[i].Managers){ + for (let index = 0; index < structureData.Departments[i].Managers.length; index++) { - if(ManagersName[2]){ + let menagers = structureData.Departments[i].Managers[index].Name; - let patronymic = ManagersName[1].split('')[0] + '.' - - ManagersName = surname + ' ' + name + ' ' + patronymic + if(menagers){ + //Сокращаю Имена и Отчества Пример Масловский Артем Андреевич Масловский А.А. + let ManagersName = structureData.Departments[i].Managers[index].Name.split(' '); + let name = ManagersName[1].split('')[0] + '.'; + let surname = ManagersName[0]; + + if(ManagersName[2]){ + let patronymic = ManagersName[1].split('')[0] + '.'; + ManagersName = surname + ' ' + name + ' ' + patronymic; } else { - ManagersName = surname + ' ' + name + ManagersName = surname + ' ' + name; } - let maxLength = 0 + let maxLength = 0; structureData.Departments[i].Managers.forEach(function(e) { - maxLength = maxLength + e.Members.length + maxLength = maxLength + e.Members.length; }) - - //Переменная для расчета высоты ячейки менеджеров. - let length = maxLength/structureData.Departments[i].Managers[index].Members.length - //Пушу ячейки - Managers.push(this._cell( ManagersName ,length,'Managers')) - } else { - Managers.push(this._cell( '' ,structureData.Departments[i].Managers[index].length,'Managers')) - } - if(structureData.Departments[i].Managers[index].Members.length){ - for (let counter = 0; counter < structureData.Departments[i].Managers[index].Members.length; counter++) { - let MembersName = structureData.Departments[i].Managers[index].Members[counter].Name - if(MembersName) { - //Сокращаю Имена и Отчества Пример Масловский Артем Андреевич Масловский А.А. - - MembersName = MembersName.split(' '); - let name = MembersName[1].split('')[0] + '.'; - let surname = MembersName[0]; - if(MembersName[2]){ - MembersName[2].split('')[0]; - - let patronymic = MembersName[2].split('')[0] + '.'; - - MembersName = surname + ' ' + name + ' ' + patronymic; - } else { - MembersName = surname + ' ' + name - } - } - //Пушу ячейки - Members.push( - this._cell( MembersName ,structureData.Departments[i].Managers[index].length,'Members', - structureData.Departments[i].Managers[index].Members[counter].Crit) + structureTable.push( + this._cell( ManagersName ,structureData.Departments[i].Managers[index].Members.length+1,'Managers') + ) + } else { + structureTable.push( + this._cell( ' ' ,structureData.Departments[i].Managers[index].Members.length+1,'Managers') ) - //Пушу ячейки - MembersTaskCount.push( - this._cell(structureData.Departments[i].Managers[index].Members[counter].TaskCount ,structureData.Departments[i].Managers[index].length,'count', - structureData.Departments[i].Managers[index].Members[counter].Crit) - ) - } + } + + if(structureData.Departments[i].Managers[index].Members.length){ + + for (let counter = 0; counter < structureData.Departments[i].Managers[index].Members.length; counter++) { + let MembersName = structureData.Departments[i].Managers[index].Members[counter].Name + if(MembersName) { + //Сокращаю Имена и Отчества Пример Масловский Артем Андреевич Масловский А.А. + MembersName = MembersName.split(' '); + let name = MembersName[1].split('')[0] + '.'; + let surname = MembersName[0]; + + if(MembersName[2]){ + MembersName[2].split('')[0]; + let patronymic = MembersName[2].split('')[0] + '.'; + MembersName = surname + ' ' + name + ' ' + patronymic; + } else { + MembersName = surname + ' ' + name + } + } + + let isCrit = structureData.Departments[i].Managers[index].Members[counter].Crit + + structureTable.push( + this._customCell( MembersName , structureData.Departments[i].Managers[index].Members[counter].TaskCount,isCrit) + ) + } + } } } - } + } } } - + return ( -
-
- - { - Departments - } - -
-
- { - Managers - } -
-
- { - Members - } -
-
- { - MembersTaskCount - } -
-
+ + {structureTable} + ) } - private _renderBodyTable(structureData:any,): JSX.Element { - var body = [] - - for (let i = 0; i < structureData.Departments.length; i++) { - body.push(this._renderCell(structureData, i)) - } - return ( -
{body}
+ private _cell(value:string,length:any,className:string,row?:boolean,): JSX.Element { - ) + return ( +
{value}
+ ) + } - componentDidMount(){ + private _customCell(membersValue:string,countValue:string,crit?:boolean): JSX.Element { + let critClassName = ''; + + if(crit) { + critClassName = 'isCrit'; + } + + return ( + +
{membersValue}
+
{countValue}
+ + ) + } - public onRenderFooter = () =>{ - } - public render(): React.ReactElement { return ( -
-
- -
-
- {this._renderHeaderCell()} -
-
- { - this._renderBodyTable(this.props.structureData) - } -
-
- -
-
+ + {this._renderHeaderTable()} + {this._renderBodyTable(this.props.structureData)} +
); } } diff --git a/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.scss b/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.scss new file mode 100644 index 0000000..8268af9 --- /dev/null +++ b/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.scss @@ -0,0 +1,3 @@ +.ms-DetailsRow-cell { + white-space: pre-line; +} \ No newline at end of file diff --git a/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.tsx b/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.tsx index 427256b..0d3689e 100644 --- a/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.tsx +++ b/src/webparts/summaryWebPart/components/SummaryContainer/SummaryContainer.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { ISummaryProjectData } from '../../interfaces/ISummaryProjectData'; -import styles from '../SummaryWebPart.module.scss' +import styles from '../SummaryWebPart.module.scss'; +import '../SummaryContainer/SummaryContainer.scss' import { DetailsList, SelectionMode, @@ -149,7 +150,13 @@ export default class SummaryContainer extends React.Component } @@ -49,20 +51,26 @@ export default class SummaryWebPart extends React.Component { - if(e.length){ - this.setState({ isPerm: true }) - }else{ + thisWeb.lists.getByTitle('CustomPerm').items.get().then((e:any) => { + let permWP = null; + e.forEach(el=>{ + if (el.Title == 'PermEdit') this.setState({isPermConfigButton: true}) + if (el.Title == 'WPSummary') this.setState({ isPerm: true }); permWP = true; + }) + + if (!permWP){ this.setState({ noPermDiv: {'Отсутствует доступ к странице'} }) } + + }) web.lists.getById('eeba7db6-4c28-41a2-a54e-82a2aaf0ca15').items.filter("Code_project eq '" + projectCode +"'").select('ID').get().then(e=>{ @@ -77,28 +85,41 @@ export default class SummaryWebPart extends React.Component { + public relocate = (loc:string) => { const { prjID } = this.state; - location.href = 'http://portal.vertex.spb.ru/PMIS/SitePages/EditForm.aspx?itemId=' + prjID; + location.href = `http://portal.vertex.spb.ru/PMIS/SitePages/${loc}.aspx?itemId=${prjID}`; } public render(): React.ReactElement { - const { pageData, isLoaded, isBlank, isPerm, noPermDiv } = this.state; + const { pageData, isLoaded, isBlank, isPerm, noPermDiv, isPermConfigButton } = this.state; - return isPerm ? isLoaded ? ( + return isPerm || isPermConfigButton ? isLoaded ? (
- +
+ {isPermConfigButton ? this.relocate('PermForm')} + style={{fontSize: '13px'}} + /> : null} + + {isPerm && this.relocate('EditForm')} + style={{ fontSize: '13px', marginRight: '10px', marginLeft: '10px'}} + />} + this.relocate('DispForm')} + style={{ fontSize: '13px' }} + /> +
- + />}
) : isBlank ? (
diff --git a/src/webparts/summaryWebPart/components/TaskStatusesChart/TaskStatusesChart.tsx b/src/webparts/summaryWebPart/components/TaskStatusesChart/TaskStatusesChart.tsx index 94495d9..dab84fe 100644 --- a/src/webparts/summaryWebPart/components/TaskStatusesChart/TaskStatusesChart.tsx +++ b/src/webparts/summaryWebPart/components/TaskStatusesChart/TaskStatusesChart.tsx @@ -27,7 +27,7 @@ export default class TaskStatusesChart extends React.Component { const { taskStats } = this.props; - let chartTitle = 'Текущee состояние проекта (выполняемых задач: '+( Number(taskStats.exec) + Number(taskStats.plan) + Number(taskStats.compl))+' шт.)' + let chartTitle = 'Текущee состояние проекта (всего задач: '+( Number(taskStats.exec) + Number(taskStats.plan) + Number(taskStats.compl))+' шт.)' return (

{chartTitle}

diff --git a/src/webparts/summaryWebPart/interfaces/IDeviationTasks.ts b/src/webparts/summaryWebPart/interfaces/IDeviationTasks.ts index 064a6f3..fe6bbd6 100644 --- a/src/webparts/summaryWebPart/interfaces/IDeviationTasks.ts +++ b/src/webparts/summaryWebPart/interfaces/IDeviationTasks.ts @@ -1,4 +1,4 @@ export interface DeviationTasks { - Departments: any; - } + Departments: any; +} \ No newline at end of file