14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Program",
|
||||
"program": "${workspaceFolder}/backend/app.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
182
backend/app.js
182
backend/app.js
@@ -88,7 +88,7 @@ function storeToken(token) {
|
||||
try {
|
||||
fs.mkdirSync(TOKEN_DIR);
|
||||
} catch (err) {
|
||||
if (err.code != 'EEXIST') {
|
||||
if (err.code !== 'EEXIST') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -109,11 +109,15 @@ function getPairs(callback){
|
||||
if(err) {
|
||||
// Handle error
|
||||
console.log(err);
|
||||
return null;
|
||||
callback(null, true);
|
||||
} else {
|
||||
const pairs = [];
|
||||
|
||||
try{
|
||||
lastRow = result.valueRanges[0].values.length;
|
||||
}catch(err){
|
||||
lastRow = 0;
|
||||
}
|
||||
|
||||
for (let i=0;i<lastRow;i++){
|
||||
let name1 = result.valueRanges[0].values[i][0];
|
||||
@@ -122,7 +126,7 @@ function getPairs(callback){
|
||||
pairs.push({name1:name1,name2:name2});
|
||||
}
|
||||
}
|
||||
callback(pairs);
|
||||
callback(pairs,false);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -139,74 +143,171 @@ function getAvailableNames(callback){
|
||||
if(err) {
|
||||
// Handle error
|
||||
console.log(err);
|
||||
return null;
|
||||
callback(null, true);
|
||||
} else {
|
||||
const names = [];
|
||||
|
||||
for (let i=0;i<result.valueRanges[0].values.length;i++){
|
||||
|
||||
try{
|
||||
let name = result.valueRanges[0].values[i][0];
|
||||
let available = result.valueRanges[1].values[i][0];
|
||||
|
||||
if (name && (available=='x')){
|
||||
if (name && (available==='x')){
|
||||
names.push(name);
|
||||
}
|
||||
}catch(err){
|
||||
}
|
||||
callback(names);
|
||||
|
||||
}
|
||||
callback(names,false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function MakePairs(callback){
|
||||
executeAPI(getAvailableNames,function(names){
|
||||
executeAPI(getPairs, function(pairs){
|
||||
let next_i=false;
|
||||
const newPairs = [];
|
||||
const usedNames = [];
|
||||
for (let i=0;i<names.length;i++){
|
||||
next_i=false;
|
||||
for (let j=0;j<names.length;j++){
|
||||
if (i!=j){
|
||||
var matrix = [];
|
||||
var tree = [];
|
||||
let done = false;
|
||||
|
||||
function count_pairs(row, col, cntr){
|
||||
if (done) return;
|
||||
|
||||
matrix[row][col] = 2;
|
||||
|
||||
//mark all fields in matrix related to row and col names
|
||||
for(let i=0;i<row;i++) matrix[row][i] = (matrix[row][i]===0)? cntr: matrix[row][i];
|
||||
for(let i=0;i<col;i++) matrix[col][i] = (matrix[col][i]===0)? cntr: matrix[col][i];
|
||||
|
||||
for(let i=row;i<matrix.length;i++) matrix[i][row] = (matrix[i][row]===0)? cntr: matrix[i][row];
|
||||
for(let i=col;i<matrix.length;i++) matrix[i][col] = (matrix[i][col]===0)? cntr: matrix[i][col];
|
||||
|
||||
//find next pair
|
||||
|
||||
let found = false;
|
||||
for (let i=0;i<matrix.length;i++){
|
||||
for (let j=0;j<=i;j++){
|
||||
if (matrix[i][j]===0){
|
||||
count_pairs(i,j,cntr+1);
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found){
|
||||
let inner_tree = [];
|
||||
for (let i=0;i<matrix.length;i++){
|
||||
for (let j=0;j<=i;j++){
|
||||
if (matrix[i][j]===2){
|
||||
inner_tree.push({row: i, col:j});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inner_tree.length === max_pairs) {
|
||||
done=true;
|
||||
tree.push(inner_tree);
|
||||
}
|
||||
}
|
||||
|
||||
//remove marks from matrix
|
||||
for(let i=0;i<row;i++) matrix[row][i] = (matrix[row][i]===cntr)? 0: matrix[row][i];
|
||||
for(let i=0;i<col;i++) matrix[col][i] = (matrix[col][i]===cntr)? 0: matrix[col][i];
|
||||
|
||||
for(let i=row;i<matrix.length;i++) matrix[i][row] = (matrix[i][row]===cntr)? 0: matrix[i][row];
|
||||
for(let i=col;i<matrix.length;i++) matrix[i][col] = (matrix[i][col]===cntr)? 0: matrix[i][col];
|
||||
|
||||
matrix[row][col] = 0;
|
||||
}
|
||||
|
||||
function MakePairsV3(callback){
|
||||
executeAPI(getAvailableNames,function(names,error){
|
||||
if (error){
|
||||
console.log("Error - could not load names");
|
||||
callback.send({pairs: null, left: null, error: true, error_message: 'Could not load names list'});
|
||||
return;
|
||||
}
|
||||
executeAPI(getPairs, function(pairs,error){
|
||||
if (error){
|
||||
console.log("Error - could not load pairs");
|
||||
callback.send({pairs: null, left: null, error: true, error_message: 'Could not load pairs list'});
|
||||
return;
|
||||
}
|
||||
max_pairs = Math.floor(names.length/2);
|
||||
matrix=[];
|
||||
|
||||
for (let i=0;i<names.length;i++){
|
||||
let matrix_row = [];
|
||||
for (let j=0;j<=i;j++) (i===j)? matrix_row.push(1):matrix_row.push(0);
|
||||
matrix.push(matrix_row);
|
||||
}
|
||||
|
||||
//Mark existing pairs, put 3 in matrix fields
|
||||
pairs.filter((pair)=>{
|
||||
if ((pair.name1==names[i] && pair.name2==names[j])||(pair.name1==names[j] && pair.name2==names[i])){
|
||||
found=true;
|
||||
return;
|
||||
|
||||
let name1_id = names.indexOf(pair.name1);
|
||||
let name2_id = names.indexOf(pair.name2);
|
||||
|
||||
if (name1_id !== -1 && name2_id !== -1){
|
||||
if (name1_id > name2_id){
|
||||
matrix[name1_id][name2_id] = 3;
|
||||
}else{
|
||||
matrix[name2_id][name1_id] = 3;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!found){
|
||||
usedNames.filter((name)=>{
|
||||
if (names[i] === name || names[j] === name){
|
||||
found=true;
|
||||
return;
|
||||
tree = [];
|
||||
done=false;
|
||||
|
||||
for (let i=0;i<names.length;i++){
|
||||
for (let j=0;j<=i;j++){
|
||||
if (matrix[i][j] === 0){
|
||||
count_pairs(i,j,5);
|
||||
if (done) break;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (done) break;
|
||||
}
|
||||
|
||||
let max_count_index = 0;
|
||||
|
||||
if (!found){
|
||||
next_i=true;
|
||||
newPairs.push({name1:names[i], name2:names[j]});
|
||||
usedNames.push(names[i]);
|
||||
usedNames.push(names[j]);
|
||||
break;
|
||||
for (let i=0;i<tree.length;i++){
|
||||
if (tree[i].length > tree[max_count_index].length)
|
||||
max_count_index = i;
|
||||
}
|
||||
|
||||
let result_pairs = [];
|
||||
if (tree.length > 0){
|
||||
for (let i=0;i<tree[max_count_index].length;i++){
|
||||
result_pairs.push({name1: names[tree[max_count_index][i].row],name2: names[tree[max_count_index][i].col] });
|
||||
}
|
||||
|
||||
let indexToRemove = [];
|
||||
|
||||
for (let i=0;i<tree[max_count_index].length;i++){
|
||||
indexToRemove.push(tree[max_count_index][i].row);
|
||||
indexToRemove.push(tree[max_count_index][i].col);
|
||||
}
|
||||
if (next_i) continue;
|
||||
|
||||
indexToRemove.sort((a,b)=>{
|
||||
if (a>b) return -1; else return 1;
|
||||
});
|
||||
|
||||
for (let i=0;i<indexToRemove.length;i++)
|
||||
names.splice(indexToRemove[i],1);
|
||||
}
|
||||
pairsForSave=newPairs;
|
||||
callback.send(newPairs);
|
||||
|
||||
if (names.length === 0) names=null;
|
||||
pairsForSave = result_pairs;
|
||||
callback.send({pairs: result_pairs, left: names, error:false});
|
||||
});
|
||||
});
|
||||
//Napravi par -> Provjeri da li postoji -> Snimi ili ponovi postupak
|
||||
|
||||
}
|
||||
|
||||
function SavePairs(callback){
|
||||
if (lastRow== null) return;
|
||||
if (lastRow=== null) {
|
||||
callback.send({result:true});
|
||||
return;
|
||||
}
|
||||
|
||||
auth=oauth2Client;
|
||||
|
||||
@@ -220,6 +321,7 @@ function SavePairs(callback){
|
||||
|
||||
const data = [];
|
||||
|
||||
if (lastRow === 0) lastRow=-1;
|
||||
let range1= '2017!A'+(lastRow+2)+':A'+(lastRow+2+pairsForSave.length);
|
||||
let range2= '2017!B'+(lastRow+2)+':B'+(lastRow+2+pairsForSave.length);
|
||||
|
||||
@@ -269,15 +371,13 @@ app.use(function(req, res, next) {
|
||||
app.get('/getPairs',(req,resp)=>{
|
||||
pairsForSave=[];
|
||||
lastRow=null;
|
||||
MakePairs(resp);
|
||||
MakePairsV3(resp);
|
||||
});
|
||||
|
||||
app.get('/savePairs', (req,resp)=>{
|
||||
SavePairs(resp);
|
||||
//resp.send({result:true});
|
||||
});
|
||||
|
||||
|
||||
app.listen(3005, function () {
|
||||
console.log('server na portu 3005');
|
||||
console.log("Server running - Port 3005");
|
||||
})
|
||||
@@ -18,10 +18,10 @@ class App extends Component {
|
||||
getPairsEventHandler = (event) =>{
|
||||
let url = `http://${BASE_URL}:3005/getPairs`;
|
||||
|
||||
this.setState({waitingPairs:true});
|
||||
this.setState({waitingPairs:true, renderFinish:false, waitingSave:true});
|
||||
|
||||
fetch(url, {}).then(function(response) { return response.json(); }).then(function(data) {
|
||||
this.setState({pairs : data, renderPairsList:true, waitingPairs:false});
|
||||
this.setState({pairs : data.pairs, left:data.left, renderPairsList:!data.error, waitingPairs:false, waitingSave:false, error: data.error, error_message: data.error_message});
|
||||
}.bind(this));
|
||||
|
||||
|
||||
@@ -46,13 +46,32 @@ class App extends Component {
|
||||
<div className = "horizontalDiv">
|
||||
<button disabled={this.state.waitingPairs} onClick = {this.getPairsEventHandler}>Get pairs</button>
|
||||
</div>
|
||||
{
|
||||
this.state.error &&
|
||||
<div>
|
||||
<h2> Error - {this.state.error_message} </h2>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.state.renderPairsList &&
|
||||
<div>
|
||||
<h2> List of pairs : </h2>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.state.renderPairsList &&
|
||||
<PairsListComponent pairs = {this.state.pairs}/>
|
||||
}
|
||||
{
|
||||
this.state.renderPairsList && this.state.left &&
|
||||
<div>
|
||||
<h2> Without pair : </h2>
|
||||
{
|
||||
this.state.left.map((name, index) =>
|
||||
(<div key={name}>{index+1}. {name}</div>))
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.state.renderPairsList &&
|
||||
<button disabled={this.state.waitingSave} onClick = {this.savePairsEventHandler}> Save pairs </button>
|
||||
|
||||
@@ -3,14 +3,14 @@ import React, { Component } from 'react';
|
||||
export default class PairComponent extends Component{
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {pairName: this.props.pair};
|
||||
this.state = {pairName: this.props.pair, index: this.props.index};
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div>
|
||||
<div className = "horizontalDiv">
|
||||
<div>{this.state.pairName.name1} - {this.state.pairName.name2}</div>
|
||||
<div>{this.state.index+1}. {this.state.pairName.name1} - {this.state.pairName.name2}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ export default class PairsListComponent extends Component{
|
||||
<div id = "outerDiv">
|
||||
{
|
||||
this.props.pairs.map((pair, index) =>
|
||||
(<PairComponent key = {index} index = {index} pair = {pair}/>))
|
||||
(<PairComponent key = {pair.name1+pair.name2} index = {index} pair = {pair}/>))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user