707 lines
28 KiB
JavaScript
707 lines
28 KiB
JavaScript
(function () {
|
|
const Ribc = window.RIBC = {};
|
|
const Admin = Ribc.admin = {};
|
|
|
|
Ribc.init = function (isSubAdmin = false) {
|
|
return new Promise((resolve, reject) => {
|
|
Promise.all([Ribc.refreshObjectData(), Ribc.refreshGeneralData(isSubAdmin)])
|
|
.then(results => resolve(results))
|
|
.catch(error => reject(error))
|
|
})
|
|
}
|
|
|
|
Ribc.refreshObjectData = () => {
|
|
return new Promise((resolve, reject) => {
|
|
floCloudAPI.requestObjectData("RIBC").then(result => {
|
|
if (!floGlobals.appObjects.RIBC)
|
|
floGlobals.appObjects.RIBC = {};
|
|
var objectList = ["projectMap", "projectBranches", "projectTaskDetails", "projectDetails", "internList", "internRating", "internRecord", "internsAssigned", "projectTaskStatus", "displayedTasks"]
|
|
objectList.forEach(obj => {
|
|
if (!floGlobals.appObjects.RIBC[obj])
|
|
floGlobals.appObjects.RIBC[obj] = {};
|
|
_[obj] = floGlobals.appObjects.RIBC[obj];
|
|
});
|
|
//_.projectMap = floGlobals.appObjects.RIBC.projectMap;
|
|
//this.lastCommit = JSON.stringify(floGlobals.appObjects.RIBC);
|
|
resolve('Object Data Refreshed Successfully')
|
|
}).catch(error => reject(error))
|
|
})
|
|
}
|
|
|
|
Ribc.refreshGeneralData = (isSubAdmin) => {
|
|
return new Promise((resolve, reject) => {
|
|
var generalDataList = ["InternUpdates"],
|
|
subAdminOnlyList = [],
|
|
selfOnlyList = [];
|
|
(isSubAdmin ? generalDataList : selfOnlyList).push("TaskRequests", "InternRequests");
|
|
let promises = [];
|
|
for (let data of generalDataList)
|
|
promises.push(floCloudAPI.requestGeneralData(data))
|
|
for (let data of subAdminOnlyList)
|
|
promises.push(floCloudAPI.requestGeneralData(data, {
|
|
senderID: floGlobals.subAdmins
|
|
}));
|
|
for (let data of selfOnlyList)
|
|
promises.push(floCloudAPI.requestGeneralData(data, {
|
|
senderID: floDapps.user.id
|
|
}));
|
|
Promise.all(promises)
|
|
.then(results => resolve('General Data Refreshed Successfully'))
|
|
.catch(error => reject(error))
|
|
})
|
|
}
|
|
|
|
const _ = {}; //private variable holder
|
|
|
|
Ribc.applyForIntern = (details) => new Promise((resolve, reject) => {
|
|
floCloudAPI.sendGeneralData(details, "InternRequests")
|
|
.then(results => resolve(results))
|
|
.catch(error => reject(error))
|
|
});
|
|
|
|
Ribc.postInternUpdate = (updates) => new Promise((resolve, reject) => {
|
|
floCloudAPI.sendGeneralData(updates, "InternUpdates")
|
|
.then(results => resolve(results))
|
|
.catch(error => reject(error))
|
|
});
|
|
|
|
Ribc.getInternUpdates = function (count = null) {
|
|
let internUpdates = Object.values(floGlobals.generalDataset("InternUpdates")).map(data => {
|
|
return {
|
|
floID: data.senderID,
|
|
update: data.message,
|
|
time: data.vectorClock.split('_')[0],
|
|
note: data.note,
|
|
tag: data.tag
|
|
}
|
|
})
|
|
internUpdates = internUpdates.filter(data => data.floID in _.internList)
|
|
internUpdates.reverse()
|
|
if (count && count < internUpdates.length)
|
|
internUpdates = internUpdates.slice(0, count)
|
|
return internUpdates;
|
|
}
|
|
|
|
Admin.commentInternUpdate = (vectorClock, comment) => new Promise((resolve, reject) => {
|
|
if (!(vectorClock in floGlobals.generalDataset("InternUpdates")))
|
|
return reject("Intern update not found");
|
|
floCloudAPI.noteApplicationData(vectorClock, comment)
|
|
.then(result => resolve(result))
|
|
.catch(error => reject(error))
|
|
});
|
|
|
|
Ribc.applyForTask = (details) => new Promise((resolve, reject) => {
|
|
floCloudAPI.sendGeneralData(details, "TaskRequests")
|
|
.then(result => resolve(result))
|
|
.catch(error => reject(error))
|
|
});
|
|
|
|
Ribc.getProjectList = () => Object.keys(_.projectMap);
|
|
Ribc.getProjectDetails = (project) => _.projectDetails[project];
|
|
Ribc.getProjectMap = (project) => _.projectMap[project];
|
|
Ribc.getProjectBranches = (project) => findAllBranches(project);
|
|
Ribc.getTaskDetails = (taskId) => _.projectTaskDetails[taskId];
|
|
Ribc.getTaskStatus = (taskId) => _.projectTaskStatus[taskId];
|
|
Ribc.getInternList = () => _.internList;
|
|
Ribc.getInternRating = (floID) => _.internRating[floID] || 0;
|
|
Ribc.getInternRecord = (floID) => _.internRecord[floID] || {};
|
|
Ribc.getAssignedInterns = (taskId) => _.internsAssigned[taskId] || [];
|
|
Ribc.getAllTasks = () => _.projectTaskDetails
|
|
Ribc.getDisplayedTasks = () => floGlobals.appObjects.RIBC.displayedTasks || [];
|
|
|
|
Admin.updateObjects = () => new Promise((resolve, reject) => {
|
|
floCloudAPI.updateObjectData("RIBC")
|
|
.then(result => resolve(result))
|
|
.catch(error => reject(error))
|
|
});
|
|
|
|
Admin.resetObjects = () => new Promise((resolve, reject) => {
|
|
floCloudAPI.resetObjectData("RIBC")
|
|
.then(result => resolve(result))
|
|
.catch(error => reject(error))
|
|
});
|
|
|
|
Admin.addProjectDetails = function (projectCode, details) {
|
|
if (!(projectCode in _.projectMap))
|
|
return "Project not Found!";
|
|
if (projectCode in _.projectDetails && typeof projectCode === 'object' && typeof details === 'object')
|
|
for (let d in details)
|
|
_.projectDetails[projectCode][d] = details[d];
|
|
else
|
|
_.projectDetails[projectCode] = details;
|
|
return "added project details for " + projectCode;
|
|
}
|
|
|
|
Ribc.getInternRequests = function (ignoreProcessed = true) {
|
|
var internRequests = Object.values(floGlobals.generalDataset("InternRequests")).map(data => {
|
|
return {
|
|
floID: data.senderID,
|
|
vectorClock: data.vectorClock,
|
|
details: data.message,
|
|
status: data.note,
|
|
}
|
|
})
|
|
//filter existing interns
|
|
internRequests = internRequests.filter(data => !(data.floID in _.internList))
|
|
//filter processed requests
|
|
if (ignoreProcessed)
|
|
internRequests = internRequests.filter(data => !data.status);
|
|
return internRequests;
|
|
}
|
|
|
|
// Resolve per-intern task status by latest timestamp (assigned/completed/failed/reopened)
|
|
Ribc.getLatestTaskStatus = function (floID, taskId) {
|
|
const rec = Ribc.getInternRecord(floID) || {};
|
|
const events = [];
|
|
|
|
const assignedOn = rec.assignedTasks?.[taskId]?.assignedOn;
|
|
if (assignedOn) events.push({ s: 'active', t: assignedOn });
|
|
|
|
const compDate = rec.completedTasks?.[taskId]?.completionDate;
|
|
if (compDate) events.push({ s: 'completed', t: compDate });
|
|
|
|
const failDate = rec.failedTasks?.[taskId]?.failedDate;
|
|
if (failDate) events.push({ s: 'failed', t: failDate });
|
|
|
|
const reopenDate = rec.reopenedTasks?.[taskId]?.reopenedDate;
|
|
if (reopenDate) events.push({ s: 'active', t: reopenDate });
|
|
|
|
if (!events.length) return 'active';
|
|
events.sort((a, b) => a.t - b.t);
|
|
return events[events.length - 1].s; // latest wins
|
|
}
|
|
// Aggregate latest status across assigned interns
|
|
Ribc.getAggregateTaskStatus = function (taskId) {
|
|
const internIds = Ribc.getAssignedInterns(taskId) || [];
|
|
if (!internIds.length) return Ribc.getTaskStatus(taskId) || 'active';
|
|
|
|
const states = internIds.map(id => Ribc.getLatestTaskStatus(id, taskId)); // 'active'|'completed'|'failed'
|
|
|
|
if (states.length && states.every(s => s === 'completed')) return 'completed';
|
|
if (states.some(s => s === 'active')) return 'active';
|
|
if (states.every(s => s === 'failed')) return 'failed';
|
|
return 'mixed';
|
|
};
|
|
|
|
|
|
Admin.processInternRequest = function (vectorClock, accept = true) {
|
|
let request = floGlobals.generalDataset("InternRequests")[vectorClock];
|
|
if (!request)
|
|
return "Request not found";
|
|
var status;
|
|
if (accept && addIntern(request.senderID, request.message[0]))
|
|
status = "Accepted";
|
|
else
|
|
status = "Rejected";
|
|
floCloudAPI.noteApplicationData(vectorClock, status).then(_ => null).catch(e => console.error(e))
|
|
return status;
|
|
}
|
|
Admin.initInternRecord = function (floID) {
|
|
if (!_.internRecord[floID])
|
|
_.internRecord[floID] = {
|
|
active: true,
|
|
joined: Date.now(),
|
|
assignedTasks: {},
|
|
completedTasks: {},
|
|
failedTasks: {},
|
|
}
|
|
}
|
|
const addIntern = Admin.addIntern = function (floID, internName) {
|
|
if (floID in _.internList)
|
|
return false
|
|
_.internList[floID] = internName
|
|
_.internRating[floID] = 0
|
|
Admin.initInternRecord(floID)
|
|
return true;
|
|
}
|
|
Admin.renameIntern = function (floID, newName) {
|
|
if (!(floID in _.internList))
|
|
return false;
|
|
_.internList[floID] = newName;
|
|
return true;
|
|
}
|
|
|
|
Admin.removeIntern = function (floID) {
|
|
if (!(floID in _.internList))
|
|
return false
|
|
delete _.internList[floID]
|
|
delete _.internRating[floID]
|
|
delete _.internRecord[floID]
|
|
for (const taskKey in _.projectTaskDetails) {
|
|
if (_.internsAssigned[taskKey].includes(floID))
|
|
_.internsAssigned[taskKey] = _.internsAssigned[taskKey].filter(id => id !== floID)
|
|
}
|
|
return true;
|
|
}
|
|
Admin.addCompletedTask = function (floID, taskKey, points, details = {}) {
|
|
if (!(floID in _.internList))
|
|
return false;
|
|
Admin.initInternRecord(floID)
|
|
_.internRecord[floID].completedTasks[taskKey] = {
|
|
points,
|
|
...details
|
|
};
|
|
// calculate rating
|
|
let totalScore = 0;
|
|
for (const taskKey in _.internRecord[floID].completedTasks) {
|
|
totalScore += _.internRecord[floID].completedTasks[taskKey].points;
|
|
}
|
|
const completedTasks = Object.keys(_.internRecord[floID].completedTasks).length;
|
|
const failedTasks = Object.keys(_.internRecord[floID].failedTasks).length;
|
|
_.internRating[floID] = parseInt(totalScore / (completedTasks + failedTasks) || 1);
|
|
return true;
|
|
}
|
|
|
|
|
|
// (existing) Append-only "reopened" stamp
|
|
Admin.addReopenedTask = function (floID, taskKey, details = {}) {
|
|
if (!(floID in _.internList)) return false;
|
|
Admin.initInternRecord(floID);
|
|
|
|
if (!_.internRecord[floID].reopenedTasks)
|
|
_.internRecord[floID].reopenedTasks = {};
|
|
|
|
const reopenedDate = details.reopenedDate || Date.now();
|
|
_.internRecord[floID].reopenedTasks[taskKey] = { reopenedDate };
|
|
return true;
|
|
};
|
|
|
|
// (new) Remove a completion entry when a task is made incomplete
|
|
Admin.removeCompletedTask = function (floID, taskKey) {
|
|
if (!(floID in _.internList)) return false;
|
|
Admin.initInternRecord(floID);
|
|
const rec = _.internRecord[floID];
|
|
if (rec?.completedTasks && taskKey in rec.completedTasks) {
|
|
delete rec.completedTasks[taskKey];
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// (existing) Recompute rating, ignoring completions superseded by later reopen
|
|
Admin.recomputeRating = function (floID) {
|
|
const rec = _.internRecord[floID];
|
|
if (!rec) return;
|
|
|
|
let totalScore = 0;
|
|
let denom = 0;
|
|
|
|
for (const key in (rec.completedTasks || {})) {
|
|
const comp = rec.completedTasks[key];
|
|
const compDate = comp.completionDate || 0;
|
|
const reopenedDate = rec.reopenedTasks?.[key]?.reopenedDate || 0;
|
|
if (reopenedDate > compDate) continue; // reopened later ⇒ ignore this completion
|
|
totalScore += Number(comp.points) || 0;
|
|
denom += 1;
|
|
}
|
|
|
|
// keep failed tasks in denominator (your current policy)
|
|
denom += Object.keys(rec.failedTasks || {}).length;
|
|
|
|
_.internRating[floID] = Math.floor(denom ? (totalScore / denom) : 1) || 1;
|
|
};
|
|
|
|
// (optional) One-shot reconciliation if you want extra safety
|
|
Admin.syncInternRecordWithTaskStatus = function (taskId) {
|
|
const getAssigned = RIBC.getAssignedInterns || RIBC.admin?.getAssignedInterns;
|
|
const assignedInterns = (typeof getAssigned === 'function' ? getAssigned(taskId) : []) || [];
|
|
const status = RIBC.getTaskStatus?.(taskId) || RIBC.getAggregateTaskStatus?.(taskId);
|
|
if (!status) return;
|
|
|
|
if (status === 'completed') {
|
|
const completionDate = Date.now();
|
|
assignedInterns.forEach(internId => {
|
|
const rec = _.internRecord?.[internId];
|
|
const has = !!(rec && rec.completedTasks && rec.completedTasks[taskId]);
|
|
if (!has) RIBC.admin.addCompletedTask(internId, taskId, 0, { completionDate });
|
|
RIBC.admin.recomputeRating?.(internId);
|
|
});
|
|
} else if (status === 'incomplete') {
|
|
const reopenedDate = Date.now();
|
|
assignedInterns.forEach(internId => {
|
|
RIBC.admin.addReopenedTask(internId, taskId, { reopenedDate });
|
|
RIBC.admin.removeCompletedTask?.(internId, taskId);
|
|
RIBC.admin.recomputeRating?.(internId);
|
|
});
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
Admin.addFailedTask = function (floID, taskKey, details = {}) {
|
|
if (!(floID in _.internList))
|
|
return false;
|
|
Admin.initInternRecord(floID)
|
|
_.internRecord[floID].failedTasks[taskKey] = {
|
|
...details
|
|
};
|
|
Admin.unassignInternFromTask(floID, taskKey);
|
|
return true;
|
|
}
|
|
Admin.setInternStatus = function (floID, active = true) {
|
|
if (!(floID in _.internList))
|
|
return false;
|
|
_.internRecord[floID].active = active;
|
|
return true;
|
|
}
|
|
Ribc.getTaskRequests = function (ignoreProcessed = true) {
|
|
var taskRequests = Object.values(floGlobals.generalDataset("TaskRequests")).map(data => {
|
|
return {
|
|
floID: data.senderID,
|
|
vectorClock: data.vectorClock,
|
|
details: data.message,
|
|
status: data.note
|
|
}
|
|
})
|
|
// filter only requests for logged in intern
|
|
try {
|
|
if (floDapps.user.id && !floGlobals.subAdmins.includes(floDapps.user.id))
|
|
taskRequests = taskRequests.filter(data => data.floID === floDapps.user.id)
|
|
} catch (err) {
|
|
return [];
|
|
}
|
|
//filter processed requests
|
|
if (ignoreProcessed)
|
|
taskRequests = taskRequests.filter(data => !data.status)
|
|
return taskRequests
|
|
}
|
|
|
|
Admin.processTaskRequest = function (vectorClock, accept = true) {
|
|
let request = floGlobals.generalDataset("TaskRequests")[vectorClock];
|
|
if (!request)
|
|
return "Request not found";
|
|
const { message: { taskId, name }, senderID } = request;
|
|
const [projectCode, branch, taskNumber] = taskId.split('_');
|
|
var status;
|
|
addIntern(senderID, name)
|
|
if (accept && assignInternToTask(senderID, projectCode, branch, taskNumber))
|
|
status = "Accepted";
|
|
else
|
|
status = "Rejected";
|
|
return floCloudAPI.noteApplicationData(vectorClock, status)
|
|
}
|
|
|
|
const assignInternToTask = Admin.assignInternToTask = function (floID, projectCode, branch, taskNumber) {
|
|
const key = projectCode + "_" + branch + "_" + taskNumber
|
|
if (!_.internsAssigned[key])
|
|
_.internsAssigned[key] = []
|
|
if (!_.internsAssigned[key].includes(floID)) {
|
|
_.internsAssigned[key].push(floID)
|
|
_.internRecord[floID].assignedTasks[key] = { assignedOn: Date.now() }
|
|
return true
|
|
} else
|
|
return false
|
|
}
|
|
|
|
Admin.unassignInternFromTask = function (floID, taskKey) {
|
|
if (_.internsAssigned[taskKey] && _.internsAssigned[taskKey].includes(floID)) {
|
|
_.internsAssigned[taskKey] = _.internsAssigned[taskKey].filter(id => id !== floID)
|
|
delete _.internRecord[floID].assignedTasks[taskKey]
|
|
return true
|
|
} else
|
|
return false
|
|
}
|
|
|
|
Admin.putTaskStatus = function (taskStatus, projectCode, branch, taskNumber) {
|
|
_.projectTaskStatus[projectCode + "_" + branch + "_" + taskNumber] = taskStatus;
|
|
};
|
|
|
|
Admin.setDisplayedTasks = function (tasksArr = []) {
|
|
floGlobals.appObjects.RIBC.displayedTasks = tasksArr;
|
|
}
|
|
|
|
Admin.createProject = function (projectCode) {
|
|
if (projectCode in _.projectMap) {
|
|
return "Project Name already exists";
|
|
}
|
|
addBranch(projectCode);
|
|
return "Project Create: " + projectCode
|
|
}
|
|
|
|
Admin.copyBranchToNewProject = function (oldProjectCode, oldBranch, newProjectCode, newBranchConnection,
|
|
newStartPoint, newEndPoint) {
|
|
//Make sure new branch is a new text string that does not exist in new project
|
|
if (oldBranch == "mainLine") {
|
|
return "You cannot change mainLine";
|
|
}
|
|
if (_.projectMap.hasOwnProperty(newProjectCode) == false) {
|
|
return "The project does not exist"
|
|
}
|
|
if (_.projectMap[newProjectCode].hasOwnProperty(newBranch) == false) {
|
|
return "The branch does not exist"
|
|
}
|
|
if (newStartPoint > newEndPoint) {
|
|
return "Startpoint cannot be later than endpoint"
|
|
}
|
|
|
|
var newBranch = addBranch(newProjectCode, newBranchConnection, newStartPoint, newEndPoint);
|
|
_.projectMap[newProjectCode][newBranch] = _.projectMap[oldProjectCode][oldBranch].slice();
|
|
|
|
|
|
if (newBranchConnection == "undefined") {
|
|
_.projectMap[newProjectCode][newBranch][0] = "mainLine";
|
|
} else {
|
|
_.projectMap[newProjectCode][newBranch][0] = "newBranchConnection";
|
|
}
|
|
if (newStartPoint != "undefined") {
|
|
_.projectMap[newProjectCode][newBranch][2] = newStartPoint;
|
|
}
|
|
if (newEndPoint != "undefined") {
|
|
_.projectMap[newProjectCode][newBranch][3] = newEndPoint;
|
|
}
|
|
|
|
//Add entry in _.projectBranches.This may not be needed now
|
|
//_.projectBranches[newProjectCode] = _.projectBranches[newProjectCode]+","+newBranch;
|
|
|
|
//Copy Task List too
|
|
var p = _.projectTaskDetails;
|
|
for (var key in p) {
|
|
if (p.hasOwnProperty(key)) {
|
|
if (key.contains(oldProjectCode + "_" + oldBranch)) {
|
|
var numberExtract = key.replace(oldProjectCode + "_" + oldBranch + "_", "");
|
|
_.projectTaskDetails[newProjectCode + "_" + newBranch + "_" + numberExtract] = p[key];
|
|
}
|
|
}
|
|
}
|
|
return _.projectMap[newProjectCode][newBranch];
|
|
}
|
|
|
|
Admin.deleteTaskInMap = function (projectCode, branch, taskNumber) {
|
|
var arr = _.projectMap[projectCode][branch];
|
|
var currentIndex;
|
|
for (var i = 4; i < arr.length; i++) {
|
|
if (arr[i] == taskNumber) {
|
|
currentIndex = i
|
|
};
|
|
}
|
|
|
|
var nextIndex = currentIndex + 1,
|
|
previousIndex = currentIndex - 1;
|
|
var nextTaskNumber = _.projectMap[projectCode][branch][nextIndex],
|
|
previousTaskNumber = _.projectMap[projectCode][branch][previousIndex];
|
|
|
|
var deleteMode;
|
|
if (currentIndex == (arr.length - 1)) {
|
|
deleteMode = "last"
|
|
};
|
|
if (currentIndex == 4) {
|
|
deleteMode = "first"
|
|
};
|
|
if ((currentIndex > 4) && (currentIndex < (arr.length - 1))) {
|
|
deleteMode = "normal"
|
|
};
|
|
if ((currentIndex == 4) && (currentIndex == (arr.length - 1))) {
|
|
deleteMode = "nothingToDelete"
|
|
};
|
|
|
|
//Checking for links elsewhere
|
|
var otherBranches = Object.keys(_.projectMap[projectCode]);
|
|
//Remove the native branch and mainLine from otherBranches list
|
|
// otherBranches.splice(otherBranches.indexOf(branch), 1);
|
|
// otherBranches.splice(otherBranches.indexOf("mainLine"), 1);
|
|
otherBranches = otherBranches.filter(currBranch => currBranch !== branch || currBranch !== "mainLine");
|
|
|
|
//Checking the link other branches
|
|
for (var i = 0; i < otherBranches.length; i++) {
|
|
if (_.projectMap[projectCode][otherBranches[i]][2] == taskNumber) {
|
|
if (deleteMode == "normal") {
|
|
_.projectMap[projectCode][otherBranches[i]][2] = previousTaskNumber
|
|
} else if (deleteMode == "last") {
|
|
_.projectMap[projectCode][otherBranches[i]][2] = previousTaskNumber
|
|
} else if (deleteMode == "first") {
|
|
_.projectMap[projectCode][otherBranches[i]][2] = nextTaskNumber
|
|
} else if (deleteMode == "undefined") {
|
|
return " nothing to delete"
|
|
}
|
|
}
|
|
if (_.projectMap[projectCode][otherBranches[i]][3] == taskNumber) {
|
|
if (deleteMode == "normal") {
|
|
_.projectMap[projectCode][otherBranches[i]][3] = nextTaskNumber
|
|
} else if (deleteMode == "last") {
|
|
_.projectMap[projectCode][otherBranches[i]][3] = previousTaskNumber
|
|
} else if (deleteMode == "first") {
|
|
_.projectMap[projectCode][otherBranches[i]][3] = nextTaskNumber
|
|
} else if (deleteMode == "undefined") {
|
|
return " nothing to delete"
|
|
}
|
|
}
|
|
} //end for loop
|
|
|
|
//Delete from other databases
|
|
var p = _.projectTaskDetails;
|
|
for (var key in p) {
|
|
if (p.hasOwnProperty(key)) {
|
|
if (key == projectCode + "_" + branch + "_" + taskNumber) {
|
|
delete p[key]
|
|
}
|
|
}
|
|
} // end function
|
|
//Now splice the element
|
|
arr.splice(currentIndex, 1);
|
|
arr[1] = arr[1] - 1;
|
|
}
|
|
|
|
Admin.insertTaskInMap = function (projectCode, branchName, insertPoint) {
|
|
var lastTasks = [];
|
|
lastTasks = findLastTaskNumber(projectCode);
|
|
var lastNumber = lastTasks[branchName];
|
|
var arr = _.projectMap[projectCode][branchName];
|
|
var addedTaskNumber = lastNumber + 1;
|
|
var insertIndex = 0;
|
|
|
|
//Find insert point index
|
|
for (var i = 4; i < arr.length; i++) {
|
|
if (arr[i] >= addedTaskNumber) {
|
|
addedTaskNumber = arr[i] + 1
|
|
}
|
|
if (arr[i] == insertPoint) {
|
|
insertIndex = i;
|
|
}
|
|
}
|
|
|
|
if (insertIndex > 3) {
|
|
arr.splice((insertIndex + 1), 0, addedTaskNumber);
|
|
arr[1]++;
|
|
} else {
|
|
return "Not possible to insert here.Try another position"
|
|
}
|
|
|
|
return addedTaskNumber;
|
|
}
|
|
|
|
|
|
//The best error management I have done
|
|
//Project changing is overdoing right now
|
|
//newStartPoint,newEndPoint is optional
|
|
Admin.changeBranchLine = function (projectCode, branch, newConnection, newStartPoint, newEndPoint) {
|
|
//find the task number on the original line where it was branched, and then close the line there
|
|
//Do some basic tests
|
|
if (branch == "mainLine") {
|
|
return "You cannot change mainLine";
|
|
}
|
|
if (_.projectMap.hasOwnProperty(projectCode) == false) {
|
|
return "The project does not exist"
|
|
}
|
|
if (_.projectMap[projectCode].hasOwnProperty(branch) == false) {
|
|
return "The branch does not exist"
|
|
}
|
|
if (_.projectMap[projectCode].hasOwnProperty(newConnection) == false) {
|
|
return "The newConnection does not exist"
|
|
}
|
|
if (newStartPoint > newEndPoint) {
|
|
return "Startpoint cannot be later than endpoint"
|
|
}
|
|
|
|
_.projectMap[projectCode][branch][0] = newConnection;
|
|
if (newStartPoint != "undefined") {
|
|
_.projectMap[projectCode][branch][2] = newStartPoint;
|
|
}
|
|
if (newEndPoint != "undefined") {
|
|
_.projectMap[projectCode][branch][3] = newEndPoint;
|
|
}
|
|
|
|
return _.projectMap[projectCode][branch];
|
|
}
|
|
|
|
//startOrEndOrNewProject 1=>Start,2=>End .. projectCode and branch will remain same .. mainLines cannot be rerouted
|
|
//One test is missing .. you cannot connect to a point after end of connected trunk .. do it later .. not critical
|
|
Admin.changeBranchPoint = function (projectCode, branch, newPoint, startOrEnd) {
|
|
var message;
|
|
|
|
if (branch != "mainLine") {
|
|
if (startOrEnd == 1) {
|
|
if (newPoint <= _.projectMap[projectCode][branch][3]) {
|
|
_.projectMap[projectCode][branch][2] = newPoint;
|
|
message = newPoint;
|
|
} else {
|
|
message = "Start point cannot be later than end point"
|
|
}
|
|
}
|
|
if (startOrEnd == 2) {
|
|
if (newPoint >= _.projectMap[projectCode][branch][2]) {
|
|
_.projectMap[projectCode][branch][3] = newPoint;
|
|
message = newPoint;
|
|
} else {
|
|
message = "End point cannot be earlier than start point"
|
|
}
|
|
}
|
|
}
|
|
if (branch == "mainLine") {
|
|
message = "mainLine cannot be rerouted"
|
|
}
|
|
return message;
|
|
}
|
|
|
|
const addBranch = Admin.addBranch = function (projectCode1, branch, startPoint, mergePoint) {
|
|
var arr = findAllBranches(projectCode1);
|
|
var newBranchName;
|
|
|
|
if (arr == false) {
|
|
_.projectMap[projectCode1] = {};
|
|
_.projectMap[projectCode1]["mainLine"] = ["mainLine", 0, "Start", "Stop"];
|
|
newBranchName = "mainLine";
|
|
_.projectBranches[projectCode1] = "mainLine";
|
|
//projectCode[projectCode.length] = projectCode1;
|
|
} else {
|
|
var str = arr[arr.length - 1];
|
|
|
|
if (str.includes("branch")) {
|
|
var res = str.split("branch");
|
|
var newNumber = parseFloat(res[1]) + 1;
|
|
newBranchName = "branch" + newNumber;
|
|
_.projectMap[projectCode1]["branch" + newNumber] = [branch, 0, startPoint, mergePoint];
|
|
_.projectBranches[projectCode1] = _.projectBranches[projectCode1] + "," + "branch" +
|
|
newNumber;
|
|
}
|
|
|
|
if (str.includes("mainLine")) {
|
|
newBranchName = "branch1";
|
|
_.projectMap[projectCode1]["branch1"] = ["mainLine", 0, startPoint, mergePoint];
|
|
_.projectBranches[projectCode1] = "mainLine,branch1";
|
|
}
|
|
}
|
|
return newBranchName;
|
|
}
|
|
|
|
Admin.editTaskDetails = function (taskDetails, projectCode, branch, taskNumber) {
|
|
//add taskDetails
|
|
_.projectTaskDetails[projectCode + "_" + branch + "_" + taskNumber] = { ..._.projectTaskDetails[projectCode + "_" + branch + "_" + taskNumber], ...taskDetails };
|
|
}
|
|
|
|
Admin.addTaskInMap = function (projectCode, branchName) {
|
|
var lastTasks = [];
|
|
lastTasks = findLastTaskNumber(projectCode);
|
|
var lastNumber = lastTasks[branchName];
|
|
|
|
var addedTaskNumber = lastNumber + 1;
|
|
_.projectMap[projectCode][branchName].push(addedTaskNumber);
|
|
_.projectMap[projectCode][branchName][1]++;
|
|
|
|
return addedTaskNumber
|
|
}
|
|
|
|
function findAllBranches(projectCode) {
|
|
if (_.projectBranches.hasOwnProperty(projectCode)) {
|
|
var branch = _.projectBranches[projectCode].split(",");
|
|
} else branch = false;
|
|
|
|
return branch;
|
|
}
|
|
|
|
function findLastTaskNumber(projectCode) {
|
|
var returnData = {};
|
|
//Find all branch lines
|
|
var branch = _.projectBranches[projectCode].split(",");
|
|
for (var i = 0; i < branch.length; i++) {
|
|
returnData[branch[i]] = _.projectMap[projectCode][branch[i]][1];
|
|
//This test seems to have become redundant
|
|
if (returnData[branch[i]] == "Stop") {
|
|
returnData[branch[i]] = 0
|
|
}
|
|
}
|
|
return returnData;
|
|
}
|
|
|
|
})();
|