add a bunch of stuff.
This commit is contained in:
Generated
+187
-2
@@ -17,6 +17,7 @@
|
|||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-svelte3": "^3.2.1",
|
"eslint-plugin-svelte3": "^3.2.1",
|
||||||
"fa-svelte": "^3.1.0",
|
"fa-svelte": "^3.1.0",
|
||||||
|
"mysql2": "^2.3.3",
|
||||||
"node-sass": "^7.0.1",
|
"node-sass": "^7.0.1",
|
||||||
"sass": "^1.49.9",
|
"sass": "^1.49.9",
|
||||||
"svelte": "^3.44.0",
|
"svelte": "^3.44.0",
|
||||||
@@ -1225,6 +1226,15 @@
|
|||||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/denque": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
@@ -2176,6 +2186,15 @@
|
|||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/generate-function": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-property": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-caller-file": {
|
"node_modules/get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
@@ -2467,7 +2486,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
},
|
},
|
||||||
@@ -2636,6 +2654,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-property": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/is-typedarray": {
|
"node_modules/is-typedarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
@@ -2803,6 +2827,12 @@
|
|||||||
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/long": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
@@ -3102,6 +3132,53 @@
|
|||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/mysql2": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"denque": "^2.0.1",
|
||||||
|
"generate-function": "^2.3.1",
|
||||||
|
"iconv-lite": "^0.6.3",
|
||||||
|
"long": "^4.0.0",
|
||||||
|
"lru-cache": "^6.0.0",
|
||||||
|
"named-placeholders": "^1.1.2",
|
||||||
|
"seq-queue": "^0.0.5",
|
||||||
|
"sqlstring": "^2.3.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/named-placeholders": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^4.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/named-placeholders/node_modules/lru-cache": {
|
||||||
|
"version": "4.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||||
|
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"pseudomap": "^1.0.2",
|
||||||
|
"yallist": "^2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/named-placeholders/node_modules/yallist": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||||
|
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/nan": {
|
"node_modules/nan": {
|
||||||
"version": "2.15.0",
|
"version": "2.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||||
@@ -3540,6 +3617,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pseudomap": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/psl": {
|
"node_modules/psl": {
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||||
@@ -3991,6 +4074,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/seq-queue": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/set-blocking": {
|
"node_modules/set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
@@ -4165,6 +4254,15 @@
|
|||||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/sqlstring": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sshpk": {
|
"node_modules/sshpk": {
|
||||||
"version": "1.17.0",
|
"version": "1.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
||||||
@@ -5747,6 +5845,12 @@
|
|||||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"denque": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"depd": {
|
"depd": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
@@ -6386,6 +6490,15 @@
|
|||||||
"globule": "^1.0.0"
|
"globule": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"generate-function": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-property": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"get-caller-file": {
|
"get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
@@ -6611,7 +6724,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
}
|
}
|
||||||
@@ -6741,6 +6853,12 @@
|
|||||||
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
|
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-property": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-typedarray": {
|
"is-typedarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
@@ -6890,6 +7008,12 @@
|
|||||||
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"long": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
@@ -7117,6 +7241,49 @@
|
|||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"mysql2": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"denque": "^2.0.1",
|
||||||
|
"generate-function": "^2.3.1",
|
||||||
|
"iconv-lite": "^0.6.3",
|
||||||
|
"long": "^4.0.0",
|
||||||
|
"lru-cache": "^6.0.0",
|
||||||
|
"named-placeholders": "^1.1.2",
|
||||||
|
"seq-queue": "^0.0.5",
|
||||||
|
"sqlstring": "^2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"named-placeholders": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^4.1.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "4.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||||
|
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"pseudomap": "^1.0.2",
|
||||||
|
"yallist": "^2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||||
|
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"nan": {
|
"nan": {
|
||||||
"version": "2.15.0",
|
"version": "2.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||||
@@ -7444,6 +7611,12 @@
|
|||||||
"retry": "^0.12.0"
|
"retry": "^0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pseudomap": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"psl": {
|
"psl": {
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||||
@@ -7755,6 +7928,12 @@
|
|||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"seq-queue": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"set-blocking": {
|
"set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
@@ -7894,6 +8073,12 @@
|
|||||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"sqlstring": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"sshpk": {
|
"sshpk": {
|
||||||
"version": "1.17.0",
|
"version": "1.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-svelte3": "^3.2.1",
|
"eslint-plugin-svelte3": "^3.2.1",
|
||||||
"fa-svelte": "^3.1.0",
|
"fa-svelte": "^3.1.0",
|
||||||
|
"mysql2": "^2.3.3",
|
||||||
"node-sass": "^7.0.1",
|
"node-sass": "^7.0.1",
|
||||||
"sass": "^1.49.9",
|
"sass": "^1.49.9",
|
||||||
"svelte": "^3.44.0",
|
"svelte": "^3.44.0",
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
-- +goose Up
|
||||||
|
-- +goose StatementBegin
|
||||||
|
CREATE TABLE scope (
|
||||||
|
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(255) NOT NULL,
|
||||||
|
`abbreviation` CHAR(8) NOT NULL
|
||||||
|
)
|
||||||
|
-- +goose StatementEnd
|
||||||
|
|
||||||
|
-- +goose Down
|
||||||
|
-- +goose StatementBegin
|
||||||
|
DROP TABLE IF EXISTS scope;
|
||||||
|
-- +goose StatementEnd
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-- +goose Up
|
||||||
|
-- +goose StatementBegin
|
||||||
|
CREATE TABLE scope_member (
|
||||||
|
`scope_id` INT NOT NULL,
|
||||||
|
`user_id` CHAR(36) NOT NULL,
|
||||||
|
`name` VARCHAR(63) NOT NULL,
|
||||||
|
`owner` BOOLEAN NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`scope_id`, `user_id`),
|
||||||
|
UNIQUE (`scope_id`, `name`)
|
||||||
|
);
|
||||||
|
-- +goose StatementEnd
|
||||||
|
|
||||||
|
-- +goose Down
|
||||||
|
-- +goose StatementBegin
|
||||||
|
DROP TABLE IF EXISTS scope_member;
|
||||||
|
-- +goose StatementEnd
|
||||||
Vendored
+7
@@ -1,11 +1,18 @@
|
|||||||
/// <reference types="@sveltejs/kit" />
|
/// <reference types="@sveltejs/kit" />
|
||||||
|
|
||||||
|
import type { ScopeEntry } from "$lib/models/scope";
|
||||||
import type Scope from "$lib/models/scope";
|
import type Scope from "$lib/models/scope";
|
||||||
|
import type User from "$lib/models/user";
|
||||||
|
|
||||||
// See https://kit.svelte.dev/docs/types#the-app-namespace
|
// See https://kit.svelte.dev/docs/types#the-app-namespace
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
declare global {
|
declare global {
|
||||||
declare namespace App {
|
declare namespace App {
|
||||||
|
interface Locals {
|
||||||
|
user: User,
|
||||||
|
scopes: ScopeEntry[],
|
||||||
|
}
|
||||||
|
|
||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
// interface Session {}
|
// interface Session {}
|
||||||
interface Stuff {
|
interface Stuff {
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-color: hsl(240, 12%, 7%);
|
background-color: hsl(240, 12%, 5%);
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import config from "$lib/config";
|
||||||
|
import type { Handle } from "@sveltejs/kit";
|
||||||
|
|
||||||
|
export const handle: Handle = async({ event, resolve }) => {
|
||||||
|
if (process.env.STUFFLOG3_USE_DUMMY_USER === "true") {
|
||||||
|
event.locals.user = {
|
||||||
|
id: "c11230be-4912-4313-83b0-410a248b5bd1",
|
||||||
|
name: "Developer",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.locals.user = {id: "", name: "Guest"};
|
||||||
|
|
||||||
|
// Actual login check.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.locals.user.id !== "") {
|
||||||
|
const db = await config.database();
|
||||||
|
event.locals.scopes = await db.withUser(event.locals.user.id).scopes().list()
|
||||||
|
} else {
|
||||||
|
event.locals.scopes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await resolve(event);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
$color-entry0: hsl(240, 5%, 7%)
|
$color-entry0: hsl(240, 5%, 7%)
|
||||||
|
$color-entry0-transparent: hsla(240, 5%, 10%, 0.7)
|
||||||
$color-entry1: hsl(240, 5%, 14%)
|
$color-entry1: hsl(240, 5%, 14%)
|
||||||
|
$color-entry1-transparent: hsla(240, 5%, 17%, 0.8)
|
||||||
$color-entry2: hsl(240, 5%, 21%)
|
$color-entry2: hsl(240, 5%, 21%)
|
||||||
|
$color-entry2-transparent: hsla(240, 5%, 24%, 0.8)
|
||||||
$color-entry3: hsl(240, 5%, 28%)
|
$color-entry3: hsl(240, 5%, 28%)
|
||||||
$color-entry4: hsl(240, 5%, 35%)
|
$color-entry4: hsl(240, 5%, 35%)
|
||||||
$color-entry5: hsl(240, 5%, 42%)
|
$color-entry5: hsl(240, 5%, 42%)
|
||||||
@@ -15,6 +18,7 @@ $color-entry13: hsl(240, 5%, 98%)
|
|||||||
|
|
||||||
$opacity-entry4: 0.40
|
$opacity-entry4: 0.40
|
||||||
$opacity-entry5: 0.60
|
$opacity-entry5: 0.60
|
||||||
|
$opacity-entry6: 0.80
|
||||||
|
|
||||||
$color-green: hsl(120, 50%, 74%)
|
$color-green: hsl(120, 50%, 74%)
|
||||||
$color-green-dark: hsl(120, 50%, 35%)
|
$color-green-dark: hsl(120, 50%, 35%)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {onMount} from "svelte";
|
||||||
|
|
||||||
|
export let initialOrientation: "portrait" | "landscape" = "portrait";
|
||||||
|
export let src = "/background.jpg";
|
||||||
|
export let opacity = 1.0;
|
||||||
|
|
||||||
|
let landscape = (initialOrientation === "landscape");
|
||||||
|
let image: HTMLImageElement;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (image.complete && typeof(image.naturalHeight) !== 'undefined' && image.naturalHeight !== 0) {
|
||||||
|
const width = image.naturalWidth;
|
||||||
|
const height = image.naturalHeight;
|
||||||
|
|
||||||
|
landscape = (width > (height * 1.50));
|
||||||
|
} else {
|
||||||
|
image.onload = () => {
|
||||||
|
const width = image.naturalWidth;
|
||||||
|
const height = image.naturalHeight;
|
||||||
|
|
||||||
|
landscape = (width > (height * 1.50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<img
|
||||||
|
bind:this={image}
|
||||||
|
class:landscape
|
||||||
|
src={src}
|
||||||
|
style={`opacity: ${opacity};`}
|
||||||
|
alt="Background"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
img {
|
||||||
|
/* Set rules to fill background */
|
||||||
|
width: 100%;
|
||||||
|
/* Set up proportionate scaling */
|
||||||
|
min-height: 100%;
|
||||||
|
height: auto;
|
||||||
|
/* Set up positioning */
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
|
||||||
|
transition: 250ms;
|
||||||
|
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.landscape {
|
||||||
|
/* Set rules to fill background */
|
||||||
|
height: 100%;
|
||||||
|
/* Set up proportionate scaling */
|
||||||
|
min-width: 100%;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -9,15 +9,16 @@
|
|||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $color-entry9;
|
color: $color-entry9;
|
||||||
background-color: $color-entry1;
|
background-color: $color-entry1-transparent;
|
||||||
border-bottom-right-radius: 0.75em;
|
border-bottom-right-radius: 0.75em;
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
padding: 0.25em 0.5ch;
|
padding: 0.25em 0.5ch;
|
||||||
transition: 250ms;
|
transition: 250ms;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
div.entry:hover {
|
div.entry:hover {
|
||||||
background-color: $color-entry2;
|
background-color: $color-entry2-transparent;
|
||||||
color: $color-entry11;
|
color: $color-entry11;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type Status from "$lib/models/status";
|
import type Status from "$lib/models/status";
|
||||||
import type { IconName } from "./Icon.svelte";
|
|
||||||
import Icon from "./Icon.svelte";
|
|
||||||
import StatusColor from "./StatusColor.svelte";
|
import StatusColor from "./StatusColor.svelte";
|
||||||
|
import StatusIcon from "./StatusIcon.svelte";
|
||||||
|
import StatusText from "./StatusText.svelte";
|
||||||
|
|
||||||
export let status: Status
|
export let status: Status
|
||||||
|
|
||||||
let statusText: string = "Unknown";
|
|
||||||
let statusIcon: IconName = "question";
|
|
||||||
|
|
||||||
$: switch (status) {
|
|
||||||
case 0:
|
|
||||||
statusIcon = "hourglass";
|
|
||||||
statusText = "Blocked";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
statusIcon = "lightbulb";
|
|
||||||
statusText = "Available";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
statusIcon = "calendar";
|
|
||||||
statusText = "Background";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
statusIcon = "spinner";
|
|
||||||
statusText = "Active";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
statusIcon = "check";
|
|
||||||
statusText = "Completed";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
statusIcon = "times";
|
|
||||||
statusText = "Failed";
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
statusIcon = "times";
|
|
||||||
statusText = "Dropped";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="entry-status">
|
<div class="entry-status">
|
||||||
<StatusColor status={status}>
|
<StatusColor status={status}>
|
||||||
<Icon name={statusIcon} />
|
<StatusIcon status={status} />
|
||||||
<span>{statusText}</span>
|
<StatusText status={status} />
|
||||||
</StatusColor>
|
</StatusColor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let subtitle: string = "";
|
||||||
|
export let fullwidth: boolean = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="header-wrapper" class:fullwidth>
|
||||||
|
<h1><slot></slot></h1>
|
||||||
|
<h2>{subtitle}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
div.header-wrapper {
|
||||||
|
&.fullwidth {
|
||||||
|
width: 180ch;
|
||||||
|
max-width: 95%;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0.333em 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-size: 3em;
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 1em 0;
|
||||||
|
margin-top: 0;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100;
|
||||||
|
|
||||||
|
&:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -38,6 +38,8 @@
|
|||||||
import { faThumbtack } from "@fortawesome/free-solid-svg-icons/faThumbtack";
|
import { faThumbtack } from "@fortawesome/free-solid-svg-icons/faThumbtack";
|
||||||
import { faHistory } from "@fortawesome/free-solid-svg-icons/faHistory";
|
import { faHistory } from "@fortawesome/free-solid-svg-icons/faHistory";
|
||||||
import { faLightbulb } from "@fortawesome/free-solid-svg-icons/faLightbulb";
|
import { faLightbulb } from "@fortawesome/free-solid-svg-icons/faLightbulb";
|
||||||
|
import { faChevronRight } from "@fortawesome/free-solid-svg-icons/faChevronRight";
|
||||||
|
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
"clock": faClock,
|
"clock": faClock,
|
||||||
@@ -58,6 +60,8 @@
|
|||||||
"calendar": faCalendar,
|
"calendar": faCalendar,
|
||||||
"expand": faExpand,
|
"expand": faExpand,
|
||||||
"search": faSearch,
|
"search": faSearch,
|
||||||
|
"chevron_right": faChevronRight,
|
||||||
|
"chevron_down": faChevronDown,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IconName = keyof typeof icons;
|
export type IconName = keyof typeof icons;
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type Status from "$lib/models/status";
|
||||||
|
import type { IconName } from "./Icon.svelte";
|
||||||
|
import Icon from "./Icon.svelte";
|
||||||
|
import StatusColor from "./StatusColor.svelte";
|
||||||
|
import StatusIcon from "./StatusIcon.svelte";
|
||||||
|
import StatusText from "./StatusText.svelte";
|
||||||
|
|
||||||
|
export let status: Status | null = null;
|
||||||
|
export let expanded: boolean | null = null;
|
||||||
|
export let title: string = "";
|
||||||
|
|
||||||
|
let expandIcon: IconName;
|
||||||
|
|
||||||
|
function onClick() {
|
||||||
|
if (expanded !== null) {
|
||||||
|
expanded = !expanded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: expandIcon = expanded ? "chevron_down" : "chevron_right";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="category">
|
||||||
|
<div on:click={onClick} class="category-header">
|
||||||
|
{#if expanded !== null}
|
||||||
|
<Icon name={expandIcon} />
|
||||||
|
{/if}
|
||||||
|
{#if status !== null}
|
||||||
|
<StatusColor status={status}>
|
||||||
|
<StatusIcon status={status} />
|
||||||
|
<StatusText status={status} />
|
||||||
|
</StatusColor>
|
||||||
|
{:else}
|
||||||
|
<span>{title}</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if expanded !== false}
|
||||||
|
<div class="category-body">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../colors.sass";
|
||||||
|
|
||||||
|
div.category {
|
||||||
|
border-left: 3px solid $color-entry1;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.category-body {
|
||||||
|
margin-top: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.category-header {
|
||||||
|
padding-left: 0.5ch;
|
||||||
|
font-weight: 600;
|
||||||
|
user-select: none;
|
||||||
|
opacity: $opacity-entry4;
|
||||||
|
|
||||||
|
:global(.icon) {
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { page } from "$app/stores";
|
||||||
|
|
||||||
|
export let href: string = "";
|
||||||
|
export let subtitle: string = "";
|
||||||
|
|
||||||
|
let selected: boolean;
|
||||||
|
$: selected = $page.url.pathname === href;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if !!href}
|
||||||
|
<a href={href}>
|
||||||
|
<div on:click class="menu-item" class:selected>
|
||||||
|
<div class="subtitle">{subtitle}</div>
|
||||||
|
<div><slot></slot></div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<div on:click class="menu-item" class:selected>
|
||||||
|
<div class="subtitle">{subtitle}</div>
|
||||||
|
<div><slot></slot></div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../colors.sass";
|
||||||
|
|
||||||
|
div.menu-item {
|
||||||
|
color: $color-entry9;
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding: 0.15em 0;
|
||||||
|
padding-left: 0.5ch;
|
||||||
|
|
||||||
|
transition: 0.25s;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
color: $color-entry13;
|
||||||
|
background-color: $color-entry0-transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
> div {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div.subtitle {
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.subtitle {
|
||||||
|
color: $color-entry5;
|
||||||
|
|
||||||
|
&:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-entry13;
|
||||||
|
background-color: $color-entry1-transparent;
|
||||||
|
|
||||||
|
div.subtitle {
|
||||||
|
color: $color-entry8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type Status from "$lib/models/status";
|
||||||
|
import Icon, { type IconName } from "./Icon.svelte";
|
||||||
|
|
||||||
|
export let status: Status;
|
||||||
|
export let block: boolean = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Icon block={block} name={STATUS_ICONS[status]} />
|
||||||
|
|
||||||
|
<script lang="ts" context="module">
|
||||||
|
const STATUS_ICONS: Record<Status, IconName> = {
|
||||||
|
0: "hourglass",
|
||||||
|
1: "lightbulb",
|
||||||
|
2: "calendar",
|
||||||
|
3: "spinner",
|
||||||
|
4: "check",
|
||||||
|
5: "times",
|
||||||
|
6: "times",
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type Status from "$lib/models/status";
|
||||||
|
|
||||||
|
export let status: Status;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span>{STATUS_NAMES[status]}</span>
|
||||||
|
|
||||||
|
<script lang="ts" context="module">
|
||||||
|
const STATUS_NAMES: Record<Status, string> = {
|
||||||
|
0: "Blocked",
|
||||||
|
1: "Available",
|
||||||
|
2: "Background",
|
||||||
|
3: "Active",
|
||||||
|
4: "Completed",
|
||||||
|
5: "Failed",
|
||||||
|
6: "Dropped",
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import type { Database } from "./database/interfaces";
|
||||||
|
import MysqlDB from "./database/mysql/database";
|
||||||
|
|
||||||
|
let databasePromise: Promise<Database> | null = null;
|
||||||
|
let databaseTime: number = 0;
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
database() {
|
||||||
|
if (databasePromise == null || Date.now() < (databaseTime - 60000)) {
|
||||||
|
databasePromise = MysqlDB.connectEnv();
|
||||||
|
databaseTime = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
return databasePromise;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import type { ScopeEntry, ScopeInput } from "$lib/models/scope";
|
||||||
|
import type Scope from "$lib/models/scope";
|
||||||
|
import type { StatEntry } from "$lib/models/stat";
|
||||||
|
import type Stat from "$lib/models/stat";
|
||||||
|
|
||||||
|
export interface Database {
|
||||||
|
userId: string
|
||||||
|
|
||||||
|
scopes(): ScopeRepo
|
||||||
|
stats(scopeId: number): StatRepo
|
||||||
|
withUser(userId: string): Database
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScopeRepo {
|
||||||
|
userId: string
|
||||||
|
|
||||||
|
find(id: number): Promise<Scope>
|
||||||
|
list(): Promise<ScopeEntry[]>
|
||||||
|
create(input: ScopeInput): Promise<Scope>
|
||||||
|
update(id: number, input: Partial<ScopeInput>): Promise<Scope>
|
||||||
|
delete(id: number): Promise<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StatRepo {
|
||||||
|
userId: string
|
||||||
|
scopeId: number
|
||||||
|
|
||||||
|
find(id: number): Promise<Stat>
|
||||||
|
findEntries(...ids: number[]): Promise<StatEntry[]>
|
||||||
|
list(): Promise<Stat[]>
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import {createPool} from "mysql2/promise"
|
||||||
|
import type {Pool} from "mysql2/promise";
|
||||||
|
|
||||||
|
import type { Database, ScopeRepo, StatRepo } from "../interfaces";
|
||||||
|
import MysqlDBScopes from "./scopes";
|
||||||
|
|
||||||
|
|
||||||
|
export default class MysqlDB implements Database {
|
||||||
|
connection: Pool
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
private constructor(userId: string, connection: Connection) {
|
||||||
|
this.userId = userId;
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
scopes(): ScopeRepo {
|
||||||
|
return new MysqlDBScopes(this.connection, this.userId);
|
||||||
|
}
|
||||||
|
stats(scopeId: number): StatRepo {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
withUser(userId: string): Database {
|
||||||
|
return new MysqlDB(userId, this.connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async connectEnv(): Promise<MysqlDB> {
|
||||||
|
return this.connect(
|
||||||
|
process.env.STUFFLOG3_MYSQL_HOST,
|
||||||
|
parseInt(process.env.STUFFLOG3_MYSQL_PORT),
|
||||||
|
process.env.STUFFLOG3_MYSQL_USERNAME,
|
||||||
|
process.env.STUFFLOG3_MYSQL_PASSWORD,
|
||||||
|
process.env.STUFFLOG3_MYSQL_SCHEMA,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async connect(host: string, port: number, user: string, password: string, database: string): Promise<MysqlDB> {
|
||||||
|
const connection = await createPool({
|
||||||
|
host, user, database, password, port,
|
||||||
|
waitForConnections: true,
|
||||||
|
connectionLimit: 20,
|
||||||
|
queueLimit: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
return new MysqlDB("", connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import type {Pool} from "mysql2/promise";
|
||||||
|
|
||||||
|
import type scope from "$lib/models/scope";
|
||||||
|
import type { ScopeEntry, ScopeInput } from "$lib/models/scope";
|
||||||
|
import type { ScopeRepo } from "../interfaces";
|
||||||
|
|
||||||
|
export default class MysqlDBScopes implements ScopeRepo {
|
||||||
|
userId: string;
|
||||||
|
connection: Pool;
|
||||||
|
|
||||||
|
constructor(connection: Pool, userId: string) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
find(id: number): Promise<scope> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
async list(): Promise<ScopeEntry[]> {
|
||||||
|
const [rows] = await this.connection.execute(`
|
||||||
|
SELECT scope.*, scope_member.name as display_name
|
||||||
|
FROM scope
|
||||||
|
INNER JOIN scope_member ON id = scope_id
|
||||||
|
WHERE user_id = ?
|
||||||
|
`, [this.userId]);
|
||||||
|
|
||||||
|
return (rows as any[]).map(r => ({
|
||||||
|
id: r.id,
|
||||||
|
name: r.name,
|
||||||
|
abbreviation: r.abbreviation,
|
||||||
|
displayName: r.display_name,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
create(input: ScopeInput): Promise<scope> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
update(id: number, input: Partial<ScopeInput>): Promise<scope> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
delete(id: number): Promise<void> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,4 +10,16 @@ export interface ScopeEntry {
|
|||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
abbreviation: string
|
abbreviation: string
|
||||||
|
displayName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScopeInput {
|
||||||
|
name: string
|
||||||
|
abbreviation: string
|
||||||
|
displayName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScopeMember {
|
||||||
|
name: string
|
||||||
|
owner: boolean
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,22 @@ enum Status {
|
|||||||
Dropped = 6,
|
Dropped = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LabeledStatus {
|
||||||
|
value: Status
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const allStatuses: LabeledStatus[] = [
|
||||||
|
{value: Status.Active, name: "Active"},
|
||||||
|
{value: Status.Background, name: "Background"},
|
||||||
|
{value: Status.Available, name: "Available"},
|
||||||
|
{value: Status.Blocked, name: "Blocked"},
|
||||||
|
{value: Status.Completed, name: "Completed"},
|
||||||
|
{value: Status.Failed, name: "Failed"},
|
||||||
|
{value: Status.Dropped, name: "Dropped"},
|
||||||
|
];
|
||||||
|
|
||||||
// Blocked -> Available -> Active -> Completed
|
// Blocked -> Available -> Active -> Completed
|
||||||
// -> Failed
|
// -> Failed
|
||||||
// -> Dropped
|
// -> Dropped
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export default interface User {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ export const get: RequestHandler = async({params}) => {
|
|||||||
|
|
||||||
const scopes: Scope[] = [
|
const scopes: Scope[] = [
|
||||||
{
|
{
|
||||||
id: 1, name: "3D Modeling", abbreviation: "3D",
|
id: 1, name: "3D Modeling", abbreviation: "3D", displayName: "Test",
|
||||||
stats: [
|
stats: [
|
||||||
{id: 101, name: "Asset", weight: 0.1, description: "Some description"},
|
{id: 101, name: "Asset", weight: 0.1, description: "Some description"},
|
||||||
{id: 102, name: "Tweak", weight: 0.2, description: "Some description"},
|
{id: 102, name: "Tweak", weight: 0.2, description: "Some description"},
|
||||||
@@ -55,7 +55,7 @@ const scopes: Scope[] = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2, name: "Roleplay", abbreviation: "RP",
|
id: 2, name: "Roleplay", abbreviation: "RP", displayName: "Test",
|
||||||
stats: [
|
stats: [
|
||||||
{id: 201, name: "Story", weight: 3, description: "Some description"},
|
{id: 201, name: "Story", weight: 3, description: "Some description"},
|
||||||
{id: 202, name: "Story Word", weight: 0.002, description: "Some description"},
|
{id: 202, name: "Story Word", weight: 0.002, description: "Some description"},
|
||||||
@@ -67,9 +67,14 @@ const scopes: Scope[] = [
|
|||||||
{id: 208, name: "Wiki Complexity", weight: 0.5, description: "Some description"},
|
{id: 208, name: "Wiki Complexity", weight: 0.5, description: "Some description"},
|
||||||
],
|
],
|
||||||
activeProjects: [
|
activeProjects: [
|
||||||
{id: 2001, name: "Ilyna T'Rea", status: Status.Active},
|
{id: 2001, name: "Ilyna: The Morning After", status: Status.Active},
|
||||||
{id: 2002, name: "Renala T'Iavay", status: Status.Active},
|
{id: 2002, name: "Renala: Finding Her Voice", status: Status.Active},
|
||||||
{id: 2003, name: "Background Stories", status: Status.Background},
|
{id: 2003, name: "General Stories", status: Status.Background},
|
||||||
|
{id: 2004, name: "Uvena: Finish Wiki Page", status: Status.Active},
|
||||||
|
{id: 2005, name: "Va'ynna: Cracking at the Seams", status: Status.Active},
|
||||||
|
{id: 2006, name: "Witch Hunt: Sala's Backlog", status: Status.Active},
|
||||||
|
{id: 2007, name: "Ilyna: Complete Wiki Page", status: Status.Completed},
|
||||||
|
{id: 2008, name: "Renala: Complete Wiki Page", status: Status.Active},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
//{id: 3, name: "Minecraft", abbreviation: "MC"},
|
//{id: 3, name: "Minecraft", abbreviation: "MC"},
|
||||||
|
|||||||
@@ -19,14 +19,92 @@
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const STATUS_ORDER = [
|
||||||
|
Status.Active,
|
||||||
|
Status.Background,
|
||||||
|
Status.Available,
|
||||||
|
Status.Blocked,
|
||||||
|
Status.Completed,
|
||||||
|
Status.Failed,
|
||||||
|
Status.Dropped,
|
||||||
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type Scope from "$lib/models/scope";
|
import type Scope from "$lib/models/scope";
|
||||||
|
import Header from "$lib/components/layout/Header.svelte";
|
||||||
|
import Status from "$lib/models/status";
|
||||||
|
import MenuCategory from "$lib/components/layout/MenuCategory.svelte";
|
||||||
|
import type { ProjectEntry } from "$lib/models/project";
|
||||||
|
import MenuItem from "$lib/components/layout/MenuItem.svelte";
|
||||||
|
|
||||||
export let scope: Scope;
|
export let scope: Scope;
|
||||||
|
|
||||||
|
let projects = scope.activeProjects;
|
||||||
|
let projectsByStatus: Record<Status, ProjectEntry[]>;
|
||||||
|
|
||||||
|
$: projectsByStatus = projects.reduce((p, c) => ({...p, [c.status]: [...p[c.status], c]}), {
|
||||||
|
0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [],
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>{scope.name}</h1>
|
<div class="scope-layout">
|
||||||
|
<div class="column main">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
<div class="column side">
|
||||||
|
<Header subtitle={scope.name}>{scope.abbreviation}</Header>
|
||||||
|
<MenuCategory title="Scope">
|
||||||
|
<MenuItem href="/{scope.id}">Overview</MenuItem>
|
||||||
|
<MenuItem href="/{scope.id}/history">History</MenuItem>
|
||||||
|
</MenuCategory>
|
||||||
|
{#each STATUS_ORDER as status (status)}
|
||||||
|
{#if projectsByStatus[status].length > 0}
|
||||||
|
<MenuCategory status={status}>
|
||||||
|
{#each projectsByStatus[status] as project (project.id)}
|
||||||
|
<MenuItem href="/{scope.id}/project/{project.id}" subtitle={
|
||||||
|
project.name.includes(": ") ? project.name.split(": ")[0] + ": " : ""
|
||||||
|
}>{
|
||||||
|
project.name.includes(": ") ? project.name.split(": ").slice(1).join(": ") : project.name
|
||||||
|
}</MenuItem>
|
||||||
|
{/each}
|
||||||
|
</MenuCategory>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
div.scope-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
flex-basis: 100%;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
width: 90ch;
|
||||||
|
max-width: 95%;
|
||||||
|
margin: auto;
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 5;
|
||||||
|
|
||||||
|
&.side {
|
||||||
|
flex: 2;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 1em;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import type { Load, LoadInput } from "@sveltejs/kit/types/internal";
|
import type { Load } from "@sveltejs/kit/types/internal";
|
||||||
|
|
||||||
export const load: Load = async({ stuff }) => {
|
export const load: Load = async({ stuff }) => {
|
||||||
return {
|
return {
|
||||||
@@ -18,3 +18,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>{$page.stuff.scope.name}</h1>
|
<h1>{$page.stuff.scope.name}</h1>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<script>
|
||||||
|
import { page } from "$app/stores";
|
||||||
|
import Backgrond from "$lib/components/layout/Backgrond.svelte";
|
||||||
|
|
||||||
|
let opacity = 0.175;
|
||||||
|
|
||||||
|
$: opacity = $page.url.pathname === "/" ? 0.3 : 0.2;
|
||||||
|
</script>
|
||||||
|
<Backgrond initialOrientation="landscape" opacity={opacity} />
|
||||||
|
<slot></slot>
|
||||||
+2
-28
@@ -17,7 +17,6 @@
|
|||||||
error: `Failed: ${res.status}`
|
error: `Failed: ${res.status}`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -29,17 +28,14 @@
|
|||||||
import type { StandaloneRequirement } from "$lib/models/project";
|
import type { StandaloneRequirement } from "$lib/models/project";
|
||||||
import type { StandaloneSprint } from "$lib/models/sprint";
|
import type { StandaloneSprint } from "$lib/models/sprint";
|
||||||
import SprintLink from "$lib/components/frontpage/SprintLink.svelte";
|
import SprintLink from "$lib/components/frontpage/SprintLink.svelte";
|
||||||
|
import Header from "$lib/components/layout/Header.svelte";
|
||||||
export let scopes: ScopeEntry[] = [];
|
export let scopes: ScopeEntry[] = [];
|
||||||
export let items: StandaloneItem[] = [];
|
export let items: StandaloneItem[] = [];
|
||||||
export let requirements: StandaloneRequirement[] = [];
|
export let requirements: StandaloneRequirement[] = [];
|
||||||
export let sprints: StandaloneSprint[] = [];
|
export let sprints: StandaloneSprint[] = [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="header-wrapper">
|
<Header fullwidth subtitle="Logging your stuff">Stufflog</Header>
|
||||||
<h1>Stufflog</h1>
|
|
||||||
<h2>Logging your stuff.</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
@@ -76,28 +72,6 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
div.header-wrapper {
|
|
||||||
width: 180ch;
|
|
||||||
max-width: 95%;
|
|
||||||
margin: auto;
|
|
||||||
margin-top: 2em;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin: 0.333em 0.333ch;
|
|
||||||
margin-bottom: 0;
|
|
||||||
font-size: 3em;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 1em;
|
|
||||||
margin: 1em 1ch;
|
|
||||||
margin-top: 0;
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 0.25em;
|
margin-top: 0.25em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ import type { ScopeEntry } from "$lib/models/scope"
|
|||||||
import Status from "$lib/models/status"
|
import Status from "$lib/models/status"
|
||||||
import type { StandaloneSprint } from "$lib/models/sprint"
|
import type { StandaloneSprint } from "$lib/models/sprint"
|
||||||
|
|
||||||
export const get: RequestHandler = async({}) => {
|
export const get: RequestHandler = async({locals}) => {
|
||||||
const scopes: ScopeEntry[] = [
|
const scopes: ScopeEntry[] = locals.scopes;
|
||||||
{id: 1, name: "3D Modeling", abbreviation: "3D"},
|
|
||||||
{id: 2, name: "Roleplay", abbreviation: "RP"},
|
|
||||||
{id: 3, name: "Minecraft", abbreviation: "MC"},
|
|
||||||
{id: 4, name: "Coding", abbreviation: "CODE"},
|
|
||||||
{id: 5, name: "System Administration", abbreviation: "SA"},
|
|
||||||
]
|
|
||||||
|
|
||||||
const items: StandaloneItem[] = [
|
const items: StandaloneItem[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 495 KiB |
Reference in New Issue
Block a user