summaryrefslogtreecommitdiffstats
path: root/src/wwwroot/scripts
diff options
context:
space:
mode:
authorivar <i@oiee.no>2025-10-19 23:41:23 +0200
committerivar <i@oiee.no>2025-10-19 23:41:23 +0200
commit3f4c0720e1e3421431e7baa20882a4a4512a7fab (patch)
tree734ca81d7d0841d8863e3f523ebba14c282dc681 /src/wwwroot/scripts
downloadfagprove-3f4c0720e1e3421431e7baa20882a4a4512a7fab.tar.xz
fagprove-3f4c0720e1e3421431e7baa20882a4a4512a7fab.zip
InitialHEADmaster
Diffstat (limited to 'src/wwwroot/scripts')
-rw-r--r--src/wwwroot/scripts/base.js97
-rw-r--r--src/wwwroot/scripts/cabins.js211
-rw-r--r--src/wwwroot/scripts/index.js0
-rw-r--r--src/wwwroot/scripts/login.js76
-rw-r--r--src/wwwroot/scripts/prototypes.js76
-rw-r--r--src/wwwroot/scripts/reservationForm.js92
-rw-r--r--src/wwwroot/scripts/reservations.js128
-rw-r--r--src/wwwroot/scripts/users.js188
-rw-r--r--src/wwwroot/scripts/utils.js91
9 files changed, 959 insertions, 0 deletions
diff --git a/src/wwwroot/scripts/base.js b/src/wwwroot/scripts/base.js
new file mode 100644
index 0000000..1c8663c
--- /dev/null
+++ b/src/wwwroot/scripts/base.js
@@ -0,0 +1,97 @@
+const constants ={
+ cabinFieldsValues: "cabin_fields_values"
+};
+
+kendo.culture("no");
+
+$(document).ready(function () {
+ $("#log-out-button").on("click", function () {
+ $.get("/api/account/logout", null, function () {
+ location.replace("/");
+ })
+ });
+ $('.ui.checkbox')
+ .checkbox()
+ ;
+ $('.ui.dropdown').dropdown();
+ $('.ui.radio.checkbox').checkbox();
+ $('.selection.dropdown').dropdown();
+ $('.ui.calendar').calendar({
+ type: 'date'
+ });
+ $('.accordion')
+ .accordion({
+ selector: {
+ trigger: '.title'
+ }
+ });
+ $("#sidebar-menu-toggler").on("click", function () {
+ let target = $(this).data("target");
+ $(target)
+ .sidebar({
+ dimPage: true,
+ scrollLock: true,
+ exclusive: true,
+ delaySetup: true,
+ useLegacy: "auto",
+ duration: 250,
+ mobileTransition: "overlay",
+ transition: "overlay"
+ })
+ .sidebar("toggle");
+ });
+
+ $(".image-wrap-link").on("click", function (e) {
+ if (e.target.currentSrc) window.open(e.target.currentSrc, "_blank");
+ });
+
+ $(document).on("click", ".k-overlay", function () {
+ let kendoWindow = $(
+ ".k-window-content.k-content",
+ $(this).next("div.k-widget.k-window")
+ );
+ if (kendoWindow == null || kendoWindow.length === 0) return;
+
+ let grid = $(".k-grid");
+ kendoWindow.data("kendoWindow").close();
+ if (grid.length) {
+ grid
+ .getKendoGrid()
+ .cancelChanges();
+ }
+ });
+
+
+ $("#profile-options-button").on("click", function (e) {
+ let form = $("#edit-profile-form");
+ let modal = $("#profile-settings-modal");
+ modal.modal("show", {
+ onHidden: form.off()
+ });
+ form.on("submit", function (e) {
+ let password=$("#password").val();
+ let passwordOnceMore = $("#password-again").val();
+ if(password !== passwordOnceMore) {
+ $.notificate("Ugyldig", "Passordene er forksjellige", "error");
+ return;
+ }
+ $.ajax({
+ url: "/api/account/password",
+ method: "put",
+ data: JSON.stringify({
+ passwordOnceMore,
+ password
+ }),
+ processData: false,
+ contentType: "application/json",
+ success: function (e) {
+ modal.modal("hide");
+ $.notificate("Passord oppdatert", "Passordet ditt er oppdatert", "success");
+ },
+ error: function (e) {
+ $.notificate("En feil oppstod", e.responseJSON.error ? e.responseJSON.error : "Vennligst prøv igjen senere", "erorr");
+ }
+ })
+ })
+ })
+}); \ No newline at end of file
diff --git a/src/wwwroot/scripts/cabins.js b/src/wwwroot/scripts/cabins.js
new file mode 100644
index 0000000..ad7a870
--- /dev/null
+++ b/src/wwwroot/scripts/cabins.js
@@ -0,0 +1,211 @@
+const cabinGrid = $("#cabinGrid");
+cabinGrid.kendoGrid({
+ noRecords: {
+ template: "Fant ingen hytter"
+ },
+ filterable: false,
+ sortable: false,
+ resizable: true,
+ scrollable: true,
+ messages: {
+ commands: {
+ cancel: "Avbryt endringer",
+ canceledit: "Avbryt",
+ create: "Legg til ny hytte",
+ destroy: "Slett",
+ edit: "Rediger",
+ save: "Lagre endringer",
+ select: "Velg",
+ update: "Oppdater"
+ }
+ },
+ editable: false,
+ toolbar: "<button class='k-button k-button-icontext' id='newCabinButton'><span class='k-icon k-i-plus'></span>Legg til hytte</button>",
+ dataSource: {
+ transport: {
+ read: "/api/cabins",
+ parameterMap: function (data, type) {
+ if (data.email) {
+ if (!$.isEmail(data.email)) {
+ $.notificate("Ugyldig e-postadresse", "", "error", false);
+ throw new Error("Invalid email not going through with the request");
+ }
+ }
+ switch (type) {
+ case "create":
+ return JSON.stringify({
+ name: data.name,
+ email: data.email,
+ role: data.role
+ });
+ case "read":
+ break;
+ default:
+ return JSON.stringify({
+ name: data.name,
+ role: data.role,
+ email: data.email,
+ id: data.id
+ });
+ }
+ }
+ },
+ schema: {
+ model: {
+ id: "id",
+ fields: {
+ id: {editable: false},
+ name: {
+ editable: true,
+ validation: {required: true}
+ },
+ categoryId: {
+ editable: true,
+ validation: {required: true},
+ },
+ email: {
+ editable: true,
+ validation: {required: true}
+ }
+ }
+ }
+ },
+ error: function (e) {
+ if (e.xhr.responseJSON.error) {
+ $.notificate("En feil oppstod", e.xhr.responseJSON.error, "error");
+ }
+ },
+ requestEnd: function (e) {
+ switch (e.type) {
+ case "create":
+ $.notificate(
+ "Bruker opprettet",
+ "En velkomstmail er sendt til " + e.response.email,
+ "success"
+ );
+ usersGrid.dataSource.read();
+ break;
+ case "update":
+ $.notificate(
+ "Bruker oppdatert",
+ "Brukeren er oppdatert",
+ "success"
+ );
+ usersGrid.dataSource.read();
+ break;
+ case "destroy":
+ $.notificate(
+ "Bruker slettet",
+ "Brukeren <b>" + e.response + "</b> er slettet.",
+ "success"
+ );
+ usersGrid.dataSource.read();
+ break;
+ }
+ },
+ },
+ columns: [
+ {
+ field: "name",
+ title: "Navn",
+ filterable: {
+ multi: true,
+ search: true
+ }
+ },
+ {
+ field: "categoryName",
+ title: "Hyttefelt"
+ },
+ {
+ command:
+ {
+ template: $("#cabinRowCommandButtons").html()
+ },
+ title: "&nbsp;",
+ }
+ ]
+}).data("kendoGrid");
+
+const cabinModal = $("#cabinModal");
+$("#newCabinButton").on("click", function () {
+ cabinModal.html($("#newCabinInfoModalTemplate").html()).modal("show");
+ $(".ui.selection.dropdown").dropdown();
+ let form = $("#newCabinForm");
+ $("#submitNewCabinForm").on("click", function (e) {
+ let values = form.form("get values");
+ if (!values) return;
+ if (!values.name) {
+ $.notificate("Ugyldig", "Hytten trenger ett navn", "error");
+ return;
+ }
+ if (!values.categoryId) {
+ $.notificate("Ugyldig", "Hytten trenger ett hyttefelt", "error");
+ return;
+ }
+ values.capacity = parseInt(values.capacity);
+ $.ajax({
+ data: JSON.stringify(values),
+ url: "/api/cabins/create",
+ contentType: "application/json",
+ processData: false,
+ method: "post",
+ success: function (e) {
+ cabinModal.modal("hide").empty();
+ cabinGrid.data("kendoGrid").dataSource.read();
+ console.log(e);
+ $.notificate("Opprettet ny hytte", "Hytten " + e + " er opprettet", "success");
+ },
+ error: function (e) {
+ $.notificate("En feil oppstod", "Vennligst prøv igjen senere", "error");
+ }
+ })
+ });
+});
+
+function deleteCabin(e) {
+ let dataItem = cabinGrid.data("kendoGrid").dataItem($(e).closest("tr"));
+ if (confirm("Er du sikker på at du vil slette: " + dataItem.name + "?")) {
+ $.ajax({
+ url: "/api/cabins/delete",
+ method: "delete",
+ data: JSON.stringify(dataItem),
+ contentType: "application/json",
+ processData: false,
+ success: function (e) {
+ cabinGrid.data("kendoGrid").dataSource.read();
+ $.notificate("Hytte slettet", dataItem.name + " er slettet", "error");
+ }
+ })
+ }
+}
+
+function openEditCabinModal(e) {
+ let dataItem = cabinGrid.data("kendoGrid").dataItem($(e).closest("tr"));
+ let template = kendo.template($("#editCabinInfoModalTemplate").html());
+ let generatedHtml = template(dataItem);
+ cabinModal.html(generatedHtml).modal("show");
+ $(".ui.selection.dropdown").dropdown("set selected", dataItem.categoryId);
+ $("#submitEditCabinForm").on("click", function (e) {
+ let form = $("#editCabinForm");
+ let values = form.form("get values");
+ if (!values) return;
+ if (!values.name) return;
+ values.capacity = parseInt(values.capacity);
+ $.ajax({
+ url: "/api/cabins/update",
+ method: "put",
+ data: JSON.stringify(values),
+ contentType: "application/json",
+ processData: false,
+ success: function (e) {
+ cabinModal.modal("hide").empty();
+ cabinGrid.data("kendoGrid").dataSource.read();
+ $.notificate("Oppdatert", dataItem.name + " er oppdatert", "success");
+ },
+ error: function (e) {
+ $.notificate("En feil oppstod", e.error ? e.error : "Vennligst prøv igjen senere", "error");
+ }
+ })
+ })
+}
diff --git a/src/wwwroot/scripts/index.js b/src/wwwroot/scripts/index.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/wwwroot/scripts/index.js
diff --git a/src/wwwroot/scripts/login.js b/src/wwwroot/scripts/login.js
new file mode 100644
index 0000000..247301b
--- /dev/null
+++ b/src/wwwroot/scripts/login.js
@@ -0,0 +1,76 @@
+$("#login-form").on("submit", function(e) {
+ let form = $(this);
+ let errorMessage = $("#error");
+ errorMessage.hide();
+ form.addClass("loading");
+ let values = form.form("get values");
+ if (!values) {
+ errorMessage.text("En feil oppstod, vennligst prøv igjen senere");
+ errorMessage.show();
+ form.removeClass("loading");
+ return;
+ }
+ if (!values.username || !values.password) {
+ errorMessage.text("Ett eller flere felt er ikke fylt inn.");
+ errorMessage.show();
+ form.removeClass("loading");
+ return;
+ }
+
+ if (!$.isEmail(values.username)) {
+ errorMessage.text("Det ser ikke ut som e-postadresse.");
+ errorMessage.show();
+ form.removeClass("loading");
+ return;
+ }
+ let requestVerificationToken = values.__RequestVerificationToken;
+ delete values.__RequestVerificationToken;
+ $.ajax({
+ method: "post",
+ url: "/api/account/login",
+ data: JSON.stringify(values),
+ processData: false,
+ contentType: "application/json",
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader(
+ "RequestVerificationToken",
+ requestVerificationToken
+ );
+ },
+ success: function() {
+ location.replace("/app");
+ },
+ error: function(e) {
+ console.error(e);
+ form.removeClass("loading");
+ if (e.status === 400 && e.responseJSON) {
+ errorMessage.text(e.responseJSON);
+ errorMessage.show();
+ } else {
+ errorMessage.text(
+ "Kunne ikke logge deg inn, vennligst prøv igjen senere"
+ );
+ errorMessage.show();
+ }
+ }
+ });
+});
+let forgotModal = $("#forgot-form-modal");
+$("#forgot-pass-link").on("click", function () {
+ forgotModal.modal("show")
+});
+
+$("#forgot-form").on("submit", function(e) {
+ let email = $("#forgot-email").val();
+ if (!$.isEmail(email)) return;
+ $.ajax({
+ url: "/api/account/forgot?email=" + email,
+ success: function (e) {
+ $.notificate("Suksess", "Hvis vi finner deg i våre systemer får du straks ett nytt passord på mail.", "success");
+ forgotModal.modal("hide")
+ },
+ error: function (e) {
+ $.notificate("En feil oppstod", "Vennligts prøv igjen senere", "error");
+ }
+ });
+});
diff --git a/src/wwwroot/scripts/prototypes.js b/src/wwwroot/scripts/prototypes.js
new file mode 100644
index 0000000..9496022
--- /dev/null
+++ b/src/wwwroot/scripts/prototypes.js
@@ -0,0 +1,76 @@
+"use strict";
+Date.prototype.addDays = function (days) {
+ let date = new Date(this.valueOf());
+ date.setDate(date.getDate() + days);
+ return date;
+};
+
+Date.prototype.substractDays = function (days) {
+ let date = new Date(this.valueOf());
+ date.setDate(date.getDate() - days);
+ return date;
+};
+
+Storage.prototype.removeRegex = function (r) {
+ if (!r) return;
+ let n = sessionStorage.length;
+ while (n--) {
+ let key = sessionStorage.key(n);
+ let rx = new RegExp(r);
+ if (rx.test(key)) {
+ sessionStorage.removeItem(key);
+ }
+ }
+};
+
+Storage.prototype.setStringified = function (key, value) {
+ let stringified = JSON.stringify(value);
+ sessionStorage.setItem(key, stringified);
+};
+
+Storage.prototype.getParsedValue = function (key) {
+ try {
+ let value = sessionStorage.getItem(key);
+ return JSON.parse(value);
+ } catch (e) {
+ return null;
+ }
+};
+
+//"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});
+String.prototype.formatUnicorn = function () {
+ let str = this.toString();
+ if (arguments.length) {
+ let t = typeof arguments[0];
+ let key;
+ let args = ("string" === t || "number" === t) ?
+ Array.prototype.slice.call(arguments)
+ : arguments[0];
+ for (key in args) {
+ str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
+ }
+ }
+ return str;
+};
+
+//"Hello, {0}, are you feeling {1}?".format("Gabriel", "OK");
+String.prototype.format = function () {
+ let args = arguments;
+ return this.replace(/{(\d+)}/g, function (match, number) {
+ return typeof args[number] != 'undefined'
+ ? args[number]
+ : match
+ ;
+ });
+};
+
+String.prototype.toHash = function () {
+ let hash = 0, i, chr;
+ if (this.length === 0) return hash;
+ for (i = 0; i < this.length; i++) {
+ chr = this.charCodeAt(i);
+ hash = ((hash << 5) - hash) + chr;
+ hash |= 0; // Convert to 32bit integer
+ }
+ return hash;
+};
diff --git a/src/wwwroot/scripts/reservationForm.js b/src/wwwroot/scripts/reservationForm.js
new file mode 100644
index 0000000..75c7b7a
--- /dev/null
+++ b/src/wwwroot/scripts/reservationForm.js
@@ -0,0 +1,92 @@
+const calendarElement = $("#calendar");
+calendarElement.kendoDateRangePicker({
+ value: new Date(),
+ weekNumber: true,
+ footer: false,
+ min: new Date(),
+ culture: "no",
+ format: "dd-MM-yyyy",
+ messages: {
+ startLabel: "Fra",
+ endLabel: "Til"
+ }
+}).data("kendoDateRangePicker");
+
+function setDisabledDates(arrayOfDateStrings) {
+ let calendar = calendarElement.data('kendoDateRangePicker');
+ let options = calendar.options;
+ options.disableDates = null; // if the new cabin pick does not disable any dates, the "old" dates carries over.
+ if (arrayOfDateStrings) {
+ options.disableDates = arrayOfDateStrings.map(v => new Date(v));
+ }
+ calendar.destroy();
+ calendarElement.html("");
+ calendarElement.kendoDateRangePicker(options);
+ calendarElement.data('kendoDateRangePicker').enable();
+ calendarElement.data('kendoDateRangePicker').open();
+}
+
+function pickCabin(element, id) {
+ $("#second-step").fadeOut();
+ $(".card").removeClass("raised green");
+ $(".choose-cabin-button").text("Velg");
+ $(".choose-cabin-button").removeClass("green");
+ $(element).closest(".card").addClass("raised green");
+ $(element).closest(".card").children(".card-title").show();
+ $(element).closest(".choose-cabin-button").text("Valgt");
+ $(element).closest(".choose-cabin-button").addClass("green");
+ sessionStorage["cabinId"] = id;
+ $.ajax({
+ url: "/api/reservations/occupancy?cabinId=" + id,
+ method: "get",
+ success: function (e) {
+ $("#second-step").fadeIn();
+ setDisabledDates(e);
+ }
+ })
+}
+
+$("#submitReservation").on("click", function () {
+ if ($("#consent").checkbox("is checked") === false) {
+ $.notificate("Ugyldig", "Du må samtykke til bruksvilkårene", "error");
+ return;
+ }
+ let extra = $("#comment").val();
+ let from = calendarElement.data("kendoDateRangePicker").range().start;
+ let to = calendarElement.data("kendoDateRangePicker").range().end;
+ let cabinId = sessionStorage["cabinId"];
+ if (!cabinId) {
+ $.notificate("Ugyldig", "En hytte må velges", "error");
+ return;
+ }
+ if (!from) {
+ $.notificate("Ugyldig", "En innsjeks dato er påkrevd", "error");
+ return;
+ }
+ if (!to) {
+ $.notificate("Ugyldig", "En utsjekks dato er påkrevd", "error");
+ return;
+ }
+ let data = {
+ ReservationObjectId: cabinId,
+ From: new Date(from).toISOString(),
+ To: new Date(to).toISOString(),
+ Extra: extra
+ };
+
+ $.ajax({
+ url: "/api/reservations/create",
+ method: "post",
+ data: JSON.stringify(data),
+ processData: false,
+ contentType: "application/json",
+ success: function (e) {
+ $.notificate("Registrert", "Din reservasjon er registrert og venter nå på godkjenning fra en administrator", "success");
+ $("#submitReservation").remove();
+ },
+ error: function (e) {
+ console.log(e);
+ $.notificate("En feil oppstod", e.responseJSON.error ? e.responseJSON.error : "Vennligst prøv igjen senere", "error");
+ }
+ })
+});
diff --git a/src/wwwroot/scripts/reservations.js b/src/wwwroot/scripts/reservations.js
new file mode 100644
index 0000000..f2f371a
--- /dev/null
+++ b/src/wwwroot/scripts/reservations.js
@@ -0,0 +1,128 @@
+const reservationsGrid = $("#reservationsGrid");
+const reservationsModal = $("#reservationModal");
+reservationsGrid.kendoGrid({
+ noRecords: {
+ template: "Fant ingen reservasjoner"
+ },
+ filterable: true,
+ sortable: false,
+ resizable: true,
+ scrollable: true,
+ editable: false,
+ dataSource: {
+ transport: {
+ read: "/api/reservations/all",
+ }
+ },
+ schema: {
+ model: {
+ id: "id",
+ fields: {
+ id: {editable: false}
+ }
+ }
+ },
+ error: function (e) {
+ if (e.xhr.responseJSON.error) {
+ $.notificate("En feil oppstod", e.xhr.responseJSON.error, "error");
+ }
+ },
+ columns:
+ [
+ {
+ field: "name",
+ title: "Navn",
+ filterable: {
+ multi: true,
+ search: true
+ }
+ },
+ {
+ title: "Fra/Til",
+ template: "#= data.from # / #= data.to #"
+ },
+ {
+ field: "status",
+ title: "Status",
+ filterable: {
+ multi: true,
+ search: false
+ },
+ values: [
+ {
+ text: "Ventende",
+ value: 0
+ },
+ {
+ text: "Godkjent",
+ value: 1,
+ },
+ {
+ text: "Avvist",
+ value: 2
+ },
+ {
+ text: "Inaktiv",
+ value: 3
+ },
+ ],
+ template: $("#reservationStatusTextTemplate").html()
+ },
+ {
+ field: "cabin",
+ title: "Hytte",
+ filterable: {
+ multi: true,
+ search: false
+ }
+ },
+ {
+ command:
+ {
+ template: $("#reservationsRowCommandButtons").html()
+ },
+ title: "&nbsp;",
+ }
+ ]
+});
+
+function inspectReservation(e) {
+ let dataItem = reservationsGrid.data("kendoGrid").dataItem($(e).closest("tr"));
+ let template = kendo.template($("#reservationInfoTemplate").html());
+ let generatedHtml = template(dataItem);
+ reservationsModal.html(generatedHtml);
+ reservationsModal.modal("show");
+}
+
+function grantReservation(e) {
+ let dataItem = reservationsGrid.data("kendoGrid").dataItem($(e).closest("tr"));
+ $.ajax({
+ url: "/api/reservations/grant?id=" + dataItem.id,
+ method: "get",
+ success: function (e) {
+ $.notificate("Reservasjon godkjent", dataItem.name + " har fått en statusoppdatering på mail", "success");
+ reservationsGrid.data("kendoGrid").dataSource.read();
+ },
+ error: function (e) {
+ $.notificate("En feil oppstod", e.error ? e.error : "Vennligst prøv igjen senere", "error");
+ reservationsGrid.data("kendoGrid").dataSource.read();
+ }
+ })
+}
+
+function rejectReservation(e) {
+ let dataItem = reservationsGrid.data("kendoGrid").dataItem($(e).closest("tr"));
+ $.ajax({
+ url: "/api/reservations/deny?id=" + dataItem.id,
+ method: "get",
+ success: function (e) {
+ $.notificate("Reservasjon avvist", dataItem.name + " har fått en statusoppdatering på mail", "success");
+ reservationsGrid.data("kendoGrid").dataSource.read();
+ },
+ error: function (e) {
+ $.notificate("En feil oppstod", e.error ? e.error : "Vennligst prøv igjen senere", "error");
+ reservationsGrid.data("kendoGrid").dataSource.read();
+ }
+ })
+
+}
diff --git a/src/wwwroot/scripts/users.js b/src/wwwroot/scripts/users.js
new file mode 100644
index 0000000..2c04412
--- /dev/null
+++ b/src/wwwroot/scripts/users.js
@@ -0,0 +1,188 @@
+let usersGrid = $("#usersGrid").kendoGrid({
+ noRecords: {
+ template: "Fant ingen brukere"
+ },
+ filterable: true,
+ sortable: false,
+ resizable: true,
+ scrollable: true,
+ messages: {
+ commands: {
+ cancel: "Avbryt endringer",
+ canceledit: "Avbryt",
+ create: "Legg til ny bruker",
+ destroy: "Slett",
+ edit: "Rediger",
+ save: "Lagre endringer",
+ select: "Velg",
+ update: "Oppdater"
+ }
+ },
+ editable: {
+ mode: "inline",
+ confirmation: "Er du sikker på at du vil slette denne brukeren?",
+ cancelDelete: "Avbryt",
+ confirmDelete: "Jeg er sikker"
+ },
+ toolbar: ["create", "search"],
+ dataSource: {
+ transport: {
+ read: "/api/users",
+ destroy: {
+ url: "/api/users/delete",
+ contentType: "application/json",
+ method: "delete"
+ },
+ create: {
+ url: "/api/users/create",
+ method: "post",
+ contentType: "application/json"
+ },
+ update: {
+ url: "/api/users/update",
+ contentType: "application/json",
+ method: "put"
+ },
+ parameterMap: function (data, type) {
+ if (data.email) {
+ if (!$.isEmail(data.email)) {
+ $.notificate("Ugyldig e-postadresse", "", "error");
+ return false;
+ }
+ }
+ switch (type) {
+ case "create":
+ return JSON.stringify({
+ name: data.name,
+ email: data.email,
+ role: data.role
+ });
+ case "read":
+ break;
+ default:
+ return JSON.stringify({
+ name: data.name,
+ role: data.role,
+ email: data.email,
+ id: data.id
+ });
+ }
+ }
+ },
+ schema: {
+ model: {
+ id: "id",
+ fields: {
+ id: {editable: false},
+ name: {
+ editable: true,
+ validation: {required: true}
+ },
+ role: {
+ editable: true,
+ validation: {required: true},
+ },
+ email: {
+ editable: true,
+ validation: {required: true}
+ }
+ }
+ }
+ },
+ error: function (e) {
+ if (e.xhr.responseJSON.error) {
+ $.notificate("En feil oppstod", e.xhr.responseJSON.error ? e.xhr.responseJSON.error : "Vennligst prøv igjen senere", "error");
+ }
+ },
+ requestEnd: function (e) {
+ switch (e.type) {
+ case "create":
+ $.notificate(
+ "Bruker opprettet",
+ "En velkomstmail er sendt til " + e.response.email,
+ "success"
+ );
+ usersGrid.dataSource.read();
+ break;
+ case "update":
+ $.notificate(
+ "Bruker oppdatert",
+ "Brukeren er oppdatert",
+ "success"
+ );
+ usersGrid.dataSource.read();
+ break;
+ case "destroy":
+ $.notificate(
+ "Bruker slettet",
+ "Brukeren <b>" + e.response + "</b> er slettet.",
+ "success"
+ );
+ usersGrid.dataSource.read();
+ break;
+ }
+ },
+ },
+ columns: [
+ {
+ field: "name",
+ title: "Navn",
+ filterable: {
+ multi: true,
+ search: true
+ }
+ },
+ {
+ field: "email",
+ title: "E-post",
+ filterable: false,
+ template:
+ '<a href="mailto:#=data.email#" class="link" title="Send mail til #=data.email#">#=data.email# <i class="at icon"></i></a>'
+ },
+ {
+ field: "role",
+ title: "Rolle",
+ filterable: {
+ multi: true,
+ search: false
+ },
+ values: [
+ {text: "Administrator", value: 1},
+ {text: "Vanlig", value: 0}
+ ]
+ },
+ {
+ command: ["edit", "destroy"],
+ title: "&nbsp;",
+ width: "300px"
+ }
+ ]
+}).data("kendoGrid");
+
+$(function () {
+
+ let minTableWidth;
+ let minColumnWidth = 100;
+ let th;
+ let idx;
+ let grid;
+
+ usersGrid.resizable.bind("start", function (e) {
+ th = $(e.currentTarget).data("th");
+ idx = th.index();
+ grid = th.closest(".k-grid").data("kendoGrid");
+ });
+
+ usersGrid.resizable.bind("resize", function (e) {
+ if (th.width() >= minColumnWidth) {
+ minTableWidth = grid.tbody.closest("table").width();
+ }
+
+ if (th.width() < minColumnWidth) {
+ // the next line is ONLY needed if Grid scrolling is enabled
+ grid.thead.closest("table").width(minTableWidth).children("colgroup").find("col").eq(idx).width(minColumnWidth);
+
+ grid.tbody.closest("table").width(minTableWidth).children("colgroup").find("col").eq(idx).width(minColumnWidth);
+ }
+ });
+});
diff --git a/src/wwwroot/scripts/utils.js b/src/wwwroot/scripts/utils.js
new file mode 100644
index 0000000..f20ab78
--- /dev/null
+++ b/src/wwwroot/scripts/utils.js
@@ -0,0 +1,91 @@
+$.niceDate = function (date) {
+ return kendo.toString(date, "dddd, MMMM d").toUpperCase();
+};
+
+$.validateTimeInput = function (input) {
+ return $.isHourAndMinute(input.val());
+};
+
+$.timeInput = function (container, options) {
+ $('<input name="' + options.field + '"/>')
+ .appendTo(container)
+ .kendoMaskedTextBox({
+ mask: "00:00"
+ });
+};
+
+$.getTimeOfDay = function (date) {
+ return kendo.toString(new Date(date), "HH:mm");
+};
+
+$.handlePhoneInput = function (evt) {
+ let theEvent = evt || window.event;
+ let key;
+ if (theEvent.type === "paste") {
+ key = event.clipboardData.getData("text/plain");
+ } else {
+ let key = theEvent.keyCode || theEvent.which;
+ key = String.fromCharCode(key);
+ }
+ let regex = /[0-9|+]|\./;
+ if (!regex.test(key)) {
+ theEvent.returnValue = false;
+ if (theEvent.preventDefault) theEvent.preventDefault();
+ }
+};
+
+$.notificate = function (title, message, type, noautohide) {
+ $('body')
+ .toast({
+ title: title,
+ message: message,
+ class: type,
+ displayTime: noautohide ? 0 : 5000
+ });
+};
+
+$.isHourAndMinute = function (value) {
+ let r = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/;
+ return r.test(value);
+};
+
+$.isEmail = function (email) {
+ let re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
+ return re.test(String(email).toLowerCase());
+};
+
+$.isIe = function () {
+ let ua = window.navigator.userAgent;
+ let msie = ua.indexOf("MSIE ");
+ return msie > 0;
+};
+
+$.isPhoneNumber = function (phone) {
+ if (phone.length < 8 || phone.length > 13) return false;
+ let re = /(0047|\\+47|47)?\d/;
+ return re.test(String(phone));
+};
+
+$.urlParam = function (name) {
+ let results = new RegExp("[?&]" + name + "=([^&#]*)").exec(
+ window.location.href
+ );
+ if (results == null) {
+ return 0;
+ }
+ return results[1] || 0;
+};
+
+$.isGuid = function (stringToTest) {
+ if (stringToTest[0] === "{") {
+ stringToTest = stringToTest.substring(1, stringToTest.length - 1);
+ }
+ let regexGuid = /^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$/gi;
+ return regexGuid.test(stringToTest);
+};
+
+$.isMobile = function () {
+ let x = window.matchMedia("(max-width: 700px)");
+ x.addEventListener("change", $.isMobile);
+ return x.matches;
+};