<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<div class="row">
<h2>Create your snippet's HTML, CSS and Javascript in the editor tabs</h2>
</div>
</div>
const WEEKDAYS_LONG = {
ru: [
'Воскресенье',
'Понедельник',
'Вторник',
'Среда',
'Четверг',
'Пятница',
'Суббота',
]
};
const WEEKDAYS_SHORT = {
ru: ['Во', 'По', 'Вт', 'Ср', 'Че', 'Пя', 'Су']
};
const MONTHS = {
ru: [
'Январь',
'Февраль',
'Март',
'Апрель',
'Май',
'Июнь',
'Июль',
'Август',
'Сентябрь',
'Октябрь',
'ноябрь',
'Декабрь',
]
};
const FIRST_DAY_OF_WEEK = {
ru: 1
};
const LABELS = {
ru: { nextMonth: 'следующий месяц', previousMonth: 'предыдущий месяц' }
};
function getDateFromJSON(jsonDateString) {
return new Date(jsonDateString.match(/\d+/)[0] * 1);
}
function getDateStringFromDate(dateForString) {
if (dateForString == undefined)return;
return ("0" + dateForString.getDate()).slice(-2) + "." + ("0" + (dateForString.getMonth() + 1)).slice(-2) + "." + dateForString.getFullYear();
}
var AppointmentsComponent = React.createClass({
getInitialState: function() {
return {
selectedDay: new Date(),
roomsData: this.props.roomsData,
floorFilters:[],
capacityFilters:[],
appointmentsData:[],
authorData:this.props.authorData
};
},
componentDidMount(){
this.getAppointmentsData();
},
getAppointmentsData: function() {
$.ajax({
url: '/_layouts/15/wssc.prt.pnt6.core/Handlers/ajax.ashx',
data: ({
method: 'WSSC.PRT.PNT6.Appointments:PortalAppointments:GetAppointmentsData',
selectedDay: getDateStringFromDate(this.state.selectedDay),
rand: Math.random()
}),
type: 'POST',
success: function(result) {
this.setState({appointmentsData:JSON.parse(result)});
}.bind(this)
})
},
changeRoomsFloorFilter: function(value) {
var newFloorFilters = this.state.floorFilters;
var indexOfValueInArray = newFloorFilters.indexOf(value);
if(indexOfValueInArray >= 0)newFloorFilters.splice(indexOfValueInArray, 1);
else newFloorFilters.push(value);
this.setState({ floorFilters: newFloorFilters });
this.getRoomsWithFilter();
},
changeRoomsCapacityFilter:function(value) {
var newCapacityFilters = this.state.capacityFilters;
var indexOfValueInArray = newCapacityFilters.indexOf(value);
if(indexOfValueInArray >= 0)newCapacityFilters.splice(indexOfValueInArray, 1);
else newCapacityFilters.push(value);
this.setState({ capacityFilters: newCapacityFilters });
this.getRoomsWithFilter();
},
getRoomsWithFilter:function() {
var FloorFilters = this.state.floorFilters;
var CapacityFilters = this.state.capacityFilters;
var newRoomsData = this.props.roomsData.filter(function( obj ) {
return ((FloorFilters.length < 1 || FloorFilters.indexOf(obj.Floor) >= 0) && (CapacityFilters.length < 1 || CapacityFilters.indexOf(obj.Capacity) >= 0));
});
this.setState({ roomsData: newRoomsData});
},
appointmentAddedHandle: function() {
this.getAppointmentsData();
},
handleDayClick: function(day){
this.setState({
selectedDay: day,
},
this.getAppointmentsData
);
},
render: function() {
return (
<div className="appointmentsComponent">
<div className="roomFilters">
<DayPicker locale="ru"
months={MONTHS["ru"]}
weekdaysLong={WEEKDAYS_LONG["ru"]}
weekdaysShort={WEEKDAYS_SHORT["ru"]}
firstDayOfWeek={FIRST_DAY_OF_WEEK["ru"]}
labels={LABELS["ru"]}
onDayClick={this.handleDayClick}
selectedDays={this.state.selectedDay}
/>
<RoomFloorFilter data={this.props.roomsData} changeRoomFloorFilter={this.changeRoomsFloorFilter} />
<RoomCapacityFilter data={this.props.roomsData} changeRoomCapacityFilter={this.changeRoomsCapacityFilter} />
</div>
<AppointmentRoomList data={this.state.roomsData} allAppointmentsData={this.state.appointmentsData} allAuthorData={this.state.authorData} selectedDay={this.state.selectedDay} appointmentAdded={this.appointmentAddedHandle}/>
</div>
);
}
});
var AppointmentRoomList = React.createClass({
appointmentAddedHandle: function() {
this.props.appointmentAdded();
},
render: function() {
var appointmentsData = this.props.allAppointmentsData;
var roomList = this.props.data.map((room) => {
var appointmentsDataForRoom = appointmentsData.filter(function( obj ) {
return obj.RoomId == room.RoomId
});
var appointmentsExchangeDataForRoom = appointmentsData.filter(function( obj ) {
return obj.RoomLocation == room.InExchangeEmail && obj.RoomLocation != null
});
var appointmentsDataForRoomJSON = JSON.stringify(appointmentsDataForRoom.concat(appointmentsExchangeDataForRoom));
return (
<AppointmentRoom roomData={room} appointmentsRoomData={appointmentsDataForRoomJSON} authorData={this.props.allAuthorData} appointmentAdded={this.appointmentAddedHandle} key={room.RoomId} selectedDay={this.props.selectedDay} />
);
});
return (
<div className="roomList">
{roomList}
</div>
);
}
});
var AppointmentRoom = React.createClass({
appointmentAddedHandle: function() {
this.props.appointmentAdded();
},
render: function() {
return (
<div className="appointmentRoom">
<div className="roomInfo">
<div className="roomImageDiv">
<img className="roomImage" src={this.props.roomData.Image} />
</div>
<div className="roomTitle">
{this.props.roomData.Title}
</div>
<div className="roomFloor">
Этаж: {this.props.roomData.Floor}
</div>
<div className="roomCapacity">
Вместимость: {this.props.roomData.Capacity}
</div>
</div>
<div className="roomTimes">
<RoomTimeList room={this.props.roomData} roomAppointmentsData={this.props.appointmentsRoomData} allAuthorData={this.props.authorData} appointmentAdded={this.appointmentAddedHandle} selectedDay={this.props.selectedDay} />
</div>
</div>
);
}
});
var RoomTimeList = React.createClass({
getInitialState: function() {
return {
isCreatingAppointment: false,
startTime: 0,
displayCreateBox: "none",
newAppointmentData:""
};
},
clickCell: function(value) {
var isCreating = this.state.isCreatingAppointment;
var newAppointment =
{
DateAppointment: "",
Start: "",
End: "",
RoomId: 0,
Theme: "",
Description: "",
ChoosenMembers: "",
RoomLocation: ""
};
if (!isCreating) {
this.setState({
startTime: value
});
}
console.log("roooom " + this.props.room.InExchangeEmail)
if (isCreating) {
newAppointment.Start = this.state.startTime;
newAppointment.End = value;
newAppointment.RoomId = this.props.room.RoomId;
newAppointment.DateAppointment = this.props.selectedDay;
newAppointment.RoomLocation = this.props.room.InExchangeEmail;
this.setState({ newAppointmentData: newAppointment }, this.showCreateBox);
}
this.setState({ isCreatingAppointment: !isCreating});
},
createAppointment: function(appointmentAddedValues) {
this.closeCreateBox();
var newAppointment = this.state.newAppointmentData;
newAppointment.Theme = appointmentAddedValues.appointmentTitleValue;
newAppointment.Description = appointmentAddedValues.appointmentDescriptionValue;
newAppointment.ChoosenMembers = JSON.stringify(appointmentAddedValues.choosenMembersList);
$.ajax({
url: '/_layouts/15/wssc.prt.pnt6.core/Handlers/ajax.ashx',
data: ({
method: 'WSSC.PRT.PNT6.Appointments:PortalAppointments:CreateAppointment',
newAppointment: JSON.stringify(newAppointment),
isInExchange: this.props.room.InExchangeEmail != null && this.props.room.InExchangeEmail.length > 0,
rand: Math.random()
}),
type: 'POST',
success: function(result) {
this.props.appointmentAdded();
}.bind(this)
})
},
showCreateBox: function() {
this.setState({ displayCreateBox: "block"});
},
closeCreateBox: function() {
this.setState({ displayCreateBox: "none"});
},
render: function() {
var AppointmentsData = JSON.parse(this.props.roomAppointmentsData);
var appointmentList = AppointmentsData.map((appointment) => {
return (
<AppointmentElement key={appointment.Id + appointment.UniqueId} appointmentData={appointment} />
);
});
var timeList = this.props.room.TimesToReserve.map((time) => {
return (
<RoomTimeCell value={time} key={time} clickRoomTimeCell={this.clickCell} />
);
});
return (
<div className="roomTimeList">
<CreateAppointmentBox displayCreateBox={this.state.displayCreateBox} creatingRoomData={this.state.newAppointmentData} authorData={this.props.allAuthorData} roomTitle={this.props.room.Title} CloseBox={this.closeCreateBox} Create={this.createAppointment} />
<div className="roomAppointments">
{appointmentList}
</div>
<div className="allCells">
{timeList}
</div>
</div>
);
}
});
var CreateAppointmentBox = React.createClass({
getInitialState: function() {
return {
appointmentTitleValue: '',
appointmentDescriptionValue: '',
appointmentMemberList: '',
chooseMemberValue: '',
chooseMemberVariants: '[{"Name":"","Surname":"","Photo":"","Position":""}]',
choosenMembersList: [],
showChooseVariants: false
};
},
CloseBox: function() {
this.props.CloseBox();
},
Create: function() {
var appointmentAddedValues = {
appointmentTitleValue: this.state.appointmentTitleValue,
appointmentDescriptionValue: this.state.appointmentDescriptionValue,
choosenMembersList: this.state.choosenMembersList
}
this.props.Create(appointmentAddedValues);
this.setState({
appointmentTitleValue: '',
appointmentDescriptionValue: '',
choosenMembersList: []
});
},
updateAppointmentTitleValue: function(e) {
this.setState({
appointmentTitleValue: e.target.value
});
},
updateAppointmentDescriptionValue: function(e) {
this.setState({
appointmentDescriptionValue: e.target.value
});
},
changeMemberResults: function(e) {
this.setState({
chooseMemberValue: e.target.value
}, this.getMemberResults);
},
getMemberResults: function() {
$.ajax({
url: '/_layouts/15/wssc.prt.pnt6.core/Handlers/ajax.ashx',
data: ({
method: 'WSSC.PRT.PNT6.Appointments:PortalAppointments:getMemberVariants',
chooseMemberValue: this.state.chooseMemberValue,
rand: Math.random()
}),
type: 'POST',
success: function(result) {
this.setState({
chooseMemberVariants: result,
showChooseVariants: result.length > 3 ? true : false
});
}.bind(this)
})
},
chooseVariant: function(memberVariant){
this.setState({
chooseMemberValue: '',
chooseMemberVariants: '[{"Name":"","Surname":"","Photo":"","Position":""}]',
choosenMembersList: this.state.choosenMembersList.concat(memberVariant),
showChooseVariants: false
});
},
DeleteNewMember: function(deletedMemberIndex) {
var newMemberList = this.state.choosenMembersList;
newMemberList.splice(deletedMemberIndex, 1);
this.setState({
choosenMembersList: newMemberList
});
},
render: function() {
var author = JSON.parse(this.props.authorData);
var memberVariants = JSON.parse(this.state.chooseMemberVariants);
var memberVariantList = memberVariants.map((memberVariant) => {
return (
<div className="memberVariant" onClick={this.chooseVariant.bind(this, memberVariant)} key={memberVariant.Id}>
<img src={memberVariant.Photo} className="memberVariantPhoto" />
<div className="memberVariantFIO">
{memberVariant.Surname} {memberVariant.Name}
</div>
<div className="memberVariantPosition">
{memberVariant.Position}
</div>
</div>
);
});
var memberList = this.state.choosenMembersList.map((newMember,index) => {
return (
<div className="member" key={newMember.Id}>
<img className="memberPhoto" src={newMember.Photo} />
<div className="memberFIO">
{newMember.Surname} {newMember.Name}
</div>
<div className="memberPosition">
{newMember.Position}
</div>
<div className="deleteNewMember" onClick={this.DeleteNewMember.bind(this, index)}>x</div>
</div>
);
});
return (
<div className="modalBox createBox" style={{display:this.props.displayCreateBox}}>
<div className="appointmentHeader">Бронирование: {this.props.roomTitle}</div>
<div className="appointmentInfoWrap">
<div className="appointmentInfoText">Информация</div>
<div className="appointmentTime">{this.props.creatingRoomData.Start} - {this.props.creatingRoomData.End}</div>
<div className="appointmentDate">{getDateStringFromDate(this.props.creatingRoomData.DateAppointment)}</div>
<div className="appointmentTitle"><input className="appointmentTitleValue corpBorder" placeholder="Тема" value={this.state.appointmentTitleValue} onChange={this.updateAppointmentTitleValue} /></div>
<div className="appointmentDescription"><textarea className="appointmentDescriptionValue corpBorder" placeholder="Описание" value={this.state.appointmentDescriptionValue} onChange={this.updateAppointmentDescriptionValue} ></textarea></div>
</div>
<div className="appointmentMembers">
<div className="appointmentInitiator">
Инициатор
</div>
<div className="initiatorInfo">
<div className="overInitiatorPhoto"><img src={author.Photo} className="initiatorPhoto" /></div>
<div className="initiatorName">{author.Surname} {author.Name}</div>
<div className="initiatorPostition">{author.Position}</div>
</div>
<div className="appointmentMemberListTitle">
Участники
</div>
<input type="text" className="chooseMember" onChange={this.changeMemberResults} value={this.state.chooseMemberValue} autoComplete="off" />
{this.state.showChooseVariants ? <div className="chooseMemberVariants">{memberVariantList}</div> : "" }
<div className="appointmentMemberList">
{memberList}
</div>
</div>
<div className="clear"></div>
<div className="appointmentCreate corporateBackground" onClick={this.Create}>Создать</div>
<div className="appointmentClose" onClick={this.CloseBox}>Отмена</div>
</div>
);
}
});
var RoomTimeCell = React.createClass({
getInitialState: function() {
return {
bgColor: "white"
};
},
clickCell: function(value) {
this.setState({ bgColor: '#ccc' });
this.props.clickRoomTimeCell(value);
},
render: function() {
return (
<div className="roomTimeCell" style={{backgroundColor:this.state.bgColor}} onClick={this.clickCell.bind(this, this.props.value)}>{this.props.value}</div>
);
}
});
var AppointmentElement = React.createClass({
getInitialState: function() {
return {
displayEditBox: "none",
};
},
showEditBox: function() {
this.setState({ displayEditBox: "block"});
},
closeEditBox: function() {
this.setState({ displayEditBox: "none"});
},
render: function() {
var appointment = this.props.appointmentData;
console.log(appointment);
var startDate = getDateFromJSON(appointment.StartTime);
var endDate = getDateFromJSON(appointment.EndTime);
var startMinutesAdd = startDate.getMinutes() > 0 ? 0.5 : 0;
var endMinutesAdd = endDate.getMinutes() > 0 ? 0.5 : 0;
var start = startDate.getHours() + 1 + startMinutesAdd;
var end = endDate.getHours() + 1 + endMinutesAdd;
var startText = (startDate.getHours() + 1) + ":" + startDate.getMinutes();
var endText = (endDate.getHours() + 1) + ":" + endDate.getMinutes();
var appointmentHeight = (end - start)*52;
var appointmentMarginTop = (start - 7) * 52;
return (
<div className="appointmentElement">
<EditAppointmentBox displayEditBox={this.state.displayEditBox} CloseBox={this.closeEditBox} editAppointmentData={this.props.appointmentData} />
<div className="appointmentInfo" onClick={this.showEditBox} style={{lineHeight:appointmentHeight + "px",height:appointmentHeight + "px",marginTop:appointmentMarginTop}}>
{startText} - {endText}
<div>
ИД брони: {appointment.Id}
</div>
</div>
</div>
);
}
});
var EditAppointmentBox = React.createClass({
getInitialState: function() {
return {
appointmentTitleValue: this.props.editAppointmentData.Theme,
appointmentDescriptionValue: this.props.editAppointmentData.Description,
appointmentMemberList: '',
chooseMemberValue: '',
chooseMemberVariants: '[{"Name":"","Surname":"","Photo":"","Position":""}]',
choosenMembersList: this.props.editAppointmentData.Attendies,
showChooseVariants: false,
isEditMode: false
};
},
CloseBox: function() {
this.props.CloseBox();
},
Update: function() {
},
updateAppointmentTitleValue: function(e) {
this.setState({
appointmentTitleValue: e.target.value
});
},
updateAppointmentDescriptionValue: function(e) {
this.setState({
appointmentDescriptionValue: e.target.value
});
},
changeMemberResults: function(e) {
this.setState({
chooseMemberValue: e.target.value
}, this.getMemberResults);
},
getMemberResults: function() {
$.ajax({
url: '/_layouts/15/wssc.prt.pnt6.core/Handlers/ajax.ashx',
data: ({
method: 'WSSC.PRT.PNT6.Appointments:PortalAppointments:getMemberVariants',
chooseMemberValue: this.state.chooseMemberValue,
rand: Math.random()
}),
type: 'POST',
success: function(result) {
this.setState({
chooseMemberVariants: result,
showChooseVariants: result.length > 3 ? true : false
});
}.bind(this)
})
},
chooseVariant: function(memberVariant){
this.setState({
chooseMemberValue: '',
chooseMemberVariants: '[{"Name":"","Surname":"","Photo":"","Position":""}]',
choosenMembersList: this.state.choosenMembersList.concat(memberVariant),
showChooseVariants: false
});
},
DeleteNewMember: function(deletedMemberIndex) {
var newMemberList = this.state.choosenMembersList;
newMemberList.splice(deletedMemberIndex, 1);
this.setState({
choosenMembersList: newMemberList
});
},
DeleteAppointment: function() {
$.ajax({
url: '/_layouts/15/wssc.prt.pnt6.core/Handlers/ajax.ashx',
data: ({
method: 'WSSC.PRT.PNT6.Appointments:PortalAppointments:DeclineAppointment',
uniqueId: this.props.editAppointmentData.UniqueId,
rand: Math.random()
}),
type: 'POST',
success: function(result) {
this.CloseBox();
}.bind(this)
})
},
render: function() {
var author = this.props.editAppointmentData.AuthorData;
var memberVariants = JSON.parse(this.state.chooseMemberVariants);
var memberVariantList = memberVariants.map((memberVariant) => {
return (
<div className="memberVariant" onClick={this.chooseVariant.bind(this, memberVariant)} key={memberVariant.Id}>
<img src={memberVariant.Photo} className="memberVariantPhoto" />
<div className="memberVariantFIO">
{memberVariant.Surname} {memberVariant.Name}
</div>
<div className="memberVariantPosition">
{memberVariant.Position}
</div>
</div>
);
});
var memberList = this.state.choosenMembersList.map((newMember,index) => {
return (
<div className="member" key={newMember.Id}>
<img className="memberPhoto" src={newMember.Photo} />
<div className="memberFIO">
{newMember.Surname} {newMember.Name}
</div>
<div className="memberPosition">
{newMember.Position}
</div>
<div className="deleteNewMember" onClick={this.DeleteNewMember.bind(this, index)}>x</div>
</div>
);
});
var Start = getDateFromJSON(this.props.editAppointmentData.StartTime);
var End = getDateFromJSON(this.props.editAppointmentData.EndTime);
return (
<div className="modalBox editBox" style={{display:this.props.displayEditBox}}>
<div className="appointmentHeader">Бронирование: {this.props.roomTitle}</div>
<div className="appointmentInfoWrap">
<div className="appointmentInfoText">Информация</div>
<div className="appointmentTime">{Start.getHours()}:{Start.getMinutes()} - {End.getHours()}:{End.getMinutes()}</div>
<div className="appointmentDate">{getDateStringFromDate(Start)}</div>
<div className="appointmentTitle"><input className="appointmentTitleValue corpBorder" placeholder="Тема" value={this.state.appointmentTitleValue} onChange={this.updateAppointmentTitleValue} /></div>
<div className="appointmentDescription"><textarea className="appointmentDescriptionValue corpBorder" placeholder="Описание" value={this.state.appointmentDescriptionValue} onChange={this.updateAppointmentDescriptionValue} ></textarea></div>
</div>
<div className="appointmentMembers">
<div className="appointmentInitiator">
Инициатор
</div>
<div className="initiatorInfo">
<div className="overInitiatorPhoto"><img src={author.Photo} className="initiatorPhoto" /></div>
<div className="initiatorName">{author.Surname} {author.Name}</div>
<div className="initiatorPostition">{author.Position}</div>
</div>
<div className="appointmentMemberListTitle">
Участники
</div>
<input type="text" className="chooseMember" onChange={this.changeMemberResults} value={this.state.chooseMemberValue} autoComplete="off" />
{this.state.showChooseVariants ? <div className="chooseMemberVariants">{memberVariantList}</div> : "" }
<div className="appointmentMemberList">
{memberList}
</div>
</div>
<div className="clear"></div>
<div className="appointmentDelete" onClick={this.DeleteAppointment}>Отменить</div>
<div className="appointmentClose" onClick={this.CloseBox}>Закрыть</div>
</div>
);
}
});
var RoomFloorFilter = React.createClass({
update: function(value) {
this.props.changeRoomFloorFilter(value);
},
render: function() {
var allFloors = this.props.data.map((room) => {
return (
room.Floor
);
});
allFloors = allFloors.sort(function(a, b) {
return a - b;
});
var distinctFloors = allFloors.filter(function(value, index, self) {
return self.indexOf(value) === index;
});
var roomFloors = distinctFloors.map((floor) => {
return (
<div className="floorFilter filterPoint" key={floor}>
<input className="floorCheckBox filterCheckBox" type="checkbox" onClick={this.update.bind(this, floor)} value={floor} />
{floor}
</div>
);
});
return (
<div className="overRoomFloorFilter">
<div className="roomFloorTitle roomFilterTitle">Этаж</div>
{roomFloors}
</div>
);
}
});
var RoomCapacityFilter = React.createClass({
update: function(value) {
this.props.changeRoomCapacityFilter(value);
},
render: function() {
var allCapacity = this.props.data.map((room) => {
return (
room.Capacity
);
});
allCapacity = allCapacity.sort(function(a, b) {
return a - b;
});
var distinctCapacity = allCapacity.filter(function(value, index, self) {
return self.indexOf(value) === index;
});
var roomCapacities = distinctCapacity.map((capacity) => {
return (
<div className="capacityFilter filterPoint" key={capacity}>
<input className="capacityCheckBox filterCheckBox" type="checkbox" onClick={this.update.bind(this, capacity)} value={capacity} />
{capacity} человек(а)
</div>
);
});
return (
<div className="overRoomCapacityFilter">
<div className="roomCapacityTitle roomFilterTitle">Вместимость</div>
{roomCapacities}
</div>
);
}
});
ReactDOM.render(
<AppointmentsComponent roomsData={roomsData} authorData={authorData} />,
document.getElementById('portalAppointmentsContainer')
);