Implementing new scoring system

This commit is contained in:
sairaj mote 2022-11-08 05:01:31 +05:30
parent 8e8b10c1a9
commit 7fcdf46618
7 changed files with 215 additions and 157 deletions

File diff suppressed because one or more lines are too long

View File

@ -72,9 +72,20 @@ body[data-theme=dark] ::-webkit-calendar-picker-indicator {
filter: invert(1);
}
.calistoga {
font-weight: 400;
font-family: "Calistoga", cursive;
.overpass {
font-weight: 700;
font-family: "Overpass", sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
letter-spacing: -0.01em;
font-weight: 700;
font-family: "Overpass", sans-serif;
}
p,
@ -284,10 +295,6 @@ cube-loader {
--size: 1.2rem;
}
sm-form {
--gap: 1rem;
}
sm-select {
--padding: 0.8rem;
--min-width: fit-content;
@ -301,11 +308,11 @@ sm-option {
font-size: 0.9rem;
}
strip-select {
sm-chips {
--gap: 0.3rem;
}
strip-option {
sm-chip {
position: relative;
font-size: 0.9rem;
--border-radius: 0.3rem;
@ -313,17 +320,6 @@ strip-option {
-moz-user-select: none;
user-select: none;
}
sm-button {
--border-radius: 0.3rem;
}
sm-button[variant=primary] .icon {
fill: rgba(var(--background-color), 1);
}
sm-button[disabled] .icon {
fill: rgba(var(--text-color), 0.6);
}
ul {
list-style: none;
}
@ -698,7 +694,6 @@ ul {
}
#confirmation_popup h4,
#prompt_popup h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
#confirmation_popup .flex,
@ -1119,10 +1114,6 @@ ul {
background-color: #00c853 !important;
}
.task-title {
font-weight: 500;
}
.padding {
padding: 1rem;
}
@ -1135,14 +1126,11 @@ ul {
}
#dashboard_view_selector {
border-radius: 2rem;
border-radius: 0.5rem;
margin: 0 auto;
padding: 0.3rem;
background-color: rgba(var(--text-color), 0.04);
}
#dashboard_view_selector strip-option {
--border-radius: 2rem;
}
.logo {
display: flex;
@ -1299,7 +1287,6 @@ ul {
.container-header h4 {
flex: 1;
font-weight: 500;
}
#intern_info_popup .grid > * {
@ -1346,7 +1333,6 @@ ul {
-moz-user-select: none;
user-select: none;
font-size: 0.85rem;
font-weight: 500;
}
.branch-button--active {
opacity: 1;
@ -1368,7 +1354,6 @@ ul {
background: rgba(var(--foreground-color), 1);
}
.task-list-item h4 {
font-weight: 500;
margin: 0;
}
.task-list-item .task-title {
@ -1827,7 +1812,6 @@ input[type=date]:focus {
fill: var(--accent-color);
}
.pinned-card .project__title {
font-weight: 500;
color: rgba(var(--text-color), 0.9);
}
.pinned-card .project__title:hover {

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -73,9 +73,19 @@ body[data-theme="dark"] {
filter: invert(1);
}
}
.calistoga {
font-weight: 400;
font-family: "Calistoga", cursive;
.overpass {
font-weight: 700;
font-family: "Overpass", sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
letter-spacing: -0.01em;
font-weight: 700;
font-family: "Overpass", sans-serif;
}
p,
strong {
@ -278,10 +288,6 @@ cube-loader {
--size: 1.2rem;
}
sm-form {
--gap: 1rem;
}
sm-select {
--padding: 0.8rem;
--min-width: fit-content;
@ -295,30 +301,16 @@ sm-option {
font-size: 0.9rem;
}
strip-select {
sm-chips {
--gap: 0.3rem;
}
strip-option {
sm-chip {
position: relative;
font-size: 0.9rem;
--border-radius: 0.3rem;
user-select: none;
}
sm-button {
--border-radius: 0.3rem;
&[variant="primary"] {
.icon {
fill: rgba(var(--background-color), 1);
}
}
&[disabled] {
.icon {
fill: rgba(var(--text-color), 0.6);
}
&[selected] {
}
}
@ -687,7 +679,6 @@ ul {
flex-direction: column;
h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
@ -1122,10 +1113,6 @@ ul {
background-color: #00c853 !important;
}
.task-title {
font-weight: 500;
}
.padding {
padding: 1rem;
}
@ -1137,13 +1124,10 @@ ul {
align-content: flex-start;
}
#dashboard_view_selector {
border-radius: 2rem;
border-radius: 0.5rem;
margin: 0 auto;
padding: 0.3rem;
background-color: rgba(var(--text-color), 0.04);
strip-option {
--border-radius: 2rem;
}
}
.logo {
display: flex;
@ -1294,7 +1278,6 @@ ul {
.container-header h4 {
flex: 1;
font-weight: 500;
}
#intern_info_popup {
@ -1339,7 +1322,6 @@ ul {
align-items: center;
user-select: none;
font-size: 0.85rem;
font-weight: 500;
&--active {
opacity: 1;
color: white;
@ -1359,7 +1341,6 @@ ul {
border-radius: 0.5rem;
background: rgba(var(--foreground-color), 1);
h4 {
font-weight: 500;
margin: 0;
}
.task-title {
@ -1801,7 +1782,6 @@ input[type="date"] {
}
}
.project__title {
font-weight: 500;
color: rgba(var(--text-color), 0.9);
&:hover {
color: var(--accent-color);

View File

@ -11,7 +11,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Calistoga&family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"
href="https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,700;0,900;1,700;1,900&family=Roboto:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"
rel="stylesheet">
<script src="components.js" defer></script>
<script id="floGlobals">
@ -93,7 +93,7 @@
<div id="landing" class="grid inner-page hidden">
<div class="gap-1-5 landing__card">
<div class="grid gap-1-5">
<h1 class="calistoga" style="max-width: 26rem;">
<h1 class="overpass" style="max-width: 26rem;">
Blockchain based <br> Internship Platform
</h1>
<div class="flex gap-0-3">
@ -306,12 +306,12 @@
<section id="dashboard_page" class="inner-page hidden"></section>
<section id="admin_page" class="inner-page hidden">
<div id="admin_page__header" class="flex align-center space-between">
<strip-select id="admin_view_selector">
<strip-option value="0" selected>Projects</strip-option>
<strip-option value="1">Interns</strip-option>
<strip-option value="2">Task display</strip-option>
<strip-option value="3">Requests</strip-option>
</strip-select>
<sm-chips id="admin_view_selector">
<sm-chip value="projects" selected>Projects</sm-chip>
<sm-chip value="interns">Interns</sm-chip>
<sm-chip value="task_display">Task display</sm-chip>
<sm-chip value="requests">Requests</sm-chip>
</sm-chips>
<button class="button button--small button--primary admin-option" onclick="commitToChanges()">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="24" height="24">
@ -564,20 +564,7 @@
</svg>
</button>
</header>
<section class="grid gap-1">
<div id="intern_info__initials" class="intern-card__initials"></div>
<h3 id="intern_info__name">Intern name</h3>
<sm-copy id="intern_info__flo_id"></sm-copy>
<div id="update_intern_score" class="flex align-center">
<svg class="icon icon--star margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M12 18.26l-7.053 3.948 1.575-7.928L.587 8.792l8.027-.952L12 .5l3.386 7.34 8.027.952-5.935 5.488 1.575 7.928z" />
</svg>
<h4 id="intern_info__score"></h4>
</div>
</section>
<section id="intern_info__wrapper" class="grid gap-1"></section>
</sm-popup>
<sm-popup id="intern_list_popup">
@ -742,6 +729,20 @@
</div>
</sm-form>
</sm-popup>
<sm-popup id="rate_participants_popup">
<header slot="header" class="popup__header">
<button class="popup__header__close justify-self-start" onclick="closePopup()">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
</svg>
</button>
<h3>Rate participants</h3>
</header>
<div id="rating_wrapper" class="flex flex-direction-column gap-1-5"></div>
</sm-popup>
<sm-popup id="secure_pwd_popup">
<header slot="header" class="popup__header">
<button class="popup__header__close justify-self-start" onclick="closePopup()">
@ -1123,24 +1124,26 @@
renderedAssignedTasks = html`No task assigned yet.`;
}
}
if (!subPageId1) {
subPageId1 = typeOfUser === 'intern' ? 'my_tasks' : 'all_tasks'
}
//creates cards for highest performing interns
//sort interns earned points
const highPerformingInterns = Object.keys(RIBC.getInternList()).sort((a, b) => RIBC.getInternRating(b) - RIBC.getInternRating(a));
const routedToAllTasks = (subPageId1 && subPageId1 === 'all_tasks') || (!subPageId1 && typeOfUser !== 'intern');
renderElem(getRef('dashboard_page'), html`
<strip-select id="dashboard_view_selector" class="margin-right-auto" onchange=${handleDashboardViewChange}>
${typeOfUser === 'intern' ? html`<strip-option value="intern_view" selected>My tasks</strip-option>` : ''}
<strip-option value="dashboard_tasks_wrapper" ?selected=${routedToAllTasks}>All tasks</strip-option>
<strip-option value="projects_wrapper" ?selected=${subPageId1 === 'projects'}>Projects</strip-option>
${floGlobals.isMobileView ? html`<strip-option value="intern_leaderboard_container">Leaderboard</strip-option>` : ''}
</strip-select>
<sm-chips id="dashboard_view_selector" class="margin-right-auto" onchange=${handleDashboardViewChange}>
${typeOfUser === 'intern' ? html`<sm-chip value="intern_view" selected>My tasks</sm-chip>` : ''}
<sm-chip value="dashboard_tasks_wrapper" ?selected=${subPageId1 === 'all_tasks'}>All tasks</sm-chip>
<sm-chip value="projects_wrapper" ?selected=${subPageId1 === 'projects'}>Projects</sm-chip>
${floGlobals.isMobileView ? html`<sm-chip value="intern_leaderboard_container">Leaderboard</sm-chip>` : ''}
</sm-chips>
${typeOfUser === 'intern' ? html`
<section id="intern_view" class="intern-option dashboard-view__item">
<ul id="assigned_task_list">${renderedAssignedTasks}</ul>
</section>
` : ''}
<div id="dashboard_tasks_wrapper" class=${`flex flex-direction-column justify-center dashboard-view__item ${typeOfUser === 'intern' ? 'hidden' : ''}`}>${render.displayTasks(params?.category, params?.search)}</div>
<div id="projects_wrapper" class="grid gap-2 align-items-start dashboard-view__item hidden"></div>
<div id="projects_wrapper" class="grid gap-2 align-items-start dashboard-view__item hidden">${render.dashProjects()}</div>
<div id="intern_leaderboard_container" class="container-card dashboard-view__item hide-on-mobile">
<div class="container-header">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> <path fill="none" d="M0 0h24v24H0z" /> <path d="M12 7a8 8 0 1 1 0 16 8 8 0 0 1 0-16zm0 3.5l-1.323 2.68-2.957.43 2.14 2.085-.505 2.946L12 17.25l2.645 1.39-.505-2.945 2.14-2.086-2.957-.43L12 10.5zm1-8.501L18 2v3l-1.363 1.138A9.935 9.935 0 0 0 13 5.049L13 2zm-2 0v3.05a9.935 9.935 0 0 0-3.636 1.088L6 5V2l5-.001z" /> </svg>
@ -1153,11 +1156,10 @@
</div>
</div>
`)
renderElem(getRef('projects_wrapper'), render.dashProjects())
changeDashboardView(getKeyByValue(floGlobals.dashboardPages, subPageId1))
if (params?.taskId) {
showTaskDetails(params.taskId)
}
else
} else
hideTaskDetails()
break;
case 'updates_page': {
@ -1225,9 +1227,10 @@
if (typeOfUser !== 'admin') return;
//show projects
if (subPageId1) {
getRef('admin_view_selector').value = subPageId1;
const viewIndex = ['projects', 'interns', 'task_display', 'requests'].findIndex(page => page === subPageId1);
getRef('admin_view_selector').value = viewIndex;
showChildElement(getRef('admin_views'), viewIndex);
showChildElement(getRef('admin_views'), viewIndex, { entry: viewIndex > currentViewIndex ? slideInLeft : slideInRight, exit: viewIndex > currentViewIndex ? slideOutLeft : slideOutRight });
currentViewIndex = viewIndex;
switch (subPageId1) {
case 'projects':
render.projectList(getRef('admin_page__project_list'), getSortedProjectList(), true)
@ -1243,6 +1246,7 @@
getRef('projects_container__left').classList.remove('hide-on-mobile')
getRef('project_editing_panel').classList.add('hidden')
history.replaceState(null, '', '#/admin_page/projects')
getRef('admin_page__project_list').querySelectorAll('.project-card').forEach(project => project.classList.remove('project-card--active'))
}
break;
case 'interns':
@ -1315,7 +1319,6 @@
dragger = dragula([getRef('display_task_map'), getRef('all_tasks')])
dragger.on('dragend', function (el, source) {
const newOrder = Array.from(getRef('display_task_map').children).map(el => el.dataset.taskId)
console.log(newOrder)
RIBC.admin.setDisplayedTasks(newOrder)
});
break;
@ -1363,14 +1366,14 @@
getRef('private_key_field').focusIn()
break;
}
if (pageId !== 'dashboard_page') {
if (appState.lastPage === 'dashboard_page') {
renderElem(getRef('dashboard_page'), html``)
}
if (pageId !== 'settings_page') {
if (appState.lastPage === 'settings_page') {
renderElem(getRef('settings_page'), html``)
}
appState.lastPage = pageId
}
appState.lastPage = pageId
}
}
// class based lazy loading
@ -1627,8 +1630,9 @@
parent.style.overflow = ''
}
parent.children[index].classList.remove(mobileView ? 'hide-on-mobile' : 'hidden')
if (entry)
if (entry) {
parent.children[index].animate(entry, animOptions).onfinish = () => resolve()
}
} else {
visibleElement.classList.add(mobileView ? 'hide-on-mobile' : 'hidden')
parent.children[index].classList.remove(mobileView ? 'hide-on-mobile' : 'hidden')
@ -1739,9 +1743,9 @@
// render categories
let renderedCategories = []
if (availableCategories.size > 1) {
renderedCategories = [html`<strip-option value='all' ?selected=${category === 'all'}>All</strip-option>`];
renderedCategories = [html`<sm-chip value='all' ?selected=${category === 'all'}>All</sm-chip>`];
availableCategories.forEach(categoryID => {
renderedCategories.push(html`<strip-option value=${categoryID} ?selected=${categoryID === category}>${floGlobals.taskCategories[categoryID]}</strip-option>`)
renderedCategories.push(html`<sm-chip value=${categoryID} ?selected=${categoryID === category}>${floGlobals.taskCategories[categoryID]}</sm-chip>`)
})
}
setTimeout(() => {
@ -1760,7 +1764,7 @@
</sm-input>
`: ''}
</div>
${availableCategories.size > 1 ? html`<strip-select id="task_category_selector" onchange='filterTasks()'>${renderedCategories}</strip-select>` : ''}
${availableCategories.size > 1 ? html`<sm-chips id="task_category_selector" onchange='filterTasks()'>${renderedCategories}</sm-chips>` : ''}
</div>
<div class="grid gap-1">
<ul id="display_task_list" class="flex flex-direction-column gap-0-5 observe-empty-state">${renderedTasks}</ul>
@ -2377,23 +2381,29 @@
}
let pinnedProjects = [];
let currentIntern;
let typeOfUser = 'general';
floGlobals.dashboardPages = {
'intern_view': 'my_tasks',
'dashboard_tasks_wrapper': 'all_tasks',
'projects_wrapper': 'projects',
'intern_leaderboard_container': 'leaderboard',
}
// find key of the object by value
function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
function handleDashboardViewChange(e) {
changeDashboardView(e.target.value)
location.hash = `#/${appState.currentPage}/${floGlobals.dashboardPages[e.target.value]}`
}
function changeDashboardView(viewId = 'dashboard_tasks_wrapper') {
document.querySelectorAll('.dashboard-view__item').forEach(item => {
if (item.id === 'intern_leaderboard_container')
item.classList.add('hide-on-mobile')
else
item.classList.add('hidden')
})
document.querySelector(`#${e.target.value}`).classList.remove('hide-on-mobile', 'hidden')
const dashboardPages = {
'intern_view': 'my_tasks',
'dashboard_tasks_wrapper': 'all_tasks',
'projects_wrapper': 'projects'
}
location.hash = `#/${appState.currentPage}/${dashboardPages[e.target.value]}`
document.querySelector(`#${viewId}`).classList.remove('hide-on-mobile', 'hidden')
}
@ -2455,12 +2465,30 @@
function showInternInfo(e) {
const internFloId = e.target.closest('.intern-card').dataset.internFloId;
const internName = RIBC.getInternList()[internFloId]
getRef('intern_info__initials').textContent = internName.split(' ').map(v => v.charAt(0)).join('');
getRef('intern_info__initials').style.setProperty('--color', `var(${getInternColor(internFloId)})`)
getRef('intern_info__name').textContent = internName;
getRef('intern_info__flo_id').value = currentIntern = internFloId;
getRef('intern_info__score').textContent = RIBC.getInternRating(internFloId); // points earned by intern
const { completedTasks = [], active = true } = RIBC.getInternRecord(internFloId) || {}
renderElem(getRef('intern_info__wrapper'), html`
<div id="intern_info__initials" class="intern-card__initials" style=${`--color: var(${getInternColor(internFloId)})`}>${internName.split(' ').map(v => v.charAt(0)).join('')}</div>
<h3 id="intern_info__name">${internName}</h3>
<sm-copy id="intern_info__flo_id" value=${internFloId}></sm-copy>
<div id="update_intern_score" class="flex align-center">
<svg class="icon icon--star margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> <path fill="none" d="M0 0h24v24H0z" /> <path d="M12 18.26l-7.053 3.948 1.575-7.928L.587 8.792l8.027-.952L12 .5l3.386 7.34 8.027.952-5.935 5.488 1.575 7.928z" /> </svg>
<h4 id="intern_info__score">0</h4>
</div>
`)
openPopup('intern_info_popup');
// animate number counting up within 1s from 0 to the intern's score
const scoreElem = getRef('intern_info__score')
const finalScore = RIBC.getInternRating(internFloId)
let score = 0;
const scoreInterval = setInterval(incrementNumber, 600 / finalScore)
function incrementNumber() {
scoreElem.textContent = score;
score++;
if (score > finalScore) {
clearInterval(scoreInterval)
}
}
incrementNumber()
}
// opens a popup containing various project information
@ -2535,12 +2563,8 @@
let currentViewIndex = 0;
getRef('admin_view_selector').addEventListener('change', (e) => {
const newViewIndex = parseInt(e.target.value);
showChildElement(getRef('admin_views'), newViewIndex, { entry: newViewIndex > currentViewIndex ? slideInLeft : slideInRight, exit: newViewIndex > currentViewIndex ? slideOutLeft : slideOutRight });
currentViewIndex = parseInt(e.target.value);
const viewIds = ['projects', 'interns', 'task_display', 'requests']
location.hash = `#/${appState.currentPage}/${viewIds[e.target.value]}`
getRef('admin_page_nav_button').href = `#/${appState.currentPage}/${viewIds[e.target.value]}`
location.hash = `#/${appState.currentPage}/${e.target.value}`
getRef('admin_page_nav_button').href = `#/${appState.currentPage}/${e.target.value}`
})
function toggleEditing(target) {
@ -2555,17 +2579,63 @@
return '₹0';
return amount.toLocaleString(currency === 'inr' ? `en-IN` : 'en-US', { style: 'currency', currency, maximumFractionDigits: 0 })
}
delegate(getRef('task_list'), 'change', 'sm-checkbox', (e) => {
delegate(getRef('task_list'), 'mousedown', 'sm-checkbox', (e) => {
e.preventDefault();
currentTask = e.target.closest('.task-list-item');
const taskStatus = e.target.checked ? 'completed' : 'incomplete'
RIBC.admin.putTaskStatus(taskStatus, appState.params.id, appState.params.branch, currentTask.dataset.taskId)
if (e.target.checked) {
// remove task from displayed list
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
const filteredTasks = RIBC.getDisplayedTasks().filter(task => task !== taskId)
RIBC.admin.setDisplayedTasks(filteredTasks)
if (e.delegateTarget.checked) {
getConfirmation('Mark this task as incomplete?', { confirmText: 'Mark as incomplete' }).then(res => {
if (res) {
RIBC.admin.putTaskStatus('incomplete', appState.params.id, appState.params.branch, currentTask.dataset.taskId)
currentTask.querySelector('sm-checkbox').checked = false;
// TODO: remove task scores from intern rating
}
})
} else {
const assignedInterns = RIBC.getAssignedInterns(appState.params.id, appState.params.branch, currentTask.dataset.taskId);
renderElem(getRef('rating_wrapper'), html`
<h4>${currentTask.querySelector('.task-title').textContent}</h4>
<sm-form>
${assignedInterns.map((intern, index) => html`
<div class="flex flex-direction-column gap-0-5 rating-part" data-intern-id=${intern}>
<h4>${RIBC.getInternList()[intern]}</h4>
<div class="flex gap-0-5">
<sm-input type="number" min="0" max="50" class="flex-1" placeholder="Rate out of 50" error-text="Points must be between 0-50" required></sm-input>
<input class="flex-1" type="date" value=${formatDate(new Date())} placeholder="Completion date" aria-label="Set date of completion" required>
</div>
</div>
`)}
<button id="rate_participants_btn" class="button button--primary" type="submit" disabled onclick="rateParticipants()"> Rate </button>
</sm-form>
`)
openPopup('rate_participants_popup')
}
})
// format unix timestamp to yyyy-mm-dd
function formatDate(unixTimestamp) {
const date = new Date(unixTimestamp);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
}
function markTaskAsCompleted() {
RIBC.admin.putTaskStatus('completed', appState.params.id, appState.params.branch, currentTask.dataset.taskId)
// remove task from displayed list
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
const filteredTasks = RIBC.getDisplayedTasks().filter(task => task !== taskId)
}
function rateParticipants() {
document.querySelectorAll('.rating-part').forEach((ratingPart) => {
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
const internId = ratingPart.dataset.internId;
const score = 50 + parseInt(ratingPart.querySelector('sm-input').value.trim());
const completionDate = ratingPart.querySelector('input').value;
RIBC.admin.addTaskScore(internId, taskId, score, { completionDate })
})
markTaskAsCompleted()
closePopup()
currentTask.querySelector('sm-checkbox').checked = true;
}
delegate(getRef('task_list'), 'change', 'sm-select', (e) => {
currentTask = e.target.closest('.task-list-item');
if (!currentTask) return;
@ -2580,16 +2650,14 @@
if (!currentTask) return;
const ogTaskDetails = RIBC.getTaskDetails(appState.params.id, appState.params.branch, currentTask.dataset.taskId)
const newTaskDetails = {}
let valid = false;
if (e.target.isContentEditable) {
e.target.contentEditable = false
newTaskDetails[e.target.dataset.editField] = DOMPurify.sanitize(e.target.innerHTML.trim())
valid = true;
} else if (e.target.closest('sm-input')) {
newTaskDetails[e.target.dataset.editField] = parseInt(e.target.value)
valid = true;
} else {
return;
}
if (!valid) return;
if (ogTaskDetails[e.target.dataset.editField] !== newTaskDetails[e.target.dataset.editField]) {
RIBC.admin.editTaskDetails(newTaskDetails, appState.params.id, appState.params.branch, currentTask.dataset.taskId)
notify('Changes saved locally, commit the changes to make them permanent', 'success')
@ -3003,6 +3071,9 @@
floGlobals.selectedInterns.clear()
getRef('assign_interns_button').disabled = true
break;
case 'rate_participants_popup':
renderElem(getRef('rating_wrapper'), html``)
break;
}
if (popupStack.items.length === 0) {
getRef('main_page').removeAttribute('inert')

View File

@ -15,7 +15,7 @@
floCloudAPI.requestObjectData("RIBC").then(result => {
if (!floGlobals.appObjects.RIBC)
floGlobals.appObjects.RIBC = {};
var objectList = ["projectMap", "projectBranches", "projectTaskDetails", "projectDetails", "internList", "internRating", "internsAssigned", "projectTaskStatus", "displayedTasks"]
var objectList = ["projectMap", "projectBranches", "projectTaskDetails", "projectDetails", "internList", "internRating", "internRecord", "internsAssigned", "projectTaskStatus", "displayedTasks"]
objectList.forEach(obj => {
if (!floGlobals.appObjects.RIBC[obj])
floGlobals.appObjects.RIBC[obj] = {};
@ -103,6 +103,7 @@
Ribc.getTaskStatus = (project, branch, task) => _.projectTaskStatus[project + "_" + branch + "_" + task];
Ribc.getInternList = () => _.internList;
Ribc.getInternRating = (floID) => _.internRating[floID];
Ribc.getInternRecord = (floID) => _.internRecord[floID];
Ribc.getAssignedInterns = (projectCode, branch, taskNumber) => _.internsAssigned[projectCode + "_" + branch + "_" + taskNumber]
Ribc.getAllTasks = () => _.projectTaskDetails
Ribc.getDisplayedTasks = () => floGlobals.appObjects.RIBC.displayedTasks || [];
@ -164,7 +165,11 @@
if (floID in _.internList)
return false
_.internList[floID] = internName
_.internRating[floID] = 1
_.internRating[floID] = 0
_.internRecord[floID] = {
active: true,
completedTasks: {},
}
return true;
}
Admin.renameIntern = function (floID, newName) {
@ -179,20 +184,38 @@
return false
delete _.internList[floID]
delete _.internRating[floID]
delete _.internRecord[floID]
for (const taskId in _.projectTaskDetails) {
if (_.internsAssigned[taskId].includes(floID))
_.internsAssigned[taskId] = _.internsAssigned[taskId].filter(id => id != floID)
}
return true;
}
Admin.updateInternRating = function (floID, change = 0) {
Admin.addTaskScore = function (floID, taskId, score, details = {}) {
if (!(floID in _.internList))
return "Intern not found!"
_.internRating[floID] += change
return "Intern rating Updated";
return false;
if (!_.internRecord[floID])
_.internRecord[floID] = {
active: true,
completedTasks: {},
}
_.internRecord[floID].completedTasks[taskId] = {
score,
...details
};
let totalScore = 0;
for (const taskId in _.internRecord[floID].completedTasks) {
totalScore += _.internRecord[floID].completedTasks[taskId].score;
}
_.internRating[floID] = totalScore;
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 {

2
scripts/ribc.min.js vendored

File diff suppressed because one or more lines are too long