Changeset 911 for js/human_3d_alignment/src/index.jsx
- Timestamp:
- 04/18/20 20:18:36 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
js/human_3d_alignment/src/index.jsx
r881 r911 1 1 /*global Module*/ 2 2 "use strict"; 3 import http from 'http'; 3 4 import React from 'react'; 5 import Genotypes from './utils/genotypes'; 4 6 import TitlePanel from './viewskeleton/titlepanel'; 5 7 import WidgetsContainer from './viewskeleton/widgetscontainer'; 8 import TextViewer from './widgets/textviewer'; 9 import ParmViewer from './widgets/parmviewer'; 6 10 import SimilViewer from './widgets/similviewer'; 11 import FitViewer from './widgets/fitviewer'; 12 import SliderViewer from './widgets/sliderviewer'; 13 import EndViewer from './widgets/endviewer'; 14 15 const ROUNDS = 15; 7 16 8 17 const styles = { … … 28 37 }; 29 38 30 //const mql = window.matchMedia('(min-width: 800px)');31 39 32 40 /** … … 44 52 window.genetics = new Module.PreconfiguredGenetics(); 45 53 this.layout = [ 46 {name:'0,similviewer', x: 0, y: 0, w: 12, h: 4} 54 {name:'0,textviewer', x: 0, y: 0, w: 9, h: 1}, 55 {name:'2,similviewer', x: 0, y: 1, w: 6, h: 4}, 56 {name:'3,fitviewer', x: 6, y: 1, w: 6, h: 2}, 57 {name:'4,sliderviewer', x: 6, y: 3, w: 6, h: 2}, 58 {name:'1,parmviewer', x: 9, y: 0, w: 3, h: 1} 47 59 ]; 48 60 … … 50 62 51 63 this.state = { 52 parametersmodal: false 64 genotypes: 0, 65 round: 0, 66 genotype1: '', 67 genotype2: '', 68 pairs: [], 69 id1: 0, 70 id2: 0, 71 parts1: 0, 72 parts2: 0, 73 selected1: [], 74 selected2: [], 75 position1: [0, 0, 0], 76 position2: [0, 0, 0], 77 rotation1: [0, 0, 0], 78 rotation2: [0, 0, 0], 79 userId: 0, 80 userIp: 'localhost', 81 timeStart: 0, 82 selectedGender: {value: "empty", label: " "}, 83 selectedYear: {value: "empty", label: " "}, 84 percent: 0, 85 sliderUpdated: true, 86 isDisable: true, 87 isFinished: false, 88 fitHeight: 2, 89 fitWidth: 6, 90 controlMode: 'translate', 91 blockView: true, 92 result: '' 53 93 }; 94 95 this.start = this.start.bind(this); 96 this.getIp = this.getIp.bind(this); 97 this.nextRound = this.nextRound.bind(this); 98 this.saveRound = this.saveRound.bind(this); 99 this.saveFit = this.saveFit.bind(this); 100 this.refresh = this.refresh.bind(this); 101 this.sendToServer = this.sendToServer.bind(this); 102 this.finishApp = this.finishApp.bind(this); 103 this.isReady = this.isReady.bind(this); 104 this.isFitted = this.isFitted.bind(this); 105 this.browserData = this.browserData.bind(this); 106 this.loadNewGenotypes = this.loadNewGenotypes.bind(this); 107 this.handleChangeStartTime = this.handleChangeStartTime.bind(this); 108 this.handleChangeId = this.handleChangeId.bind(this); 109 this.handleChangeIp = this.handleChangeIp.bind(this); 110 this.handleChangeGender = this.handleChangeGender.bind(this); 111 this.handleChangeYear = this.handleChangeYear.bind(this); 112 this.handleChangePercent = this.handleChangePercent.bind(this); 113 this.handleChangeStartTime = this.handleChangeStartTime.bind(this); 114 this.handleChangeFitHeight = this.handleChangeFitHeight.bind(this); 115 this.handleChangeFitWidth = this.handleChangeFitWidth.bind(this); 116 this.handleChangeControlMode = this.handleChangeControlMode.bind(this); 117 this.handleChangePosition1 = this.handleChangePosition1.bind(this); 118 this.handleChangePosition2 = this.handleChangePosition2.bind(this); 119 this.handleChangeRotation1 = this.handleChangeRotation1.bind(this); 120 this.handleChangeRotation2 = this.handleChangeRotation2.bind(this); 121 this.handleChangeBlockView = this.handleChangeBlockView.bind(this); 122 this.onClickNext = this.onClickNext.bind(this); 123 this.onClickFinish = this.onClickFinish.bind(this); 54 124 } 55 125 … … 58 128 */ 59 129 componentDidMount() { 60 this.useLayout(this.layout); 130 window.addEventListener( 'keydown', ( event ) => { 131 switch ( event.keyCode ) { 132 case 84: // T 133 this.handleChangeControlMode( "translate" ); 134 break; 135 case 82: // R 136 this.handleChangeControlMode( "rotate" ); 137 break; 138 } 139 } ); 140 let timeStart = new Date(); 141 this.handleChangeStartTime(timeStart); //set time start 142 this.handleChangeId( Math.round(timeStart.getTime() / 1000).toString() + (Math.floor(Math.random() * (9999999 - 1000000 + 1) ) + 1000000).toString() + this.browserData().toString() ); //set user id = time + random + browserData_hash 143 this.getIp(); //set user ip 144 this.genotypes = new Genotypes(this, "https://raw.githubusercontent.com/arturolejnik95/human_3d_alignment/master/walking.gen"); //load text from file to this.genotypes 145 let head = "'User ID'|'User IP'|'Gender'|'Year of born'|'Start time'|'Stop time'|'Position of 1st'|'Position of 2nd'|'Rotation of 1st'|'Rotation of 2nd'|'ID 1st'|'ID 2nd'|'Fit'|'Result'\n" 146 this.handleChangeResult(head); 61 147 } 62 148 … … 65 151 */ 66 152 componentDidUpdate() { 67 window.dispatchEvent(new Event('resize')); 153 //window.dispatchEvent(new Event('resize')); 154 if (this.state.genotype1 != '' && this.state.genotype2 != '') { 155 this.useLayout(this.layout); 156 } 157 } 158 159 160 /** 161 * Start questionnaire if genotypes are loaded 162 */ 163 start() { 164 this.setState({ genotypes: this.genotypes.id.length }, function() { 165 console.log(`Genotypes: `, this.state.genotypes); 166 }); 167 168 this.loadNewGenotypes(); 169 this.handleChangeBlockView(false); 170 this.useLayout(this.layout); 171 } 172 173 getIp() { 174 http.get({'host': 'api.ipify.org', 'port': 80, 'path': '/'}, (resp) => { 175 resp.on('data', ip => { 176 this.handleChangeIp(ip) 177 }); 178 }); 179 } 180 181 /** 182 * Save data about this round 183 */ 184 saveRound() { 185 this.setState({ sliderUpdated: false }, function() { 186 console.log('Slider Updated: ' + this.state.sliderUpdated); 187 }); 188 this.isReady(); 189 } 190 191 /** 192 * Preset result as: 193 * user ID - IP - gender - year of born - start : end - position of 1. : position of 2. 194 * - rotation of 1. : rotation of 2. - id of 1. : id of second - pairs (1. mesh : 2. mesh) - fit result (0 - 100) ; 195 */ 196 saveFit() { 197 let min = Math.min(this.state.parts1, this.state.parts2); 198 let timeStop = new Date(); 199 let start = this.state.timeStart; 200 let stop = timeStop; 201 start = ("0" + start.getDate()).slice(-2) + '.' + ("0" + (start.getMonth() + 1)).slice(-2) + '.' + start.getFullYear() + ' ' + String(start.getHours()).padStart(2, '0') + ':' + String(start.getMinutes()).padStart(2, '0') + ':' + String(start.getSeconds()).padStart(2, '0'); 202 stop = ("0" + stop.getDate()).slice(-2) + '.' + ("0" + (stop.getMonth() + 1)).slice(-2) + '.' + stop.getFullYear() + ' ' + String(stop.getHours()).padStart(2, '0') + ':' + String(stop.getMinutes()).padStart(2, '0') + ':' + String(stop.getSeconds()).padStart(2, '0'); 203 204 let fit = this.state.userId + '|' + 205 this.state.userIp + '|' + 206 this.state.selectedGender.value + '|' + 207 this.state.selectedYear.value + '|' + 208 start + '|' + 209 stop + '|' + 210 '(' + this.state.position1[0] + ',' + this.state.position1[1] + ',' + this.state.position1[2] + ')|' + 211 '(' + this.state.position2[0] + ',' + this.state.position2[1] + ',' + this.state.position2[2] + ')|' + 212 '(' + this.state.rotation1[0] + ',' + this.state.rotation1[1] + ',' + this.state.rotation1[2] + ')|' + 213 '(' + this.state.rotation2[0] + ',' + this.state.rotation2[1] + ',' + this.state.rotation2[2] + ')|'; 214 215 216 let pair = this.state.pairs[this.state.pairs.length - 1]; 217 fit = fit + this.genotypes.id[pair[0]] + '|' + this.genotypes.id[pair[1]] + '|'; 218 219 for (let i = 0; i < min; i++) { 220 fit = fit + this.state.selected1[i] + ':' + (this.state.selected2[i].charCodeAt(0) - 65 + 1); 221 if (i < min - 1) { 222 fit = fit + ';'; 223 } 224 } 225 fit = fit + '|' + this.state.percent + '\n'; 226 227 this.sendToServer(fit); 228 229 this.handleChangeResult(this.state.result + fit); 230 this.handleChangeStartTime(timeStop); 231 } 232 233 234 235 sendToServer(fit) { 236 let rawFile = new XMLHttpRequest(); 237 rawFile.addEventListener('load', () => { 238 console.log(rawFile.responseText); 239 }); 240 rawFile.addEventListener('error', () => { 241 console.log('Błąd wysyłania na serwer'); 242 }); 243 244 rawFile.open("POST", 'https://ptsv2.com/t/b7nhq-1578108725/post'); 245 rawFile.setRequestHeader("Content-type", 'text/plain'); 246 rawFile.send(fit); 247 } 248 249 /** 250 * Load next pair of genotypes 251 */ 252 nextRound() { 253 this.loadNewGenotypes(); 254 this.handleChangeBlockView(false); 255 } 256 257 /** 258 * Refresh used default layout 259 */ 260 refresh() { 261 this.useLayout(this.layout); 262 } 263 264 /** 265 * Load new genotypes to simulator viewer 266 */ 267 loadNewGenotypes() { 268 //Firstly it chooses pair of genotypes that user doesnt used before 269 let rand1, rand2, amount1, amount2, gen1, gen2; 270 271 do { 272 rand1 = 0, rand2 = 0; 273 do { 274 while (rand1 == rand2) { 275 rand1 = Math.floor(Math.random() * this.state.genotypes); 276 rand2 = Math.floor(Math.random() * this.state.genotypes); 277 } 278 } while (this.state.pairs.includes([rand1, rand2]) || this.state.pairs.includes([rand2, rand1])); 279 280 //This part load genotypes to the state 281 gen1 = this.genotypes.genotype[rand1]; 282 gen2 = this.genotypes.genotype[rand2]; 283 amount1 = gen1.split('').filter(function(sign){return sign === 'X'}).length; 284 amount2 = gen2.split('').filter(function(sign){return sign === 'X'}).length; 285 if (amount1 > 0) { 286 amount1++; 287 } 288 if (amount2 > 0) { 289 amount2++ 290 } 291 } while (amount1 > 52 || amount2 > 52); 292 293 let newpairs = this.state.pairs; 294 if (amount1 <= amount2) { 295 newpairs.push([rand1, rand2]); 296 this.setState({ genotype1: gen1, genotype2: gen2 }, function() { 297 console.log(`Genotypes: `, this.state.genotype1, this.state.genotype2); 298 }); 299 this.setState({parts1: amount1, parts2: amount2}, function() { 300 console.log(this.state.parts1 + ' ' + this.state.parts2); 301 }); 302 } else { 303 newpairs.push([rand2, rand1]); 304 this.setState({ genotype1: gen2, genotype2: gen1 }, function() { 305 console.log(`Genotypes: `, this.state.genotype1, this.state.genotype2); 306 }); 307 this.setState({parts1: amount2, parts2: amount1}, function() { 308 console.log(this.state.parts1 + ' ' + this.state.parts2); 309 }); 310 } 311 this.setState({ pairs: newpairs }, function() { 312 console.log(`Pairs: `, this.state.pairs); 313 }); 314 315 //Load tables of selected parts in fitviewer 316 let min = Math.min(amount1, amount2); 317 let s1 = []; 318 let s2 = []; 319 for (let i = 0; i < min; i++) { 320 s1.push((i+1).toString()); 321 s2.push(' '); 322 } 323 324 //Start new round and load to state tables of selected and round 325 let r = this.state.round + 1; 326 this.setState({ round: r, selected1: s1, selected2: s2}, function() { 327 console.log(`Round and state `, this.state.round + '. ' + this.state.selected1 + ' ' + this.state.selected2); 328 }); 329 } 330 331 /** 332 * Check is user ready to go to the next question by checking choosed gender, birth year and percent of similarity 333 */ 334 isReady() { 335 if (this.state.selectedGender.value != 'empty' && this.state.selectedYear.value != 'empty' && this.state.sliderUpdated) { 336 this.setState({isDisable: false}, function() { 337 console.log(this.state.isDisable); 338 }); 339 } else { 340 if (!this.state.isDisable) { 341 this.setState({isDisable: true}, function() { 342 console.log(this.state.isDisable); 343 }); 344 } 345 } 346 } 347 348 /** 349 * Check is user matched all needed sticks 350 */ 351 isFitted() { 352 let index1 = this.state.selected1.indexOf(' '); 353 let index2 = this.state.selected2.indexOf(' '); 354 355 if (index1 < 0 && index2 < 0 && this.state.sliderUpdated) { 356 this.setState({sliderUpdated: false}, function() { 357 console.log(this.state.sliderUpdated); 358 this.isReady(); 359 }); 360 } 361 } 362 363 /** 364 * Return hash data of browser 365 */ 366 browserData() { 367 let data = navigator.userAgent; 368 let hash = 0; 369 for (let i = 0; i < data.length; i++) { 370 let character = data.charCodeAt(i); 371 hash = ((hash<<5)-hash)+character; 372 hash = hash & hash; // Convert to 32bit integer 373 } 374 return hash; 375 } 376 377 /** 378 * Performed at the end of the survey 379 */ 380 finishApp() { 381 this.layout = [ 382 {name:'5,endviewer', x: 0, y: 0, w: 12, h: 4} 383 ]; 384 this.useLayout(this.layout); 385 } 386 387 /** 388 * Allow to change gender in state 389 * @param {string} gen choosed gender by user in listbox 390 */ 391 handleChangeGender(gen) { 392 this.setState({ selectedGender: gen }, function() { 393 console.log(`Gender selected:`, this.state.selectedGender); 394 console.log(this.genotypes.id.length) 395 this.isReady(); 396 }); 397 }; 398 399 /** 400 * Allow to change IP 401 * @param {number} ip user IP 402 */ 403 handleChangeIp(ip) { 404 this.setState({ userIp: ip }, function() { 405 console.log(`IP:`, this.state.userIp); 406 }); 407 } 408 409 /** 410 * Allow to change user ID 411 * @param {number} id user ID 412 */ 413 handleChangeId(id) { 414 this.setState({ userId: id }, function() { 415 console.log(`ID:`, this.state.userId); 416 }); 417 } 418 419 /** 420 * Allow to change start time 421 * @param {number} time time of begging fitting framsticks 422 */ 423 handleChangeStartTime(time) { 424 this.setState({ timeStart: time }, function() { 425 console.log(`Start time:`, this.state.timeStart); 426 }); 427 } 428 429 /** 430 * Allow to change birth year in state 431 * @param {number} year choosed birth year by user in listbox 432 */ 433 handleChangeYear(year) { 434 this.setState({ selectedYear: year }, function() { 435 console.log(`Birth year selected:`, this.state.selectedYear); 436 this.isReady(); 437 }); 438 } 439 440 /** 441 * Allow to change percent in state and mark this in state.sliderUpdated 442 * @param {Integer} per choosed similarity of framsticks by user in percentage 443 */ 444 handleChangePercent(per) { 445 this.setState({ percent: per, sliderUpdated: true }, function() { 446 console.log('Percent selected: ' + this.state.percent + ' ' + this.state.sliderUpdated); 447 this.isReady(); 448 }); 449 } 450 451 /** 452 * 453 * @param {number} nr framstick id 454 * @param {number} pos position on the match map 455 * @param {*} val id of choosed stick 456 */ 457 handleChangeSelected(nr, pos, val) { 458 if (nr == 1) { 459 this.setState(state => { 460 const selected1 = state.selected1.map((item, i) => { 461 if (pos === i) { 462 return val; 463 } else { 464 return item; 465 } 466 }); 467 468 return { 469 selected1, 470 }; 471 }, function() { 472 console.log(this.state.selected1); 473 this.isFitted(); 474 }); 475 } else { 476 this.setState(state => { 477 const selected2 = state.selected2.map((item, i) => { 478 if (pos === i) { 479 let v = val.charCodeAt(0); 480 if (v > 90) { 481 v = v - 6; 482 } 483 let res = String.fromCharCode(v); 484 return res; 485 } else { 486 return item; 487 } 488 }); 489 490 return { 491 selected2, 492 }; 493 }, function() { 494 console.log(this.state.selected2); 495 this.isFitted(); 496 }); 497 } 498 } 499 500 /** 501 * Function to inform fitviewer about change of height to update scrollbar (for firefox) 502 * @param {number} h height 503 */ 504 handleChangeFitHeight(h) { 505 this.setState({ fitHeight: h }, function() { 506 console.log(`Fit Height:`, this.state.fitHeight); 507 }); 508 } 509 510 /** 511 * Function to inform fitviewer about change of width to update scrollbar (for firefox) 512 * @param {number} w width 513 */ 514 handleChangeFitWidth(w) { 515 this.setState({ fitWidth: w }, function() { 516 console.log(`Fit Width:`, this.state.fitWidth); 517 }); 518 } 519 520 /** 521 * Allow to change transform controler mode 522 * @param {number} mode translate or rotation 523 */ 524 handleChangeControlMode(mode) { 525 this.setState({ controlMode: mode }, function() { 526 console.log(`Control mode:`, this.state.controlMode); 527 }); 528 } 529 530 /** 531 * Allow to save actural position of first genotype 532 * @param {Array} pos position [x, y, z] of first genotype 533 */ 534 handleChangePosition1(pos) { 535 this.setState({ position1: pos}, function() { 536 console.log('Position1: ', this.state.position1); 537 }); 538 } 539 540 /** 541 * Allow to save actural position of second genotype 542 * @param {Array} pos position [x, y, z] of second genotype 543 */ 544 handleChangePosition2(pos) { 545 this.setState({ position2: pos}, function() { 546 console.log('Position2: ', this.state.position2); 547 }); 548 } 549 550 /** 551 * Allow to save actural rotation of first genotype 552 * @param {Array} rot rotation [x, y, z] of first genotype 553 */ 554 handleChangeRotation1(rot) { 555 this.setState({ rotation1: rot}, function() { 556 console.log('Rotation1: ', this.state.rotation1); 557 }); 558 } 559 560 /** 561 * Allow to save actural rotation of second genotype 562 * @param {Array} rot rotation [x, y, z] of second genotype 563 */ 564 handleChangeRotation2(rot) { 565 this.setState({ rotation2: rot}, function() { 566 console.log('Rotation2: ', this.state.rotation2); 567 }); 568 } 569 570 /** 571 * Allow to block view in simviewer 572 * @param {Array} rot rotation [x, y, z] of second genotype 573 */ 574 handleChangeBlockView(bool) { 575 this.setState({ blockView: bool}, function() { 576 console.log('Block View: ', this.state.blockView); 577 }); 578 } 579 580 /** 581 * Allow to change finish result that will be save in the file at the end 582 * @param {string} res text to be save in file 583 */ 584 handleChangeResult(res) { 585 this.setState({ result: res }, function() { 586 console.log('Result: ', this.state.result); 587 }); 588 } 589 590 /** 591 * Next button function 592 */ 593 onClickNext() { 594 this.handleChangeBlockView(true); 595 this.saveFit(); 596 if (this.state.round == ROUNDS) { 597 this.setState({ isFinished: true }, function() { 598 console.log('Finish state: ' + this.state.isFinished); 599 600 if (this.state.isFinished) { 601 this.finishApp(); 602 } 603 }); 604 } else { 605 this.nextRound(); 606 } 607 } 608 609 /** 610 * Close button function 611 */ 612 onClickFinish() { 613 this.setState({ isFinished: true }, function() { 614 console.log('Finish state: ' + this.state.isFinished); 615 616 if (this.state.isFinished) { 617 this.finishApp(); 618 } 619 }); 68 620 } 69 621 … … 76 628 for (let i = 0; i < layout.length; i++) { 77 629 newlayout.push({name: layout[i].i, x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 630 if (newlayout[i].name == '2fitviewer') { 631 this.handleChangeFitHeight(newlayout[i].h); 632 this.handleChangeFitWidth(newlayout[i].w); 633 } 78 634 } 79 635 } … … 87 643 let name = layout[i].name.split(',')[1]; 88 644 switch (name) { 645 case 'textviewer': 646 items.push({content: <TextViewer/>, i: "" + i + 'textviewer', 647 x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 648 break; 89 649 case 'similviewer': 90 items.push({content: <SimilViewer/>, i: "" + i + 'similviewer', 650 items.push({content: <SimilViewer 651 genotype1 = {this.state.genotype1} 652 genotype2 = {this.state.genotype2} 653 selected1 = {this.state.selected1} 654 selected2 = {this.state.selected2} 655 blockView = {this.state.blockView} 656 handleChangePosition1 = {(pos) => this.handleChangePosition1(pos)} 657 handleChangePosition2 = {(pos) => this.handleChangePosition2(pos)} 658 handleChangeRotation1 = {(rot) => this.handleChangeRotation1(rot)} 659 handleChangeRotation2 = {(rot) => this.handleChangeRotation2(rot)} 660 controlMode = {this.state.controlMode} 661 round = {this.state.round}/>, 662 i: "" + i + 'similviewer', 663 x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 664 break; 665 case 'parmviewer': 666 items.push({content: <ParmViewer 667 handleChangeYear = {(year) => {this.handleChangeYear(year)}} 668 handleChangeGender = {(gen) => {this.handleChangeGender(gen)}} 669 />, 670 i: "" + i + 'parmviewer', 671 x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 672 break; 673 case 'fitviewer': 674 items.push({content: <FitViewer 675 selected1 = {this.state.selected1} 676 selected2 = {this.state.selected2} 677 parts1 = {this.state.parts1} 678 parts2 = {this.state.parts2} 679 fitHeight = {this.state.fitHeight} 680 fitWidth = {this.state.fitWidth} 681 handleChangeSelected = {(nr, pos, val) => {this.handleChangeSelected(nr, pos, val)}}/>, 682 i: "" + i + 'fitviewer', 683 x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 684 break; 685 case 'sliderviewer': 686 items.push({content: <SliderViewer 687 isDisable = {this.state.isDisable} 688 parts1 = {this.state.parts1} 689 parts2 = {this.state.parts2} 690 selected1 = {this.state.selected1} 691 selected2 = {this.state.selected2} 692 onClickNext = {() => {this.onClickNext()}} 693 onClickFinish = {() => {this.onClickFinish()}} 694 handleChangePercent = {(per) => {this.handleChangePercent(per)}}/>, 695 i: "" + i + 'sliderviewer', 696 x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 697 break; 698 case 'endviewer': 699 items.push({content: <EndViewer 700 userId = {this.state.userId} 701 result = {this.state.result}/>, 702 i: "" + i + 'endviewer', 91 703 x: layout[i].x, y: layout[i].y, w: layout[i].w, h: layout[i].h}); 92 704 break; … … 104 716 const contentHeader = ( 105 717 <span> 106 <span style={{marginLeft: '20px'}}>Matching in 3D</span> 718 <span style={{marginLeft: '20px', fontFamily: "'Fira Mono', Monaco, 'Andale Mono', 'Lucida Console', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace"}}> 719 Ankieta 720 </span> 107 721 </span> 108 722 ); 109 723 110 724 return ( 111 <TitlePanel title={contentHeader}> 112 <div style={styles.content}> 113 {this.container} 114 </div> 115 </TitlePanel> 725 <TitlePanel 726 title={contentHeader} 727 > 728 <div style={styles.content}> 729 {this.container} 730 </div> 731 </TitlePanel> 116 732 ); 117 733 }
Note: See TracChangeset
for help on using the changeset viewer.