Skip to content

Commit

Permalink
feat(polls): add option to import from csv
Browse files Browse the repository at this point in the history
  • Loading branch information
NotFish232 committed Dec 8, 2023
1 parent d9ad6ad commit 4916599
Show file tree
Hide file tree
Showing 6 changed files with 1,155 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ dump.rdb
*.log
*.swp
celerybeat-schedule
celerybeat-schedule.dir
celerybeat-schedule.pag

# Development-specific ignores
devconfig.json
Expand Down
22 changes: 22 additions & 0 deletions intranet/static/css/polls.form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@
padding-bottom: 10px;
}

#import_from_csv {
width: 150px;
}

#csv_wrapper {
padding-top: 10px;
padding-bottom: 10px;
}

#csv_input {
display: none;
width: 0;
height: 0;
}

#csv_error {
padding-left: 10px;
width: 50px;
color: red;
text-decoration: none;
}

#questions {
.question {
position: relative;
Expand Down
113 changes: 91 additions & 22 deletions intranet/static/js/polls.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ function addInline(item) {
});
}

$(function() {

$(function () {
var questionTemplate = _.template($("#question-template").html());
var choiceTemplate = _.template($("#choice-template").html());

Expand All @@ -36,31 +37,99 @@ $(function() {
format: "Y-m-d H:i:s"
});

poll_questions.sort(function(a, b) {
poll_questions.sort(function (a, b) {
return a.fields.num - b.fields.num;
});

poll_choices.sort(function(a, b) {
poll_choices.sort(function (a, b) {
return a.fields.num - b.fields.num;
});

$.each(poll_questions, function(k, v) {
$.each(poll_questions, function (k, v) {
$("#questions").append(questionTemplate(v));
});

$.each(poll_choices, function(k, v) {
$.each(poll_choices, function (k, v) {
$("#questions .question[data-id='" + v.fields.question + "']").find(".choices").append(choiceTemplate(v));
});

$("#questions .type").selectize();

$("#questions [contenteditable='true']").each(function(k, v) {
$("#questions [contenteditable='true']").each(function (k, v) {
addInline(v);
});

$("#poll-form").submit(function() {
$("#import_from_csv").click(async function (e) {
e.preventDefault();
$("#csv_input").click();
});

$("#csv_input").on("change", function (e) {
e.preventDefault();
let file = $("#csv_input").prop("files")[0];
let file_reader = new FileReader();
file_reader.onload = async function (e) {
// csv should have the following headers
// name, position, platform, slogan
let csv_data = $.csv.toArrays(file_reader.result);
if (csv_data.length == 0) {
$("#csv_error").text("Empty CSV");
return;
}

let required_labels = ["position", "name", "platform", "slogan"]
let labels = csv_data[0].map(l => l.toLowerCase());
if (!required_labels.every(l => labels.includes(l))) {
let missing_labels = required_labels.filter(l => !labels.includes(l))
$("#csv_error").text(`Missing required label(s): ${missing_labels.join(", ")}`)
return;
}
$("#csv_error").text();

let content = csv_data.slice(1);
let map = {}; // (position) -> (name, platform, slogan)
for (let line of content) {
let position = line[labels.indexOf("position")];
let name = line[labels.indexOf("name")];
let platform = line[labels.indexOf("platform")];
let slogan = line[labels.indexOf("slogan")];

if (!(position in map)) {
map[position] = [];
}
map[position].push([name, platform, slogan]);
}

let sleep = async () => { await new Promise(resolve => setTimeout(resolve, 0)); };

for (let [position, choices] of Object.entries(map)) {
$("#add_question").click();
let question_element = $("#questions .question:last-child");
await sleep();

// set position, type, and max choices of question
question_element.find(".text").html(position);
question_element.find(".type").data('selectize').setValue("RAN");
question_element.find(".max").val(`${Math.min(choices.length, 3)}`);

for (let choice of choices) {
let [name, platform, slogan] = choice;

question_element.find(".add_choice").click();
await sleep();

let text_field = question_element.find(".choices .choice:last-child .info");
let text = $(`<a href="${platform}">${name} | ${slogan}</a>`)
text_field.html(text);
}
}
}
file_reader.readAsText(file);
});

$("#poll-form").submit(function () {
var out = [];
$("#questions .question").each(function() {
$("#questions .question").each(function () {
var q = {
"question": $(this).find(".text").html(),
"type": $(this).find(".type").val(),
Expand All @@ -70,7 +139,7 @@ $(function() {
if ($(this).attr("data-id")) {
q["pk"] = $(this).attr("data-id");
}
$(this).find(".choices .choice").each(function() {
$(this).find(".choices .choice").each(function () {
var c = {
"info": $(this).find(".info").html()
};
Expand All @@ -85,63 +154,63 @@ $(function() {
return true;
});

$("#add_question").click(function(e) {
$("#add_question").click(function (e) {
e.preventDefault();
var new_question = $(questionTemplate(default_question));
new_question.appendTo("#questions").hide().slideDown("fast");
new_question.find(".type").selectize();
addInline(new_question.find("[contenteditable='true']")[0]);
});

$("#questions").on("click", ".add_choice", function(e) {
$("#questions").on("click", ".add_choice", function (e) {
e.preventDefault();
var new_choice = $(choiceTemplate(default_choice));
new_choice.appendTo($(this).closest(".question").find(".choices")).hide().slideDown("fast");
addInline(new_choice.find("[contenteditable='true']")[0]);
});

$("#questions").on("click", ".question > .actions .fas.fa-arrow-up", function(e) {
$("#questions").on("click", ".question > .actions .fas.fa-arrow-up", function (e) {
var ele = $(this).closest(".question");
ele.insertBefore(ele.prev());
e.preventDefault();
});

$("#questions").on("click", ".question > .actions .fas.fa-arrow-down", function(e) {
$("#questions").on("click", ".question > .actions .fas.fa-arrow-down", function (e) {
var ele = $(this).closest(".question");
ele.insertAfter(ele.next());
e.preventDefault();
});

$("#questions").on("click", ".question .choice .actions .fas.fa-arrow-up", function(e) {
$("#questions").on("click", ".question .choice .actions .fas.fa-arrow-up", function (e) {
var ele = $(this).closest(".choice");
ele.insertBefore(ele.prev());
e.preventDefault();
});

$("#questions").on("click", ".question .choice .actions .fas.fa-arrow-down", function(e) {
$("#questions").on("click", ".question .choice .actions .fas.fa-arrow-down", function (e) {
var ele = $(this).closest(".choice");
ele.insertAfter(ele.next());
e.preventDefault();
});

$("#questions").on("click", ".question > .actions .fas.fa-times", function(e) {
$(this).closest(".question").slideUp("fast", function() {
$("#questions").on("click", ".question > .actions .fas.fa-times", function (e) {
$(this).closest(".question").slideUp("fast", function () {
$(this).remove();
});
e.preventDefault();
});

$("#questions").on("click", ".question .choice .actions .fas.fa-times", function(e) {
$(this).closest(".choice").slideUp("fast", function() {
$("#questions").on("click", ".question .choice .actions .fas.fa-times", function (e) {
$(this).closest(".choice").slideUp("fast", function () {
$(this).remove();
});
e.preventDefault();
});

$("#questions").on("change", "select.type", function(e) {
$("#questions").on("change", "select.type", function (e) {
e.preventDefault();
$("select.type").each(function() {
if($(this).val() === "RAN") {
$("select.type").each(function () {
if ($(this).val() === "RAN") {
$(this).parent().next().next().next().next().show("fast");
}
else {
Expand Down
Loading

0 comments on commit 4916599

Please sign in to comment.