UI improvements

This commit is contained in:
sairaj mote 2022-11-09 04:28:23 +05:30
parent 7fcdf46618
commit 0ecde83eb1
5 changed files with 137 additions and 70 deletions

File diff suppressed because one or more lines are too long

View File

@ -190,7 +190,9 @@ button:not(:disabled),
}
button:disabled {
opacity: 0.5;
opacity: 0.4;
cursor: not-allowed;
filter: saturate(0);
}
.cta {
@ -1345,7 +1347,7 @@ ul {
padding: 1rem 0 1.5rem 0;
}
.task-list-item {
.admin-task {
display: grid;
align-content: flex-start;
padding: 1rem;
@ -1353,13 +1355,13 @@ ul {
border-radius: 0.5rem;
background: rgba(var(--foreground-color), 1);
}
.task-list-item h4 {
.admin-task h4 {
margin: 0;
}
.task-list-item .task-title {
.admin-task .task-title {
line-height: 1.6;
}
.task-list-item__task-number {
.admin-task__task-number {
font-size: 0.8rem;
color: rgba(var(--text-color), 0.8);
border: solid 0.1em var(--accent-color);
@ -1368,6 +1370,15 @@ ul {
font-weight: 500;
}
.tag {
padding: 0.4rem 0.8rem;
border-radius: 3rem;
font-size: 0.9rem;
font-weight: 500;
color: var(--green);
background-color: rgba(var(--text-color), 0.06);
}
.task__branch_container:not(:empty) {
display: grid;
gap: 0.5rem;
@ -1422,8 +1433,8 @@ ul {
user-select: none;
display: flex;
font-size: 0.8rem;
padding: 0.2rem 0 0.2rem 0.4rem;
border-radius: 0.2rem;
padding: 0.4rem;
border-radius: 0.3rem;
border: 1px solid rgba(var(--text-color), 0.24);
align-items: center;
white-space: nowrap;
@ -1431,6 +1442,7 @@ ul {
}
.assigned-interns .assigned-intern button {
padding: 0.2rem;
margin-right: -0.2rem;
}
.assigned-interns .assigned-intern button .icon {
height: 1rem;

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -181,7 +181,9 @@ button,
}
}
button:disabled {
opacity: 0.5;
opacity: 0.4;
cursor: not-allowed;
filter: saturate(0);
}
.cta {
@ -1333,13 +1335,15 @@ ul {
gap: 0.5rem;
padding: 1rem 0 1.5rem 0;
}
.task-list-item {
.admin-task {
display: grid;
align-content: flex-start;
padding: 1rem;
gap: 0.5rem;
border-radius: 0.5rem;
background: rgba(var(--foreground-color), 1);
&.completed {
}
h4 {
margin: 0;
}
@ -1355,6 +1359,14 @@ ul {
font-weight: 500;
}
}
.tag {
padding: 0.4rem 0.8rem;
border-radius: 3rem;
font-size: 0.9rem;
font-weight: 500;
color: var(--green);
background-color: rgba(var(--text-color), 0.06);
}
.task__branch_container {
&:not(:empty) {
display: grid;
@ -1410,14 +1422,15 @@ ul {
user-select: none;
display: flex;
font-size: 0.8rem;
padding: 0.2rem 0 0.2rem 0.4rem;
border-radius: 0.2rem;
padding: 0.4rem;
border-radius: 0.3rem;
border: 1px solid rgba(var(--text-color), 0.24);
align-items: center;
white-space: nowrap;
text-transform: capitalize;
button {
padding: 0.2rem;
margin-right: -0.2rem;
.icon {
height: 1rem;
width: 1rem;

View File

@ -1857,7 +1857,7 @@
const internPoints = RIBC.getInternRating(internFloId)
const initials = internName.split(' ').map(v => v.charAt(0)).join('');
return html`
<label class="intern-card align-center interact" .dataset=${{ internFloId }} onclick=${showInternInfo} title="Intern Information">
<label class="intern-card align-center interact" .dataset=${{ internFloId }} onclick=${selectable ? false : showInternInfo} title="Intern Information">
${selectable ? html`<input type="checkbox" class="intern-card__checkbox" value=${internFloId}>` : ''}
<div class="intern-card__initials" style=${`--color: var(${getInternColor(internFloId)})`}>${initials}</div>
<div class="intern-card__name capitalize">${internName}</div>
@ -1921,13 +1921,13 @@
</span>
`
},
taskListItem(task, ref) {
adminTask(task) {
const assignedInterns = RIBC.getAssignedInterns(appState.params.id, appState.params.branch, task)
const taskDetails = { title, description, category, maxSlots, duration, durationType, reward } = RIBC.getTaskDetails(appState.params.id, appState.params.branch, task)
const status = RIBC.getTaskStatus(appState.params.id, appState.params.branch, task)
const taskDetails = { title, description, category, maxSlots, duration, durationType, reward } = RIBC.getTaskDetails(appState.params.id, appState.params.branch, task)
let assignedInternsCards
if (assignedInterns) {
assignedInternsCards = filterMap(assignedInterns, (internFloId) => render.assignedInternCard(internFloId, true))
assignedInternsCards = filterMap(assignedInterns, (internFloId) => render.assignedInternCard(internFloId, status === 'incomplete'))
}
const branches = getAllBranches(appState.params.id)
const branchesButtons = filterMap(branches, (branch) => {
@ -1940,26 +1940,31 @@
})
}
})
const categories = [];
for (const categoryID in floGlobals.taskCategories) {
categories.push(html`<sm-option value=${categoryID} ?selected=${categoryID === category}>${floGlobals.taskCategories[categoryID]}</sm-option>`)
}
const taskDescription = createElement('p', {
const descriptionOptions = {
className: 'task-description ws-pre-line wrap-around',
attributes: {
innerHTML: DOMPurify.sanitize(description)
}
if (status === 'incomplete') {
descriptionOptions.attributes = {
'data-editable': '',
'data-edit-field': 'description',
},
innerHTML: DOMPurify.sanitize(description)
})
return html.for(ref, `${appState.params.id}_${appState.params.branch}_${task}`)`
<li class="task-list-item" .dataset=${{ taskId: task }}>
}
}
const taskDescription = createElement('p', descriptionOptions)
if (status === 'incomplete') {
const categories = [];
for (const categoryID in floGlobals.taskCategories) {
categories.push(html`<sm-option value=${categoryID} ?selected=${categoryID === category}>${floGlobals.taskCategories[categoryID]}</sm-option>`)
}
return html`
<li class=${`admin-task ${status}`} .dataset=${{ taskId: task }}>
<div class="flex align-center gap-0-3">
<div class="flex align-center gap-0-5">
<sm-checkbox ?checked=${status === 'completed'}>
<p class="margin-left-0-5">Mark as complete</p>
</sm-checkbox>
<div class="task-list-item__task-number">ID: ${task}</div>
<button class="button button--small button--colored" onclick=${initTaskScoring}>
<svg class="icon margin-right-0-3" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/></svg>
Mark as complete
</button>
<div class="admin-task__task-number">ID: ${task}</div>
</div>
<button class="button--danger icon-only margin-left-auto"onclick="removeThisTask()">
<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="M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"/></svg>
@ -1970,13 +1975,14 @@
</div>
<h4 class="task-title capitalize" data-editable data-edit-field="title">${title}</h4>
<div class="assigned-interns">
<button class="button--outlined button--small button--colored" onclick="currentTask=this.closest('.task-list-item');openPopup('intern_list_popup')">
<button class="button--outlined button--small button--colored" onclick="currentTask=this.closest('.admin-task');openPopup('intern_list_popup')">
<svg class="icon margin-right-0-3" 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="M11 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0-6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zM5 18c.2-.63 2.57-1.68 4.96-1.94l2.04-2c-.39-.04-.68-.06-1-.06-2.67 0-8 1.34-8 4v2h9l-2-2H5zm15.6-5.5l-5.13 5.17-2.07-2.08L12 17l3.47 3.5L22 13.91z"/></svg>
Assign intern
</button>
${assignedInternsCards}
</div>
${taskDescription}
${branchesButtons.length ? html`<div class="task__branch_container">${branchesButtons}</div>` : ''}
<div class="grid gap-0-5 margin-top-1" style="grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));">
<sm-select data-edit-field="category" label="Category: ">${categories}</sm-select>
<div class="flex flex-1">
@ -1993,9 +1999,48 @@
<svg slot="icon" class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <g> <rect fill="none" height="24" width="24"></rect> </g> <g> <g> <path d="M13.66,7C13.1,5.82,11.9,5,10.5,5L6,5V3h12v2l-3.26,0c0.48,0.58,0.84,1.26,1.05,2L18,7v2l-2.02,0c-0.25,2.8-2.61,5-5.48,5 H9.77l6.73,7h-2.77L7,14v-2h3.5c1.76,0,3.22-1.3,3.46-3L6,9V7L13.66,7z"> </path> </g> </g> </svg>
</sm-input>
</div>
${branchesButtons.length ? html`<div class="task__branch_container">${branchesButtons}</div>` : ''}
</li>
`;
} else {
return html`
<li class=${`admin-task ${status}`} .dataset=${{ taskId: task }}>
<div class="flex align-center gap-0-3 space-between">
<button class="button button--small button--danger" onclick=${markTaskAsIncomplete}>
<svg class="icon margin-right-0-3" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><path d="M17,12c-2.76,0-5,2.24-5,5s2.24,5,5,5c2.76,0,5-2.24,5-5S19.76,12,17,12z M18.65,19.35l-2.15-2.15V14h1v2.79l1.85,1.85 L18.65,19.35z M18,3h-3.18C14.4,1.84,13.3,1,12,1S9.6,1.84,9.18,3H6C4.9,3,4,3.9,4,5v15c0,1.1,0.9,2,2,2h6.11 c-0.59-0.57-1.07-1.25-1.42-2H6V5h2v3h8V5h2v5.08c0.71,0.1,1.38,0.31,2,0.6V5C20,3.9,19.1,3,18,3z M12,5c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1c0.55,0,1,0.45,1,1C13,4.55,12.55,5,12,5z"/></g></svg>
Mark as incomplete
</button>
<span class="tag">Completed</span>
</div>
<h4 class="task-title capitalize">${title}</h4>
<div class="assigned-interns">
${assignedInternsCards}
</div>
<details>
<summary>View details</summary>
${taskDescription}
${branchesButtons.length ? html`<div class="task__branch_container">${branchesButtons}</div>` : ''}
<div class="display-task__details flex flex-wrap gap-0-3 margin-top-1">
<div class="display-task__detail">
<span class="display-task__detail__title">Category: </span>
<span class="display-task__detail__value">${floGlobals.taskCategories[category]}</span>
</div>
<div class="display-task__detail">
<span class="display-task__detail__title">Duration: </span>
<span class="display-task__detail__value">${duration} ${durationType}</span>
</div>
<div class="display-task__detail">
<span class="display-task__detail__title">Max slots: </span>
<span class="display-task__detail__value">${maxSlots}</span>
</div>
<div class="display-task__detail">
<span class="display-task__detail__title">Reward: </span>
<span class="display-task__detail__value">${reward}</span>
</div>
</div>
</details>
</li>
`;
}
},
taskRequestCard(request) {
const { details: { taskId, name, brief, contact, portfolioLink }, floID, vectorClock } = request
@ -2540,7 +2585,7 @@
</p>`)
}
if (taskListContainer === 'task_list') {
branchTasks.slice(4).forEach((task) => tasks.push(render.taskListItem(task, getRef(taskListContainer))))
branchTasks.slice(4).forEach((task) => tasks.push(render.adminTask(task)))
} else {
branchTasks.slice(4).forEach((task) => tasks.push(render.taskCard(task)))
}
@ -2579,27 +2624,17 @@
return '₹0';
return amount.toLocaleString(currency === 'inr' ? `en-IN` : 'en-US', { style: 'currency', currency, maximumFractionDigits: 0 })
}
delegate(getRef('task_list'), 'mousedown', 'sm-checkbox', (e) => {
e.preventDefault();
currentTask = e.target.closest('.task-list-item');
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`
function initTaskScoring(e) {
currentTask = e.target.closest('.admin-task');
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>
<sm-input type="number" min="0" max="50" class="flex-1" placeholder="Rate out of 50" error-text="Points must be between 0-50" autofocus 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>
@ -2607,9 +2642,19 @@
<button id="rate_participants_btn" class="button button--primary" type="submit" disabled onclick="rateParticipants()"> Rate </button>
</sm-form>
`)
openPopup('rate_participants_popup')
}
})
openPopup('rate_participants_popup')
}
function markTaskAsIncomplete(e) {
currentTask = e.target.closest('.admin-task');
getConfirmation('Mark this task as incomplete?', { message: 'Score given to participants regarding this task will also be removed', confirmText: 'Mark as incomplete' }).then(res => {
if (res) {
RIBC.admin.putTaskStatus('incomplete', appState.params.id, appState.params.branch, currentTask.dataset.taskId)
// TODO: remove task scores from intern rating
renderBranchTasks()
}
})
}
// format unix timestamp to yyyy-mm-dd
function formatDate(unixTimestamp) {
const date = new Date(unixTimestamp);
@ -2623,6 +2668,7 @@
// remove task from displayed list
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
const filteredTasks = RIBC.getDisplayedTasks().filter(task => task !== taskId)
renderBranchTasks()
}
function rateParticipants() {
document.querySelectorAll('.rating-part').forEach((ratingPart) => {
@ -2634,10 +2680,9 @@
})
markTaskAsCompleted()
closePopup()
currentTask.querySelector('sm-checkbox').checked = true;
}
delegate(getRef('task_list'), 'change', 'sm-select', (e) => {
currentTask = e.target.closest('.task-list-item');
currentTask = e.target.closest('.admin-task');
if (!currentTask) return;
const taskDetails = {
[e.target.dataset.editField]: e.target.value
@ -2646,7 +2691,7 @@
notify('Changes saved locally, commit the changes to make them permanent', 'success')
})
getRef('task_list').addEventListener('focusout', (e) => {
currentTask = e.target.closest('.task-list-item');
currentTask = e.target.closest('.admin-task');
if (!currentTask) return;
const ogTaskDetails = RIBC.getTaskDetails(appState.params.id, appState.params.branch, currentTask.dataset.taskId)
const newTaskDetails = {}
@ -2669,8 +2714,8 @@
}
})
getRef('task_list').addEventListener('click', (e) => {
if (e.target.closest('.task-list-item')) {
currentTask = e.target.closest('.task-list-item');
if (e.target.closest('.admin-task')) {
currentTask = e.target.closest('.admin-task');
}
if (e.target.closest('.task-option')) {
const optionButton = e.target.closest('.task-option')