diff --git a/db.sql b/db.sql
new file mode 100644
index 0000000..2197ba9
--- /dev/null
+++ b/db.sql
@@ -0,0 +1,185 @@
+-- --------------------------------------------------------
+-- Host: 10.10.5.31
+-- Server-Version: 8.0.42-0ubuntu0.24.04.1 - (Ubuntu)
+-- Server-Betriebssystem: Linux
+-- HeidiSQL Version: 12.10.0.7000
+-- --------------------------------------------------------
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET NAMES utf8 */;
+/*!50503 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+
+-- Exportiere Datenbank-Struktur für hikos
+CREATE DATABASE IF NOT EXISTS `hikos` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
+USE `hikos`;
+
+-- Exportiere Struktur von Tabelle hikos.aduser
+CREATE TABLE IF NOT EXISTS `aduser` (
+ `aduser_id` int NOT NULL AUTO_INCREMENT,
+ `aduser_samaccountname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ `aduser_sid` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ `aduser_ruleset_id` int NOT NULL DEFAULT '-1',
+ PRIMARY KEY (`aduser_id`),
+ UNIQUE KEY `aduser_samaccountname` (`aduser_samaccountname`),
+ UNIQUE KEY `aduser_sid` (`aduser_sid`),
+ KEY `FK_aduser_ruleset` (`aduser_ruleset_id`),
+ CONSTRAINT `FK_aduser_ruleset` FOREIGN KEY (`aduser_ruleset_id`) REFERENCES `ruleset` (`ruleset_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.aduser: ~0 rows (ungefähr)
+
+-- Exportiere Struktur von Tabelle hikos.contact
+CREATE TABLE IF NOT EXISTS `contact` (
+ `contact_id` int NOT NULL AUTO_INCREMENT,
+ `contact_owner_id` int NOT NULL DEFAULT '-1',
+ `contact_aduser_id` int DEFAULT NULL,
+ `contact_displayname` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ `contact_phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `contact_mobile` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `contact_homeoffice` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `contact_email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `contact_room` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `contact_department_id` int DEFAULT NULL,
+ `contact_location_id` int DEFAULT NULL,
+ PRIMARY KEY (`contact_id`) USING BTREE,
+ UNIQUE KEY `contact_aduser_id` (`contact_aduser_id`),
+ KEY `FK_contact_department` (`contact_department_id`),
+ KEY `FK_contact_location` (`contact_location_id`),
+ CONSTRAINT `FK_contact_aduser_2` FOREIGN KEY (`contact_aduser_id`) REFERENCES `aduser` (`aduser_id`),
+ CONSTRAINT `FK_contact_department` FOREIGN KEY (`contact_department_id`) REFERENCES `department` (`department_id`),
+ CONSTRAINT `FK_contact_location` FOREIGN KEY (`contact_location_id`) REFERENCES `location` (`location_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.contact: ~1 rows (ungefähr)
+REPLACE INTO `contact` (`contact_id`, `contact_owner_id`, `contact_aduser_id`, `contact_displayname`, `contact_phone`, `contact_mobile`, `contact_homeoffice`, `contact_email`, `contact_room`, `contact_department_id`, `contact_location_id`) VALUES
+ (1, -1, NULL, 'Bergner, Jan', '1142', '123', '123', '123', '123', NULL, NULL);
+
+-- Exportiere Struktur von Tabelle hikos.contactkeyword
+CREATE TABLE IF NOT EXISTS `contactkeyword` (
+ `contactkeyword_contact` int NOT NULL,
+ `contactkeyword_keyword` int NOT NULL,
+ PRIMARY KEY (`contactkeyword_contact`,`contactkeyword_keyword`),
+ KEY `FK_contactkeyword_keyword` (`contactkeyword_keyword`),
+ CONSTRAINT `FK_contactkeyword_contact` FOREIGN KEY (`contactkeyword_contact`) REFERENCES `contact` (`contact_id`),
+ CONSTRAINT `FK_contactkeyword_keyword` FOREIGN KEY (`contactkeyword_keyword`) REFERENCES `keyword` (`keyword_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.contactkeyword: ~0 rows (ungefähr)
+
+-- Exportiere Struktur von Tabelle hikos.department
+CREATE TABLE IF NOT EXISTS `department` (
+ `department_id` int NOT NULL AUTO_INCREMENT,
+ `department_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ PRIMARY KEY (`department_id`),
+ UNIQUE KEY `department_name` (`department_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.department: ~0 rows (ungefähr)
+
+-- Exportiere Struktur von Tabelle hikos.flag
+CREATE TABLE IF NOT EXISTS `flag` (
+ `flag_id` int NOT NULL AUTO_INCREMENT,
+ `flag_contact_id` int NOT NULL,
+ `flag_key` varchar(250) COLLATE utf8mb4_general_ci NOT NULL,
+ `flag_value` longtext COLLATE utf8mb4_general_ci,
+ PRIMARY KEY (`flag_id`),
+ UNIQUE KEY `flag_contact_id_flag_key` (`flag_contact_id`,`flag_key`),
+ CONSTRAINT `FK__contact` FOREIGN KEY (`flag_contact_id`) REFERENCES `contact` (`contact_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.flag: ~0 rows (ungefähr)
+
+-- Exportiere Struktur von Tabelle hikos.keyword
+CREATE TABLE IF NOT EXISTS `keyword` (
+ `keyword_id` int NOT NULL AUTO_INCREMENT,
+ `keyword_owner` int NOT NULL DEFAULT '-1',
+ `keyword_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ PRIMARY KEY (`keyword_id`),
+ UNIQUE KEY `keyword_owner_keyword_name` (`keyword_owner`,`keyword_name`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.keyword: ~2 rows (ungefähr)
+REPLACE INTO `keyword` (`keyword_id`, `keyword_owner`, `keyword_name`) VALUES
+ (1, -1, 'Test'),
+ (2, 1, 'Demo1');
+
+-- Exportiere Struktur von Tabelle hikos.location
+CREATE TABLE IF NOT EXISTS `location` (
+ `location_id` int NOT NULL AUTO_INCREMENT,
+ `location_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ `location_address` varchar(250) COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `location_zip` varchar(250) COLLATE utf8mb4_general_ci DEFAULT NULL,
+ `location_city` varchar(250) COLLATE utf8mb4_general_ci DEFAULT NULL,
+ PRIMARY KEY (`location_id`),
+ UNIQUE KEY `location_name` (`location_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.location: ~0 rows (ungefähr)
+
+-- Exportiere Struktur von Tabelle hikos.ruleset
+CREATE TABLE IF NOT EXISTS `ruleset` (
+ `ruleset_id` int NOT NULL AUTO_INCREMENT,
+ `ruleset_name` varchar(250) COLLATE utf8mb4_general_ci NOT NULL,
+ `ruleset_default_contact_read` int NOT NULL DEFAULT '1',
+ `ruleset_default_contact_write` int NOT NULL DEFAULT '0',
+ `ruleset_default_contact_delete` int NOT NULL DEFAULT '0',
+ `ruleset_default_keyword_read` int NOT NULL DEFAULT '1',
+ `ruleset_default_keyword_write` int NOT NULL DEFAULT '0',
+ `ruleset_default_keyword_delete` int NOT NULL DEFAULT '0',
+ `ruleset_default_keyword_attach` int NOT NULL DEFAULT '0',
+ `ruleset_default_keyword_detach` int NOT NULL DEFAULT '0',
+ `ruleset_default_aduser_read` int NOT NULL DEFAULT '0',
+ `ruleset_default_aduser_write` int NOT NULL DEFAULT '0',
+ `ruleset_default_aduser_delete` int NOT NULL DEFAULT '0',
+ `ruleset_default_location_read` int NOT NULL DEFAULT '1',
+ `ruleset_default_location_write` int NOT NULL DEFAULT '0',
+ `ruleset_default_location_delete` int NOT NULL DEFAULT '0',
+ `ruleset_default_department_read` int NOT NULL DEFAULT '1',
+ `ruleset_default_department_write` int NOT NULL DEFAULT '0',
+ `ruleset_default_department_delete` int NOT NULL DEFAULT '0',
+ `ruleset_self_contact_read` int NOT NULL DEFAULT '1',
+ `ruleset_self_contact_write` int NOT NULL DEFAULT '1',
+ `ruleset_self_keyword_attach` int NOT NULL DEFAULT '1',
+ `ruleset_self_keyword_detach` int NOT NULL DEFAULT '1',
+ `ruleset_private_contact_read` int NOT NULL DEFAULT '1',
+ `ruleset_private_contact_write` int NOT NULL DEFAULT '1',
+ `ruleset_private_keyword_add` int NOT NULL DEFAULT '1',
+ `ruleset_private_keyword_delete` int NOT NULL DEFAULT '1',
+ `ruleset_private_keyword_attach` int NOT NULL DEFAULT '1',
+ `ruleset_private_keyword_detach` int NOT NULL DEFAULT '1',
+ PRIMARY KEY (`ruleset_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.ruleset: ~2 rows (ungefähr)
+REPLACE INTO `ruleset` (`ruleset_id`, `ruleset_name`, `ruleset_default_contact_read`, `ruleset_default_contact_write`, `ruleset_default_contact_delete`, `ruleset_default_keyword_read`, `ruleset_default_keyword_write`, `ruleset_default_keyword_delete`, `ruleset_default_keyword_attach`, `ruleset_default_keyword_detach`, `ruleset_default_aduser_read`, `ruleset_default_aduser_write`, `ruleset_default_aduser_delete`, `ruleset_default_location_read`, `ruleset_default_location_write`, `ruleset_default_location_delete`, `ruleset_default_department_read`, `ruleset_default_department_write`, `ruleset_default_department_delete`, `ruleset_self_contact_read`, `ruleset_self_contact_write`, `ruleset_self_keyword_attach`, `ruleset_self_keyword_detach`, `ruleset_private_contact_read`, `ruleset_private_contact_write`, `ruleset_private_keyword_add`, `ruleset_private_keyword_delete`, `ruleset_private_keyword_attach`, `ruleset_private_keyword_detach`) VALUES
+ (-1, 'Default_Ruleset', 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
+ (0, 'Default_Admin_Ruleset', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+
+-- Exportiere Struktur von Tabelle hikos.sessions
+CREATE TABLE IF NOT EXISTS `sessions` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
+ `token` varchar(512) COLLATE utf8mb4_general_ci NOT NULL,
+ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ `expires_at` timestamp NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+
+-- Exportiere Daten aus Tabelle hikos.sessions: ~4 rows (ungefähr)
+REPLACE INTO `sessions` (`id`, `username`, `token`, `created_at`, `expires_at`) VALUES
+ (5, 'admin', 'qITgAy47f5gmlBG72y_vJWh5IC7_aXQGKsL6M7IFTWU', '2025-05-20 18:14:30', '2025-05-21 18:14:30'),
+ (6, 'admin', 'Vjde9ngqPdUchF_I2_FzekK6Kb3-wBtZy_7mFPtRMV8', '2025-05-20 19:18:58', '2025-05-21 19:18:58'),
+ (7, 'admin', 'E2znECPx1Ppcwsby4ky7sQMf55Wax0KttnFmV83rqoc', '2025-05-21 04:21:43', '2025-05-22 04:21:43'),
+ (8, 'admin', 'Y7MVV-Nd4i1BPEerPLbv0jM0gJ4dYnnqZ0OtxnVWUXw', '2025-05-21 04:22:08', '2025-05-22 04:22:08');
+
+/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
+/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
+/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;
diff --git a/main.go b/main.go
index f0619d2..8e80a74 100644
--- a/main.go
+++ b/main.go
@@ -128,6 +128,7 @@ type Keyword struct {
type DataPort struct {
Contacts []Contact
Keywords []Keyword
+ /*Links []ContactKeywordLink*/
}
/* ################################################################## */
@@ -144,33 +145,39 @@ func (s *Server) privateHello(w http.ResponseWriter, r *http.Request) {
}
func GetDataReturnDataPort(QueryContact, QueryKeyword string) DataPort {
- rows, err := DB.Query(QueryContact)
- if err != nil {
- fmt.Println("a", err)
- }
var contList []Contact
- for rows.Next() {
- var c Contact
- err = rows.Scan(&c.Id, &c.OwnerId, &c.AdUserId, &c.DisplayName, &c.Phone, &c.Mobile, &c.Homeoffice, &c.Email, &c.Room, &c.DepartmentId, &c.LocationId)
+ var keywordList []Keyword
+
+ if QueryContact != "" {
+ rowsContact, err := DB.Query(QueryContact)
if err != nil {
- fmt.Println("b", err)
+ fmt.Println("a", err)
+ }
+ for rowsContact.Next() {
+ var c Contact
+ err = rowsContact.Scan(&c.Id, &c.OwnerId, &c.AdUserId, &c.DisplayName, &c.Phone, &c.Mobile, &c.Homeoffice, &c.Email, &c.Room, &c.DepartmentId, &c.LocationId)
+ if err != nil {
+ fmt.Println("b", err)
+ }
+ contList = append(contList, c)
}
- contList = append(contList, c)
}
- rows1, err := DB.Query(QueryKeyword)
- if err != nil {
- fmt.Println("c", err)
- }
- var keywordList []Keyword
- for rows1.Next() {
- var c0 Keyword
- err = rows1.Scan(&c0.Id, &c0.Owner, &c0.Name)
+ if QueryKeyword != "" {
+ rowsKeyword, err := DB.Query(QueryKeyword)
if err != nil {
- fmt.Println("d", err)
+ fmt.Println("c", err)
+ }
+ for rowsKeyword.Next() {
+ var c0 Keyword
+ err = rowsKeyword.Scan(&c0.Id, &c0.Owner, &c0.Name)
+ if err != nil {
+ fmt.Println("d", err)
+ }
+ keywordList = append(keywordList, c0)
}
- keywordList = append(keywordList, c0)
}
+
return DataPort{Contacts: contList, Keywords: keywordList}
}
@@ -283,44 +290,39 @@ func main() {
tplFull.ExecuteTemplate(w, "layout", nil)
})*/
- mux.HandleFunc("/htmx/kontakt", func(w http.ResponseWriter, r *http.Request) {
+ mux.HandleFunc("/htmx/contact", func(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, "bad request", http.StatusBadRequest)
return
}
sparam := strings.TrimSpace(r.Form.Get("search"))
-
+ fmt.Println("All_OK", sparam)
sqlq := "SELECT * FROM contact c WHERE c.contact_displayname LIKE '%" + sparam + "%' OR c.contact_phone LIKE '%" + sparam + "%' OR c.contact_mobile LIKE '%" + sparam + "%' OR c.contact_homeoffice LIKE '%" + sparam + "%';"
-
- rows, err := db.Query(sqlq)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- }
-
- var contList []Contact
-
- for rows.Next() {
- var c Contact
- err = rows.Scan(&c.Id)
- contList = append(contList, c)
- }
-
- tplKontakt.ExecuteTemplate(w, "kontakt", contList)
+ D := GetDataReturnDataPort(sqlq, "")
+ tplKontakt.ExecuteTemplate(w, "kontakt", D)
})
mux.HandleFunc("/htmx/kontaktbyschlagwort", func(w http.ResponseWriter, r *http.Request) {
tplKontakt.ExecuteTemplate(w, "kontakt", nil)
})
- mux.HandleFunc("/htmx/amt", func(w http.ResponseWriter, r *http.Request) {
+ mux.HandleFunc("/htmx/department", func(w http.ResponseWriter, r *http.Request) {
+ if err := r.ParseForm(); err != nil {
+ http.Error(w, "bad request", http.StatusBadRequest)
+ return
+ }
+ sparam := strings.TrimSpace(r.Form.Get("search"))
+ fmt.Println("Department_OK", sparam)
+ sqlq := "SELECT c.* FROM contact c JOIN department d ON c.contact_department_id = d.department_id WHERE d.department_name LIKE '%" + sparam + "%';"
+ D := GetDataReturnDataPort(sqlq, "")
+ tplKontakt.ExecuteTemplate(w, "kontakt", D)
+ })
+
+ mux.HandleFunc("/htmx/room", func(w http.ResponseWriter, r *http.Request) {
tplKontakt.ExecuteTemplate(w, "kontakt", nil)
})
- mux.HandleFunc("/htmx/raum", func(w http.ResponseWriter, r *http.Request) {
- tplKontakt.ExecuteTemplate(w, "kontakt", nil)
- })
-
- mux.HandleFunc("/htmx/gebaeude", func(w http.ResponseWriter, r *http.Request) {
+ mux.HandleFunc("/htmx/location", func(w http.ResponseWriter, r *http.Request) {
tplKontakt.ExecuteTemplate(w, "kontakt", nil)
})
diff --git a/static/packages/htmx/ext/README.md b/static/packages/htmx/ext/README.md
new file mode 100644
index 0000000..366e714
--- /dev/null
+++ b/static/packages/htmx/ext/README.md
@@ -0,0 +1,9 @@
+# Why Are These Files Here?
+
+These are legacy extensions for htmx 1.x and are **NOT** actively maintained or guaranteed to work with htmx 2.x.
+They are here because we unfortunately linked to unversioned unpkg URLs in the installation guides for them
+in 1.x, so we need to keep them here to preserve those URLs and not break existing users functionality.
+
+If you are looking for extensions for htmx 2.x, please see the [htmx 2.0 extensions site](https://htmx.org/extensions),
+which has links to the new extensions repos (They have all been moved to their own NPM projects and URLs, like
+they should have been from the start!)
diff --git a/static/packages/htmx/ext/_WARNING_DEPRECATED_FILES_.txt b/static/packages/htmx/ext/_WARNING_DEPRECATED_FILES_.txt
new file mode 100644
index 0000000..6dff4c2
--- /dev/null
+++ b/static/packages/htmx/ext/_WARNING_DEPRECATED_FILES_.txt
@@ -0,0 +1,5 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!! THESE FILES ARE DEPRECATED AND UNSUPPORTED !!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SEE README.md FOR MORE DETAILS
diff --git a/static/packages/htmx/ext/ajax-header.js b/static/packages/htmx/ext/ajax-header.js
new file mode 100644
index 0000000..e8c2dbc
--- /dev/null
+++ b/static/packages/htmx/ext/ajax-header.js
@@ -0,0 +1,11 @@
+if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+}
+htmx.defineExtension('ajax-header', {
+ onEvent: function (name, evt) {
+ if (name === "htmx:configRequest") {
+ evt.detail.headers['X-Requested-With'] = 'XMLHttpRequest';
+ }
+ }
+});
diff --git a/static/packages/htmx/ext/alpine-morph.js b/static/packages/htmx/ext/alpine-morph.js
new file mode 100644
index 0000000..ea41cf0
--- /dev/null
+++ b/static/packages/htmx/ext/alpine-morph.js
@@ -0,0 +1,20 @@
+if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+}
+htmx.defineExtension('alpine-morph', {
+ isInlineSwap: function (swapStyle) {
+ return swapStyle === 'morph';
+ },
+ handleSwap: function (swapStyle, target, fragment) {
+ if (swapStyle === 'morph') {
+ if (fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ Alpine.morph(target, fragment.firstElementChild);
+ return [target];
+ } else {
+ Alpine.morph(target, fragment.outerHTML);
+ return [target];
+ }
+ }
+ }
+});
diff --git a/static/packages/htmx/ext/class-tools.js b/static/packages/htmx/ext/class-tools.js
new file mode 100644
index 0000000..83f5c7c
--- /dev/null
+++ b/static/packages/htmx/ext/class-tools.js
@@ -0,0 +1,97 @@
+(function () {
+
+ if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+ }
+
+ function splitOnWhitespace(trigger) {
+ return trigger.split(/\s+/);
+ }
+
+ function parseClassOperation(trimmedValue) {
+ var split = splitOnWhitespace(trimmedValue);
+ if (split.length > 1) {
+ var operation = split[0];
+ var classDef = split[1].trim();
+ var cssClass;
+ var delay;
+ if (classDef.indexOf(":") > 0) {
+ var splitCssClass = classDef.split(':');
+ cssClass = splitCssClass[0];
+ delay = htmx.parseInterval(splitCssClass[1]);
+ } else {
+ cssClass = classDef;
+ delay = 100;
+ }
+ return {
+ operation: operation,
+ cssClass: cssClass,
+ delay: delay
+ }
+ } else {
+ return null;
+ }
+ }
+
+ function performOperation(elt, classOperation, classList, currentRunTime) {
+ setTimeout(function () {
+ elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
+ }, currentRunTime)
+ }
+
+ function toggleOperation(elt, classOperation, classList, currentRunTime) {
+ setTimeout(function () {
+ setInterval(function () {
+ elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
+ }, classOperation.delay);
+ }, currentRunTime)
+ }
+
+ function processClassList(elt, classList) {
+ var runs = classList.split("&");
+ for (var i = 0; i < runs.length; i++) {
+ var run = runs[i];
+ var currentRunTime = 0;
+ var classOperations = run.split(",");
+ for (var j = 0; j < classOperations.length; j++) {
+ var value = classOperations[j];
+ var trimmedValue = value.trim();
+ var classOperation = parseClassOperation(trimmedValue);
+ if (classOperation) {
+ if (classOperation.operation === "toggle") {
+ toggleOperation(elt, classOperation, classList, currentRunTime);
+ currentRunTime = currentRunTime + classOperation.delay;
+ } else {
+ currentRunTime = currentRunTime + classOperation.delay;
+ performOperation(elt, classOperation, classList, currentRunTime);
+ }
+ }
+ }
+ }
+ }
+
+ function maybeProcessClasses(elt) {
+ if (elt.getAttribute) {
+ var classList = elt.getAttribute("classes") || elt.getAttribute("data-classes");
+ if (classList) {
+ processClassList(elt, classList);
+ }
+ }
+ }
+
+ htmx.defineExtension('class-tools', {
+ onEvent: function (name, evt) {
+ if (name === "htmx:afterProcessNode") {
+ var elt = evt.detail.elt;
+ maybeProcessClasses(elt);
+ if (elt.querySelectorAll) {
+ var children = elt.querySelectorAll("[classes], [data-classes]");
+ for (var i = 0; i < children.length; i++) {
+ maybeProcessClasses(children[i]);
+ }
+ }
+ }
+ }
+ });
+})();
diff --git a/static/packages/htmx/ext/client-side-templates.js b/static/packages/htmx/ext/client-side-templates.js
new file mode 100644
index 0000000..d23c5c9
--- /dev/null
+++ b/static/packages/htmx/ext/client-side-templates.js
@@ -0,0 +1,100 @@
+if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+}
+htmx.defineExtension('client-side-templates', {
+ transformResponse : function(text, xhr, elt) {
+
+ var mustacheTemplate = htmx.closest(elt, "[mustache-template]");
+ if (mustacheTemplate) {
+ var data = JSON.parse(text);
+ var templateId = mustacheTemplate.getAttribute('mustache-template');
+ var template = htmx.find("#" + templateId);
+ if (template) {
+ return Mustache.render(template.innerHTML, data);
+ } else {
+ throw "Unknown mustache template: " + templateId;
+ }
+ }
+
+ var mustacheArrayTemplate = htmx.closest(elt, "[mustache-array-template]");
+ if (mustacheArrayTemplate) {
+ var data = JSON.parse(text);
+ var templateId = mustacheArrayTemplate.getAttribute('mustache-array-template');
+ var template = htmx.find("#" + templateId);
+ if (template) {
+ return Mustache.render(template.innerHTML, {"data": data });
+ } else {
+ throw "Unknown mustache template: " + templateId;
+ }
+ }
+
+ var handlebarsTemplate = htmx.closest(elt, "[handlebars-template]");
+ if (handlebarsTemplate) {
+ var data = JSON.parse(text);
+ var templateId = handlebarsTemplate.getAttribute('handlebars-template');
+ var templateElement = htmx.find('#' + templateId).innerHTML;
+ var renderTemplate = Handlebars.compile(templateElement);
+ if (renderTemplate) {
+ return renderTemplate(data);
+ } else {
+ throw "Unknown handlebars template: " + templateId;
+ }
+ }
+
+ var handlebarsArrayTemplate = htmx.closest(elt, "[handlebars-array-template]");
+ if (handlebarsArrayTemplate) {
+ var data = JSON.parse(text);
+ var templateId = handlebarsArrayTemplate.getAttribute('handlebars-array-template');
+ var templateElement = htmx.find('#' + templateId).innerHTML;
+ var renderTemplate = Handlebars.compile(templateElement);
+ if (renderTemplate) {
+ return renderTemplate(data);
+ } else {
+ throw "Unknown handlebars template: " + templateId;
+ }
+ }
+
+ var nunjucksTemplate = htmx.closest(elt, "[nunjucks-template]");
+ if (nunjucksTemplate) {
+ var data = JSON.parse(text);
+ var templateName = nunjucksTemplate.getAttribute('nunjucks-template');
+ var template = htmx.find('#' + templateName);
+ if (template) {
+ return nunjucks.renderString(template.innerHTML, data);
+ } else {
+ return nunjucks.render(templateName, data);
+ }
+ }
+
+ var xsltTemplate = htmx.closest(elt, "[xslt-template]");
+ if (xsltTemplate) {
+ var templateId = xsltTemplate.getAttribute('xslt-template');
+ var template = htmx.find("#" + templateId);
+ if (template) {
+ var content = template.innerHTML ? new DOMParser().parseFromString(template.innerHTML, 'application/xml')
+ : template.contentDocument;
+ var processor = new XSLTProcessor();
+ processor.importStylesheet(content);
+ var data = new DOMParser().parseFromString(text, "application/xml");
+ var frag = processor.transformToFragment(data, document);
+ return new XMLSerializer().serializeToString(frag);
+ } else {
+ throw "Unknown XSLT template: " + templateId;
+ }
+ }
+
+ var nunjucksArrayTemplate = htmx.closest(elt, "[nunjucks-array-template]");
+ if (nunjucksArrayTemplate) {
+ var data = JSON.parse(text);
+ var templateName = nunjucksArrayTemplate.getAttribute('nunjucks-array-template');
+ var template = htmx.find('#' + templateName);
+ if (template) {
+ return nunjucks.renderString(template.innerHTML, {"data": data});
+ } else {
+ return nunjucks.render(templateName, {"data": data});
+ }
+ }
+ return text;
+ }
+});
diff --git a/static/packages/htmx/ext/debug.js b/static/packages/htmx/ext/debug.js
new file mode 100644
index 0000000..aa88c9e
--- /dev/null
+++ b/static/packages/htmx/ext/debug.js
@@ -0,0 +1,15 @@
+if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+}
+htmx.defineExtension('debug', {
+ onEvent: function (name, evt) {
+ if (console.debug) {
+ console.debug(name, evt);
+ } else if (console) {
+ console.log("DEBUG:", name, evt);
+ } else {
+ throw "NO CONSOLE SUPPORTED"
+ }
+ }
+});
diff --git a/static/packages/htmx/ext/disable-element.js b/static/packages/htmx/ext/disable-element.js
new file mode 100644
index 0000000..0192661
--- /dev/null
+++ b/static/packages/htmx/ext/disable-element.js
@@ -0,0 +1,20 @@
+if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+}
+// Disable Submit Button
+htmx.defineExtension('disable-element', {
+ onEvent: function (name, evt) {
+ let elt = evt.detail.elt;
+ let target = elt.getAttribute("hx-disable-element");
+ let targetElements = (target == "self") ? [ elt ] : document.querySelectorAll(target);
+
+ for (var i = 0; i < targetElements.length; i++) {
+ if (name === "htmx:beforeRequest" && targetElements[i]) {
+ targetElements[i].disabled = true;
+ } else if (name == "htmx:afterRequest" && targetElements[i]) {
+ targetElements[i].disabled = false;
+ }
+ }
+ }
+});
diff --git a/static/packages/htmx/ext/event-header.js b/static/packages/htmx/ext/event-header.js
new file mode 100644
index 0000000..0ccb7de
--- /dev/null
+++ b/static/packages/htmx/ext/event-header.js
@@ -0,0 +1,41 @@
+(function(){
+ if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+ }
+ function stringifyEvent(event) {
+ var obj = {};
+ for (var key in event) {
+ obj[key] = event[key];
+ }
+ return JSON.stringify(obj, function(key, value){
+ if(value instanceof Node){
+ var nodeRep = value.tagName;
+ if (nodeRep) {
+ nodeRep = nodeRep.toLowerCase();
+ if(value.id){
+ nodeRep += "#" + value.id;
+ }
+ if(value.classList && value.classList.length){
+ nodeRep += "." + value.classList.toString().replace(" ", ".")
+ }
+ return nodeRep;
+ } else {
+ return "Node"
+ }
+ }
+ if (value instanceof Window) return 'Window';
+ return value;
+ });
+ }
+
+ htmx.defineExtension('event-header', {
+ onEvent: function (name, evt) {
+ if (name === "htmx:configRequest") {
+ if (evt.detail.triggeringEvent) {
+ evt.detail.headers['Triggering-Event'] = stringifyEvent(evt.detail.triggeringEvent);
+ }
+ }
+ }
+ });
+})();
diff --git a/static/packages/htmx/ext/head-support.js b/static/packages/htmx/ext/head-support.js
new file mode 100644
index 0000000..07c0231
--- /dev/null
+++ b/static/packages/htmx/ext/head-support.js
@@ -0,0 +1,146 @@
+//==========================================================
+// head-support.js
+//
+// An extension to htmx 1.0 to add head tag merging.
+//==========================================================
+(function(){
+
+ if (htmx.version && !htmx.version.startsWith("1.")) {
+ console.warn("WARNING: You are using an htmx 1 extension with htmx " + htmx.version +
+ ". It is recommended that you move to the version of this extension found on https://htmx.org/extensions")
+ }
+
+ var api = null;
+
+ function log() {
+ //console.log(arguments);
+ }
+
+ function mergeHead(newContent, defaultMergeStrategy) {
+
+ if (newContent && newContent.indexOf('
-1) {
+ const htmlDoc = document.createElement("html");
+ // remove svgs to avoid conflicts
+ var contentWithSvgsRemoved = newContent.replace(/