diff --git a/express.js b/express.js
index 0d9a69897e..684236d357 100644
--- a/express.js
+++ b/express.js
@@ -1,11 +1,65 @@
+/**
+@module express.js
+@description
+
+# Express.js 🚅
+
+[Express](https://expressjs.com) is a minimal and flexible Node.js web application framework that provides a robust
+set of features for web and mobile applications.
+
+Our implementation provides the following endpoints and features:
+
+- SAML authentication endpoints for Single Sign-On
+- Rate-limited API endpoints for provider interactions
+- Static file serving for documentation
+- Security enhancements including header protection
+
+The server implements the following core features:
+
+- Rate limiting: 1000 requests per 1 min per IP
+- Cookie parsing for session management
+- JSON body parsing with 5MB limit for POST requests
+- Static file serving with HTML extension support
+
+## Security 🔐
+
+- X-Powered-By header disabled
+- Rate limiting enabled
+- SAML authentication required for protected routes
+
+## env
+
+```env
+PORT - Server port (default: 3000)
+DIR - Base directory for routes
+RATE_LIMIT - Maximum requests per window (default: 1000)
+RATE_LIMIT_WINDOW - Time window in ms (default: 1 min)
+```
+@requires dotenv - Environment configuration loading
+@requires express - Web application framework
+@requires cookie-parser - HTTP cookie parsing middleware
+@requires express-rate-limit - Rate limiting middleware
+*/
+
require('dotenv').config();
const express = require('express');
-
const cookieParser = require('cookie-parser');
+const rateLimit = require('express-rate-limit');
const app = express();
+app.disable('x-powered-by');
+
+const limiter = rateLimit({
+ windowMs: process.env.RATE_LIMIT_WINDOW ?? 1 * 60 * 1000, // 1 min
+ limit: process.env.RATE_LIMIT ?? 1000, //1000 requests per 1min
+ standardHeaders: 'draft-8',
+ legacyHeaders: false,
+});
+
+app.use(limiter);
+
app.use(
'/xyz',
express.static('docs', {
@@ -33,7 +87,13 @@ app.post(
api,
);
-app.get(`${process.env.DIR || ''}/api/sign/:signer?`, api);
+app.get(`${process.env.DIR || ''}/api/sign/:provider?`, api);
+
+app.post(
+ `${process.env.DIR || ''}/api/sign/:provider?`,
+ express.json({ limit: '5mb' }),
+ api,
+);
app.get(`${process.env.DIR || ''}/api/query/:template?`, api);
@@ -73,12 +133,6 @@ app.post(
api,
);
-app.post(
- `${process.env.DIR || ''}/saml/logout/callback`,
- express.urlencoded({ extended: true }),
- api,
-);
-
app.get(`${process.env.DIR || ''}/view/:template?`, api);
app.get(`${process.env.DIR || ''}/:locale?`, api);
diff --git a/jsdoc_xyz.json b/jsdoc_xyz.json
index acb3318b67..b6c07a902d 100644
--- a/jsdoc_xyz.json
+++ b/jsdoc_xyz.json
@@ -1,14 +1,9 @@
{
"source": {
- "include": [
- "api",
- "mod"
- ],
+ "include": ["api", "mod", "express.js"],
"includePattern": ".js$"
},
- "plugins": [
- "plugins/markdown"
- ],
+ "plugins": ["plugins/markdown"],
"opts": {
"encoding": "utf8",
"readme": "./api/README.md",
@@ -19,9 +14,7 @@
"theme_opts": {
"title": "XYZ",
"homepageTitle": "XYZ",
- "static_dir": [
- "./public/icons"
- ],
+ "static_dir": ["./public/icons"],
"favicon": "./public/icons/favicon.ico",
"menu": [
{
@@ -41,4 +34,4 @@
"hardwrap": false,
"idInHeadings": true
}
-}
\ No newline at end of file
+}
diff --git a/lib/dictionaries/en.mjs b/lib/dictionaries/en.mjs
index e0b46c2046..d3df56acce 100644
--- a/lib/dictionaries/en.mjs
+++ b/lib/dictionaries/en.mjs
@@ -97,4 +97,10 @@ export default {
locations: 'Locations',
no_locales: 'Your account has been verified and approved, but you do not have access to any locales. This is likely as an administrator has not given you the required roles. Please contact an administrator to resolve this.',
no_layers: 'No accessible layers in locale.',
+ csv_upload_import: 'Import From CSV',
+ csv_upload_success: 'Data imported successfully',
+ csv_upload_failed: 'Data import failed, please try again.',
+ csv_upload_number_of_columns_imported: 'The number of columns in your imported file',
+ csv_upload_number_of_columns_required: 'is not the same as the number of columns required',
+ csv_upload_rows_imported: 'Rows Imported',
};
\ No newline at end of file
diff --git a/lib/ui/Dataview.mjs b/lib/ui/Dataview.mjs
index 47b876e61d..979b42e6f4 100644
--- a/lib/ui/Dataview.mjs
+++ b/lib/ui/Dataview.mjs
@@ -154,7 +154,7 @@ function show() {
}
//Show toolbar buttons if there are any
- this.btnRow?.style.setProperty('display','block')
+ this.btnRow?.style.setProperty('display','flex')
this.target.style.display = 'block'
}
diff --git a/lib/ui/Tabview.mjs b/lib/ui/Tabview.mjs
index 38cf0905c2..f7760c2c62 100644
--- a/lib/ui/Tabview.mjs
+++ b/lib/ui/Tabview.mjs
@@ -153,7 +153,7 @@ function addTab(entry) {
}
//Show toolbar buttons if there are any
- entry.btnRow?.style.setProperty('display', 'block')
+ entry.btnRow?.style.setProperty('display', 'flex')
}
/**
diff --git a/lib/ui/utils/jsonDataview.mjs b/lib/ui/utils/jsonDataview.mjs
index 9460f037dd..10cc063b50 100644
--- a/lib/ui/utils/jsonDataview.mjs
+++ b/lib/ui/utils/jsonDataview.mjs
@@ -11,7 +11,8 @@ The jsonDataview module exports as default an object with a create method for JS
export default {
create,
toolbar: {
- jsonfile
+ jsonfile,
+ csvupload
}
}
@@ -76,3 +77,27 @@ function jsonfile(dataview) {
return button;
}
+
+function csvupload(dataview) {
+
+ dataview.toolbar.csvupload.label ??= 'CSV Upload'
+
+ dataview.toolbar.csvupload.input = mapp.utils.html.node` {
+
+ if (!e.target.files[0]) return;
+
+ dataview.toolbar.csvupload.file = e.target.files[0]
+
+ const uploaded = await mapp.utils.csvUpload(
+ dataview.toolbar.csvupload.file,
+ dataview.toolbar.csvupload
+ );
+
+ dataview.setData(uploaded)
+ }}>`
+
+ return dataview.toolbar.csvupload.input;
+}
diff --git a/lib/utils/_utils.mjs b/lib/utils/_utils.mjs
index 03081ae7b3..95851fcb76 100644
--- a/lib/utils/_utils.mjs
+++ b/lib/utils/_utils.mjs
@@ -18,6 +18,8 @@ const areSetsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(
import csvDownload from './csvDownload.mjs'
+import csvUpload from './csvUpload.mjs'
+
import compose from './compose.mjs'
import convert from './convert.mjs'
@@ -82,6 +84,7 @@ export default {
compose,
copyToClipboard,
csvDownload,
+ csvUpload,
dataURLtoBlob,
formatNumericValue,
unformatStringValue,
diff --git a/lib/utils/csvUpload.mjs b/lib/utils/csvUpload.mjs
new file mode 100644
index 0000000000..00c69f91e9
--- /dev/null
+++ b/lib/utils/csvUpload.mjs
@@ -0,0 +1,200 @@
+/**
+## /utils/csvUpload
+
+This module exports the default csvUpload method for mapp utils module.
+
+@module /utils/csvUpload
+*/
+
+// Define schema methods.
+const schemaMethods = {
+ // eslint-disable-next-line quotes
+ Text: (val) => `'${val.replace(/'/g, "''")}'`,
+ Integer: (val) => parseInt(val.replace(/[^\d.-]/g, '')) || 'NULL',
+ Float: (val) => parseFloat(val.replace(/[^\d.-]/g, '')) || 'NULL',
+};
+
+/**
+@function csvUpload
+@async
+
+@description
+This function uploads a CSV file to a database store.
+
+@param {File} file The CSV file to upload.
+@param {Object} params The parameters object.
+@property {String} params.query The query to upload the data.
+@property {Boolean} [params.async] If set to true, the data is uploaded asynchronously. Default is false.
+@property {Boolean} [params.header] If set to true, the first row is treated as a header row and not uploaded.
+
+@returns {} The outcome object and any messages returned by the database.
+*/
+export default async function csvUpload(file, params = {}) {
+ if (!params.query) {
+ console.warn(`Query required`);
+ return;
+ }
+
+ return new Promise((resolve) => {
+ const reader = new FileReader();
+
+ reader.readAsText(file);
+
+ reader.onload = async (e) => {
+ // Split text file into rows on carriage return / new line.
+ const rows = e.target.result.trim().split(/\r?\n/);
+
+ // The file has a header row.
+ if (params.header) {
+ const headerRow = rows.shift();
+
+ params.fields ??= headerRow.replaceAll('"', '').split(',');
+ }
+
+ const chunks = chunkRows(rows, params);
+
+ let responses = [];
+
+ // If async = true, then we need to wait for all promises to resolve before returning the outcome object.
+ if (params.async) {
+ responses = await Promise.all(
+ chunks.map((chunk) => postRequestData(chunk, params)),
+ );
+ }
+
+ // If async = false, run them synchhronously.
+ else {
+ for (const chunk of chunks) {
+ const response = await postRequestData(chunk, params);
+ responses.push(response);
+ }
+ }
+
+ resolve(responses);
+ };
+ });
+}
+
+/**
+@function chunkRows
+@description
+The method iterates over each row in the rows param. And returns an array of chunks according to max payload size for the POST request.
+
+@param {array} rows An array of rows extracted from the CSV file.
+@param {object} params Parameter for chunking the rows array.
+@property {Number} [params.chunkSize] The chunk size in bytes to upload the data in. Defaults to 4MB.
+@property {Array} [params.schema] The schema array of column types.
+@returns {Array} An array of field arrays chunked to size.
+*/
+function chunkRows(rows, params) {
+ const chunks = [];
+
+ // Set default chunksize in bytes.
+ params.chunkSize ??= 4000000;
+ let chunkSize = 0;
+ let chunk = [];
+
+ rows.forEach((row) => {
+
+ // Split row into fields array.
+ const fields = splitRowIntoFields(row);
+
+ // Create row string for values from by passing field value to schema method.
+ const fieldsRow = `(${fields.map((fieldValue, i) => {
+
+ const schemaType = params.schema?.[i] || 'Text';
+ return schemaMethods[schemaType](fieldValue);
+ }).join()})`;
+
+ // Determine blob size in bytes for the row.
+ const rowSize = new Blob([fieldsRow]).size;
+
+ // Check whether the chunk would exceed lambda payload limit.
+ if (chunkSize + rowSize >= params.chunkSize) {
+ chunks.push(structuredClone(chunk));
+
+ // Create a new current chunk.
+ chunk = [];
+ chunkSize = 0;
+ }
+
+ // Add row to current chunk and sum size.
+ chunkSize += rowSize;
+ chunk.push(fieldsRow);
+ });
+
+ // Push the last chunk if it exists.
+ if (chunk.length) chunks.push(chunk);
+
+ return chunks;
+}
+
+/**
+@function splitRowIntoFields
+@description
+The method splits a CSV row string into fields.
+
+@param {String} row The row to split.
+@returns {Array} The fields array.
+*/
+function splitRowIntoFields(row) {
+ // Create an array to store the fields.
+ const fields = [];
+
+ // Create a variable to store the current field.
+ let currentField = '';
+
+ let insideQuotes = false;
+
+ // Loop through each character in the row.
+ for (const character of row) {
+ // This if statement checks if the character is a double quote.
+ if (character === '"') {
+ // If the character is a double quote, we toggle the insideQuotes variable, which will be used to determine if we are inside a quote.
+ insideQuotes = !insideQuotes;
+ }
+ // If the character is a comma and we are not inside quotes, we push the current field to the fields array.
+ else if (character === ',' && !insideQuotes) {
+ // Push current field to fields array
+ fields.push(currentField.trim());
+
+ // Reset for the next field
+ currentField = '';
+ } else {
+ // Add character to current field
+ currentField += character;
+ }
+ }
+
+ // Push the last field (if any) after the loop to the fields array.
+ if (currentField) {
+ fields.push(currentField.trim());
+ }
+
+ return fields;
+}
+
+/**
+@function postRequestData
+@description
+The method returns a parameterised query object from the XHR utility method.
+
+@param {Array} data Data for the post request body.
+@param {Object} params Parameters for the post query.
+@returns {} Returns promise from XHR query utility.
+*/
+function postRequestData(data, params) {
+ params.queryparams ??= {};
+
+ const queryParams = mapp.utils.queryParams(params);
+
+ const paramString = mapp.utils.paramString(queryParams);
+
+ const url = `${mapp.host}/api/query?${paramString}`;
+
+ return mapp.utils.xhr({
+ method: 'POST',
+ url,
+ body: JSON.stringify({ data }),
+ });
+}
diff --git a/package.json b/package.json
index 360481546f..8e5de13a17 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"eslint": "^9.13.0",
"express": "^4.18.3",
"nodemon": "^3.1.7",
- "uhtml": "^3.1.0"
+ "uhtml": "^3.1.0",
+ "express-rate-limit": "^7.5.0"
}
}
diff --git a/public/css/_button.css b/public/css/_button.css
deleted file mode 100644
index 2209598610..0000000000
--- a/public/css/_button.css
+++ /dev/null
@@ -1,174 +0,0 @@
-
-
-button {
- border: none;
- outline: none;
- background: none;
- text-align: center;
-
- &.mask-icon,
- & >.mask-icon {
- background-color: var(--color-primary)
- }
-
- &.mask-icon.active,
- &.active>.mask-icon,
- & >.mask-icon.active {
- background-color: var(--color-on)
- }
-
- &:hover {
- cursor: pointer;
- }
-
- &:disabled {
- opacity: 0.3;
- &:hover {
- cursor: not-allowed;
- }
- }
-
- &.wide {
- width: 100%;
- }
-
- &.flat {
- border-radius: 3px;
- border-bottom: 1px solid var(--color-light-secondary);
- padding: 0.3em;
-
- &.active {
- border-bottom: 3px solid var(--color-on);
- }
- }
-
- &.underline {
- display: none;
- margin-bottom: 5px;
- text-decoration: underline
- }
-
- &.raised {
- border-radius: 3px;
- border: 1px solid var(--color-light-secondary);
- box-shadow: 1px 1px 2px var(--color-light-secondary);
- padding: 0.3em;
-
- &.active {
- box-shadow: none;
- }
- }
-
- &.active {
- background-color: var(--color-on);
- }
-}
-
-.btn-column {
- display: grid;
- grid-auto-rows: minmax(min-content, 4em);
- padding: 0.7em;
-
- & button,
- & >div,
- & >a {
- width: 2em;
- height: 2em;
- }
-
- & a > div,
- & button > div {
- height: 100%;
- }
-
- & button:disabled,
- & a:disabled {
- cursor: not-allowed;
- }
-}
-
-.btn-row {
- display: flex;
- & > * {
- margin: 10px 5px;
- }
-}
-
-.btn-panel {
- width: 100%;
- padding: 0.3em 0.5em;
- background-color: white;
- border: 1px solid var(--color-light-secondary);
- border-radius: 3px;
- box-shadow: 1px 1px 3px var(--color-primary-light);
-
- & .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- overflow: hidden;
- pointer-events: none;
-
- & h3 {
- text-overflow: ellipsis;
- overflow: hidden;
- }
- }
-
- & .mask-icon {
- width: 1.5em;
- height: 1.5em;
- -webkit-mask-position: right;
- mask-position: right;
- }
-
- & .panel {
- display: block;
- position: absolute;
- width: 100%;
- bottom: 15em;
- left: 0;
- right: 0;
- z-index: 99;
- color: black;
- background: white;
- overflow: hidden;
- padding: 1em 1.5em;
- opacity: 0;
- border-radius: 3px;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- pointer-events: none;
- transition: 0.2s ease-in-out;
-
- & .content {
- padding: 1em;
- }
-
- &::after {
- content: initial;
- }
- }
-
- &.active {
- background-color: var(--color-primary);
- color: #fff;
-
- & .mask-icon {
- background-color: #fff;
- }
-
- & .panel {
- bottom: 2em;
- pointer-events: auto;
- opacity: 1;
- }
-
- &.downward .panel {
- bottom: -7em; /* places adjacent to the bottom border of parent */
- }
- }
-
- &.downward .panel {
- bottom: -15em;
- }
-}
\ No newline at end of file
diff --git a/public/css/_colours.css b/public/css/_colours.css
deleted file mode 100644
index c0a9bbaa17..0000000000
--- a/public/css/_colours.css
+++ /dev/null
@@ -1,23 +0,0 @@
-:root {
-
- --color-off-black: #3f3f3f;
-
- --color-primary: #003D57;
-
- --color-primary-light: #939faa;
-
- --color-light: #ffffff;
-
- --color-light-secondary: #f2f2f2;
-
- --color-light-tertiary: #fafafa;
-
- --color-mid: #e3e3e3;
-
- --color-on: #E18335;
-
- --color-no: #A21309;
-
- --color-changed: #ffffa7;
-
-}
diff --git a/public/css/_dialog.css b/public/css/_dialog.css
deleted file mode 100644
index 6585571517..0000000000
--- a/public/css/_dialog.css
+++ /dev/null
@@ -1,119 +0,0 @@
-.headerDrag {
- cursor: grab;
-}
-
-dialog>button.close {
- position: absolute;
- top: 0em;
- right: 0em;
- height: 1em;
- width: 1em;
- margin: 0.4em;
-}
-
-dialog.dialog {
- position: absolute;
- border: none !important;
- border-radius: 2px;
- cursor: grab;
- user-select: none;
- padding: 5px;
- overflow: unset !important;
- isolation: isolate;
-}
-
-dialog.modal {
- position: fixed;
- border: none !important;
- border-radius: 2px;
- text-wrap: wrap;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- z-index: 9999;
-}
-
-header {
- & button {
- height: 1em;
- width: 1em;
- margin: 0.4em;
- }
-}
-
-.dialog>header {
- display: flex;
- justify-content: space-between;
-
- &>:nth-child(2) {
- margin-left: auto;
- }
-}
-
-dialog.alert-confirm {
- width: 350px;
- max-height: 70%;
- z-index: 1001;
- user-select: none;
-}
-
-dialog.alert-confirm::-webkit-scrollbar {
- display: none;
-}
-
-dialog.alert-confirm:focus {
- outline: none;
-}
-
-dialog.alert-confirm h4 {
- padding: 0.5em 1em;
- background-color: var(--color-primary);
- border-bottom: solid 2px var(--color-primary-light);
- color: var(--color-light)
-}
-
-dialog.alert-confirm .content {
- padding: 1em;
-}
-
-dialog.alert-confirm p {
- white-space: pre;
- text-wrap: pretty;
- text-align: center;
- padding: 1em;
-}
-
-dialog.alert-confirm .buttons {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- grid-gap: 0.2em
-}
-
-dialog.alert-confirm button {
- float: right;
- font-size: 0.9em;
- color: var(--color-primary);
- z-index: 1005;
-}
-
-dialog.minimized .content {
- display: none;
-}
-
-dialog .minimize-btn.mask-icon {
- -webkit-mask-image: url("../icons/icon-remove.svg");
- mask-image: url("../icons/icon-remove.svg");
-}
-
-dialog.minimized .minimize-btn.mask-icon {
- -webkit-mask-image: url("../icons/icon-fullscreen.svg");
- mask-image: url("../icons/icon-fullscreen.svg");
-}
-
-@media only screen and (max-width: 768px) {
-
- dialog.alert-confirm {
- min-width: 350px;
- max-width: 70%;
- }
-}
\ No newline at end of file
diff --git a/public/css/_icons.css b/public/css/_icons.css
deleted file mode 100644
index b16cd75b00..0000000000
--- a/public/css/_icons.css
+++ /dev/null
@@ -1,777 +0,0 @@
-.bg-icon {
- background-repeat: no-repeat;
- background-size: contain;
- -webkit-background-size: contain;
-
- &.pos-center {
- background-position: center;
- }
- &.pos-right {
- background-position: right;
- }
- &.pos-left {
- background-position: left;
- }
-}
-
-.mask-icon {
- mask-repeat: no-repeat;
- -webkit-mask-repeat: no-repeat;
- mask-size: contain;
- -webkit-mask-size: contain;
-
- &.pos-center {
- mask-position: center;
- -webkit-mask-position: center;
- }
- &.pos-right {
- mask-position: right;
- -webkit-mask-position: right;
- }
- &.pos-left {
- mask-position: left;
- -webkit-mask-position: left;
- }
-}
-
-.add {
- &.bg-icon {
- background-image: url("../icons/icon-add.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-add.svg");
- mask-image: url("../icons/icon-add.svg");
- }
-}
-
-.add-chart {
- &.bg-icon {
- background-image: url("../icons/icon-add-chart.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-add-chart.svg");
- mask-image: url("../icons/icon-add-chart.svg");
- }
-}
-
-.add-document {
- &.bg-icon {
- background-image: url("../icons/icon-add-document.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-add-document.svg");
- mask-image: url("../icons/icon-add-document.svg");
- }
-}
-
-.add-photo {
- &.bg-icon {
- background-image: url("../icons/icon-add-photo.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-add-photo.svg");
- mask-image: url("../icons/icon-add-photo.svg");
- }
-}
-
-.area {
- &.bg-icon {
- background-image: url("../icons/icon-area.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-area.svg");
- mask-image: url("../icons/icon-area.svg");
- }
-}
-
-.arrow-down {
- &.bg-icon {
- background-image: url("../icons/icon-arrow-down.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-arrow-down.svg");
- mask-image: url("../icons/icon-arrow-down.svg");
- }
-}
-
-.arrow-up {
- &.bg-icon {
- background-image: url("../icons/icon-arrow-up.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-arrow-up.svg");
- mask-image: url("../icons/icon-arrow-up.svg");
- }
-}
-
-.bar-chart {
- &.bg-icon {
- background-image: url("../icons/icon-bar-chart.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-bar-chart.svg");
- mask-image: url("../icons/icon-bar-chart.svg");
- }
-}
-
-.bubble-chart {
- &.bg-icon {
- background-image: url("../icons/icon-bubble-chart.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-bubble-chart.svg");
- mask-image: url("../icons/icon-bubble-chart.svg");
- }
-}
-
-.bug-report {
- &.bg-icon {
- background-image: url("../icons/icon-bug-report.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-bug-report.svg");
- mask-image: url("../icons/icon-bug-report.svg");
- }
-}
-
-.build {
- &.bg-icon {
- background-image: url("../icons/icon-build.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-build.svg");
- mask-image: url("../icons/icon-build.svg");
- }
-}
-
-.car {
- &.bg-icon {
- background-image: url("../icons/icon-car.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-car.svg");
- mask-image: url("../icons/icon-car.svg");
- }
-}
-
-.circle-dot {
- &.bg-icon {
- background-image: url("../icons/icon-circle-dot.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-circle-dot.svg");
- mask-image: url("../icons/icon-circle-dot.svg");
- }
-}
-
-.city {
- &.bg-icon {
- background-image: url("../icons/icon-city.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-city.svg");
- mask-image: url("../icons/icon-city.svg");
- }
-}
-
-.copy {
- &.bg-icon {
- background-image: url("../icons/icon-copy.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-copy.svg");
- mask-image: url("../icons/icon-copy.svg");
- }
-}
-
-.close {
- &.bg-icon {
- background-image: url("../icons/icon-close.svg");
-
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-close.svg");
- mask-image: url("../icons/icon-close.svg");
- }
-}
-
-.cloud-upload {
- &.bg-icon {
- background-image: url("../icons/icon-cloud-upload.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-cloud-upload.svg");
- mask-image: url("../icons/icon-cloud-upload.svg");
- }
-}
-
-.description {
- &.bg-icon {
- background-image: url("../icons/icon-description.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-description.svg");
- mask-image: url("../icons/icon-description.svg");
- }
-}
-
-.done {
- &.bg-icon {
- background-image: url("../icons/icon-done.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-done.svg");
- mask-image: url("../icons/icon-done.svg");
- }
-}
-
-.donut-small {
- &.bg-icon {
- background-image: url("../icons/icon-donut-small.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-donut-small.svg");
- mask-image: url("../icons/icon-donut-small.svg");
- }
-}
-
-.drop-down {
- &.bg-icon {
- background-image: url("../icons/icon-drop-down.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-drop-down.svg");
- mask-image: url("../icons/icon-drop-down.svg");
- }
-}
-
-.drop-up {
- &.bg-icon {
- background-image: url("../icons/icon-drop-up.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-drop-up.svg");
- mask-image: url("../icons/icon-drop-up.svg");
- }
-}
-
-.edit {
- &.bg-icon {
- background-image: url("../icons/icon-edit.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-edit.svg");
- mask-image: url("../icons/icon-edit.svg");
- }
-}
-
-.event-note {
- &.bg-icon {
- background-image: url("../icons/icon-event-note.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-event-note.svg");
- mask-image: url("../icons/icon-event-note.svg");
- }
-}
-
-.face {
- &.bg-icon {
- background-image: url("../icons/icon-face.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-face.svg");
- mask-image: url("../icons/icon-face.svg");
- }
-}
-
-.feature-info {
- &.bg-icon {
- background-image: url("../icons/icon-feature-info.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-feature-info.svg");
- mask-image: url("../icons/icon-feature-info.svg");
- }
-}
-
-.filter-list {
- &.bg-icon {
- background-image: url("../icons/icon-filter-list.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-filter-list.svg");
- mask-image: url("../icons/icon-filter-list.svg");
- }
-}
-
-.fullscreen {
- &.bg-icon {
- background-image: url("../icons/icon-fullscreen.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-fullscreen.svg");
- mask-image: url("../icons/icon-fullscreen.svg");
- }
-}
-
-.gps-not-fixed {
- &.bg-icon {
- background-image: url("../icons/icon-gps_not_fixed.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-gps_not_fixed.svg");
- mask-image: url("../icons/icon-gps_not_fixed.svg");
- }
-}
-
-.layers {
- &.bg-icon {
- background-image: url("../icons/icon-layers.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-layers.svg");
- mask-image: url("../icons/icon-layers.svg");
- }
-}
-
-.line {
- &.bg-icon {
- background-image: url("../icons/icon-line.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-line.svg");
- mask-image: url("../icons/icon-line.svg");
- }
-}
-
-.location {
- &.bg-icon {
- background-image: url("../icons/icon-location.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-location.svg");
- mask-image: url("../icons/icon-location.svg");
- }
-}
-
-.location-tick {
- &.bg-icon {
- background-image: url("../icons/icon-location-tick.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-location-tick.svg");
- mask-image: url("../icons/icon-location-tick.svg");
- }
-}
-
-.lock-closed {
- &.bg-icon {
- background-image: url("../icons/icon-lock-closed.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-lock-closed.svg");
- mask-image: url("../icons/icon-lock-closed.svg");
- }
-}
-
-.lock-open {
- &.bg-icon {
- background-image: url("../icons/icon-lock-open.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-lock-open.svg");
- mask-image: url("../icons/icon-lock-open.svg");
- }
-}
-
-.logout {
- &.bg-icon {
- background-image: url("../icons/icon-logout.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-logout.svg");
- mask-image: url("../icons/icon-logout.svg");
- }
-}
-
-.map {
- &.bg-icon {
- background-image: url("../icons/icon-map.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-map.svg");
- mask-image: url("../icons/icon-map.svg");
- }
-}
-
-.maps-ugc {
- &.bg-icon {
- background-image: url("../icons/icon-maps-ugc.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-maps-ugc.svg");
- mask-image: url("../icons/icon-maps-ugc.svg");
- }
-}
-
-.multiline-chart {
- &.bg-icon {
- background-image: url("../icons/icon-multiline-chart.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-multiline-chart.svg");
- mask-image: url("../icons/icon-multiline-chart.svg");
- }
-}
-
-.notes {
- &.bg-icon {
- background-image: url("../icons/icon-notes.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-notes.svg");
- mask-image: url("../icons/icon-notes.svg");
- }
-}
-
-.open-in-new {
- &.bg-icon {
- background-image: url("../icons/icon-open-in-new.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-open-in-new.svg");
- mask-image: url("../icons/icon-open-in-new.svg");
- }
-}
-
-.pageview {
- &.bg-icon {
- background-image: url("../icons/icon-pageview.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-pageview.svg");
- mask-image: url("../icons/icon-pageview.svg");
- }
-}
-
-.people {
- &.bg-icon {
- background-image: url("../icons/icon-people.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-people.svg");
- mask-image: url("../icons/icon-people.svg");
- }
-}
-
-.pie-chart {
- &.bg-icon {
- background-image: url("../icons/icon-pie-chart.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-pie-chart.svg");
- mask-image: url("../icons/icon-pie-chart.svg");
- }
-}
-
-.radio-button-checked {
- &.bg-icon {
- background-image: url("../icons/icon-radio-button-checked.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-radio-button-checked.svg");
- mask-image: url("../icons/icon-radio-button-checked.svg");
- }
-}
-
-.remove {
- &.bg-icon {
- background-image: url("../icons/icon-remove.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-remove.svg");
- mask-image: url("../icons/icon-remove.svg");
- }
-}
-
-.reply {
- &.bg-icon {
- background-image: url("../icons/icon-reply.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-reply.svg");
- mask-image: url("../icons/icon-reply.svg");
- }
-}
-
-.restore {
- &.bg-icon {
- background-image: url("../icons/icon-restore.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-restore.svg");
- mask-image: url("../icons/icon-restore.svg");
- }
-}
-
-.room {
- &.bg-icon {
- background-image: url("../icons/icon-room.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-room.svg");
- mask-image: url("../icons/icon-room.svg");
- }
-}
-
-.save {
- &.bg-icon {
- background-image: url("../icons/icon-save.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-save.svg");
- mask-image: url("../icons/icon-save.svg");
- }
-}
-
-.scatter-plot {
- &.bg-icon {
- background-image: url("../icons/icon-scatter-plot.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-scatter-plot.svg");
- mask-image: url("../icons/icon-scatter-plot.svg");
- }
-}
-
-.school {
- &.bg-icon {
- background-image: url("../icons/icon-school.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-school.svg");
- mask-image: url("../icons/icon-school.svg");
- }
-}
-
-.search {
- &.bg-icon {
- background-image: url("../icons/icon-search.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-search.svg");
- mask-image: url("../icons/icon-search.svg");
- }
-}
-
-.settings {
- &.bg-icon {
- background-image: url("../icons/icon-settings.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-settings.svg");
- mask-image: url("../icons/icon-settings.svg");
- }
-}
-
-.show-chart {
- &.bg-icon {
- background-image: url("../icons/icon-show-chart.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-show-chart.svg");
- mask-image: url("../icons/icon-show-chart.svg");
- }
-}
-
-.straighten {
- &.bg-icon {
- background-image: url("../icons/icon-straighten.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-straighten.svg");
- mask-image: url("../icons/icon-straighten.svg");
- }
-}
-
-.supervisor-account {
- &.bg-icon {
- background-image: url("../icons/icon-supervisor-account.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-supervisor-account.svg");
- mask-image: url("../icons/icon-supervisor-account.svg");
- }
-}
-
-.tick-done {
- &.bg-icon {
- background-image: url("../icons/icon-tick-done.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-tick-done.svg");
- mask-image: url("../icons/icon-tick-done.svg");
- }
-}
-
-.tick-done-all {
- &.bg-icon {
- background-image: url("../icons/icon-tick-done-all.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-tick-done-all.svg");
- mask-image: url("../icons/icon-tick-done-all.svg");
- }
-}
-
-.toggle {
- &.bg-icon {
- background-image: url("../icons/icon-toggle-off.svg");
- &.on {
- background-image: url("../icons/icon-toggle-on.svg");
- }
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-toggle-off.svg");
- mask-image: url("../icons/icon-toggle-off.svg");
- &.on {
- -webkit-mask-image: url("../icons/icon-toggle-on.svg");
- mask-image: url("../icons/icon-toggle-on.svg");
- }
- }
- &.disabled {
- opacity: 0.5;
- pointer-events: none;
- }
-}
-
-.touch-app {
- &.bg-icon {
- background-image: url("../icons/icon-touch-app.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-touch-app.svg");
- mask-image: url("../icons/icon-touch-app.svg");
- }
-}
-
-.translate {
- &.bg-icon {
- background-image: url("../icons/icon-translate.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-translate.svg");
- mask-image: url("../icons/icon-translate.svg");
- }
-}
-
-.trash {
- &.bg-icon {
- background-image: url("../icons/icon-trash.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-trash.svg");
- mask-image: url("../icons/icon-trash.svg");
- }
-}
-
-.vertical-align-bottom {
- &.bg-icon {
- background-image: url("../icons/icon-vertical-align-bottom.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-vertical-align-bottom.svg");
- mask-image: url("../icons/icon-vertical-align-bottom.svg");
- }
-}
-
-.vertical-align-top {
- &.bg-icon {
- background-image: url("../icons/icon-vertical-align-top.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-vertical-align-top.svg");
- mask-image: url("../icons/icon-vertical-align-top.svg");
- }
-}
-
-.view-list {
- &.bg-icon {
- background-image: url("../icons/icon-view-list.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-view-list.svg");
- mask-image: url("../icons/icon-view-list.svg");
- }
-}
-
-.visibility-off {
- &.bg-icon {
- background-image: url("../icons/icon-visibility-off.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-visibility-off.svg");
- mask-image: url("../icons/icon-visibility-off.svg");
- }
-}
-
-.warning {
- &.bg-icon {
- background-image: url("../icons/icon-warning.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-warning.svg");
- mask-image: url("../icons/icon-warning.svg");
- }
-}
-
-.wysiwyg {
- &.bg-icon {
- background-image: url("../icons/icon-wysiwyg.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-wysiwyg.svg");
- mask-image: url("../icons/icon-wysiwyg.svg");
- }
-}
-
-.info {
- &.bg-icon {
- background-image: url("../icons/icon-info.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-info.svg");
- mask-image: url("../icons/icon-info.svg");
- }
-}
-
-.question-mark {
- &.bg-icon {
- background-image: url("../icons/icon-question-mark.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-question-mark.svg");
- mask-image: url("../icons/icon-question-mark.svg");
- }
-}
-
-.lightbulb {
- &.bg-icon {
- background-image: url("../icons/icon-lightbulb.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-lightbulb.svg");
- mask-image: url("../icons/icon-lightbulb.svg");
- }
-}
-
-.info-report {
- &.bg-icon {
- background-image: url("../icons/icon-info-report.svg");
- }
- &.mask-icon {
- -webkit-mask-image: url("../icons/icon-info-report.svg");
- mask-image: url("../icons/icon-info-report.svg");
- }
-}
\ No newline at end of file
diff --git a/public/css/_inputs.css b/public/css/_inputs.css
deleted file mode 100644
index 27ffefb57d..0000000000
--- a/public/css/_inputs.css
+++ /dev/null
@@ -1,388 +0,0 @@
-input {
- width: 100%;
-
- &:focus {
- outline: none;
- }
-}
-
-input.invalid {
- opacity: 0.5;
- outline: 1px solid var(--color-no);
-}
-
-input::placeholder {
- text-align: left;
-}
-
-input::-moz-focus-inner,
-input::-moz-focus-outer {
- border: 0;
-}
-
-textarea {
- width: 100%;
- resize: none;
- border: none;
- border-bottom: 0.5px dotted;
- background-color: var(--color-light-secondary);
-}
-
-input[type=number] {
- -moz-appearance: textfield;
- text-align: right;
-}
-
-input[type=number]::-webkit-inner-spin-button,
-input[type=number]::-webkit-outer-spin-button {
- -webkit-appearance: none;
- margin: 0;
-}
-
-input[type=search],
-input[type=date],
-input[type=time],
-input[type=datetime-local] {
- border: 1px solid #ccc;
- padding: 5px;
-
- &:focus {
- cursor: text;
- }
-}
-
-input[type=text],
-input[type=number] {
- padding: 5px;
- border: none;
- background-color: var(--color-light-secondary);
- border-bottom: 0.5px dotted;
- display: inline-block;
- width: 100%;
- min-width: 2.4ch;
-
- &:focus {
- cursor: text;
- }
-}
-
-input[type=search]:focus+ul,
-input[type=search]+ul:active {
- display: block;
-}
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration:hover,
-input[type="search"]::-webkit-search-cancel-button:hover {
- cursor: pointer;
-}
-
-label.checkbox {
- display: block;
-
- &.disabled {
- opacity: 0.3;
- pointer-events: none;
- }
-
- &.inline {
- display: inline-block;
- }
-
- &>span {
- vertical-align: middle;
- }
-
- &.inline+span {
- vertical-align: middle;
- }
-
- &>input {
- display: none;
- }
-
- &>div {
- display: inline-block;
- vertical-align: middle;
- height: 1em;
- min-height: 12px;
- width: 1em;
- min-width: 12px;
- margin-right: 0.5em;
- background-repeat: no-repeat;
- background-position: center;
- background-size: contain;
- -webkit-background-size: contain;
- background-image: url("../icons/icon-checkbox-unchecked.svg");
- }
-
- &>div:hover {
- cursor: pointer;
- }
-
- & input:checked+div {
- background-image: url("../icons/icon-checkbox-checked.svg");
- }
-
- & input:disabled~* {
- opacity: 0.4;
- }
-}
-
-.searchbox {
- width: 100%;
- overflow: visible;
- position: relative;
- background-color: white;
- box-shadow: var(--color-mid) 0px 8px 24px;
-
- &>ul {
- display: none;
- max-height: 500px;
- overflow-y: auto;
- overflow-x: hidden;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- margin-top: -1px;
- text-align: left;
- background-color: white;
- z-index: 999;
-
- &>li {
- padding: 5px;
- }
-
- &>li:hover {
- background-color: var(--color-primary-light);
- cursor: pointer;
- }
-
- &>li.selected {
- background-color: var(--color-light-secondary);
- }
-
- & .label {
- padding: 0 6px;
- border-radius: 2px;
- color: var(--color-light);
- font-size: 80%;
- font-weight: bold;
- background-color: var(--color-primary);
- }
- }
-}
-
-.dropdown {
- width: 100%;
- overflow: visible;
- position: relative;
- background-color: white;
- box-shadow: var(--color-mid) 0px 8px 24px;
-
- &:disabled {
- pointer-events: none;
- opacity: 0.4;
- }
-
- &>.head {
- padding: 5px;
- display: flex;
- align-items: center;
-
- &>:first-child {
- pointer-events: none;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
-
- &>.icon {
- pointer-events: none;
- margin-left: auto;
- width: 1.5em;
- content: url("../icons/icon-drop-down.svg");
- }
- }
-
- &>ul {
- display: none;
- position: absolute;
- max-height: 500px;
- overflow-y: auto;
- overflow-x: hidden;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- margin-top: -1px;
- text-align: left;
- background-color: white;
- z-index: 997;
-
- &>li {
- padding: 5px;
- }
-
- &>li:hover {
- background-color: var(--color-primary-light);
- cursor: pointer;
- }
-
- &>li.selected {
- background-color: var(--color-light-secondary);
- }
-
- & .label {
- padding: 0 6px;
- border-radius: 2px;
- color: var(--color-light);
- font-size: 80%;
- font-weight: bold;
- background-color: var(--color-primary);
- }
- }
-
- &.active>ul {
- display: block;
-
- &>.head>.icon {
- content: url("../icons/icon-drop-up.svg");
- }
- }
-
- &.dropdown-reverse>ul {
- bottom: 30px;
- }
-}
-
-@media print {
- .dropdown {
- box-shadow: none;
-
- &>.head>.icon {
- display: none;
- }
- }
-
- .searchbox {
- box-shadow: none;
- }
-}
-
-.input-range {
- --dif: calc(var(--max) - var(--min));
- display: grid;
- grid-template-columns: 50% 50%;
- position: relative;
- width: 100%;
-
- & .label-row {
- grid-row: 1;
- grid-column: 1/3;
- }
-
- & .track-bg {
- grid-row: 2;
- grid-column: 1/3;
- background: linear-gradient(0deg, transparent 0 45%, var(--color-primary-light) 45% 55%, transparent 55% 100%);
- z-index: 1;
- }
-
- &.single::after {
- grid-column: 1/3;
- grid-row: 2;
- background: linear-gradient(0deg, transparent 0 45%, var(--color-primary) 45% 55%, transparent 55% 100%);
- content: '';
- z-index: 2;
- width: calc((var(--a) - var(--min)) / var(--dif) * (100% - 10px));
- }
-
- &.multi {
- &>.label-row {
- display: flex;
- justify-content: space-between;
-
- &>div {
- flex-grow: 1
- }
- }
-
- &::before,
- &::after {
- grid-column: 1/3;
- grid-row: 2;
- background: linear-gradient(0deg, transparent 0 45%, var(--color-primary) 45% 55%, transparent 55% 100%);
- content: '';
- z-index: 2;
- }
-
- &::before {
- margin-left: calc(10px + (var(--a) - var(--min)) / var(--dif) * (100% - 10px));
- width: calc((var(--b) - var(--a)) / var(--dif) * (100% - 10px));
- }
-
- &::after {
- margin-left: calc(10px + (var(--b) - var(--min)) / var(--dif) * (100% - 10px));
- width: calc((var(--a) - var(--b)) / var(--dif) * (100% - 10px));
- }
- }
-
- & input[type='range'] {
- -webkit-appearance: none;
- grid-column: 1/3;
- grid-row: 2;
- z-index: 3;
- top: 0;
- left: 0;
- margin: 0;
- background: none;
- /* get rid of white Chrome background */
- pointer-events: none;
- }
-
- &.disabled {
- opacity: 0.5;
- pointer-events: none;
- }
-}
-
-.input-range input[type='range']::-webkit-slider-runnable-track {
- width: 100%;
- height: 100%;
- background: none;
- /* get rid of Firefox track background */
-}
-
-.input-range input[type='range']::-moz-range-track {
- width: 100%;
- height: 100%;
- background: none;
- /* get rid of Firefox track background */
-}
-
-.input-range input[type='range']::-webkit-slider-thumb {
- -webkit-appearance: none;
- border: none;
- /* get rid of Firefox thumb border */
- width: 20px;
- height: 40px;
- border-radius: 0;
- /* get rid of Firefox corner rounding */
- pointer-events: auto;
- cursor: pointer;
- background: url("../icons/thumb.svg");
- background-repeat: no-repeat;
- background-position: center;
- box-shadow: none;
-}
-
-.input-range input[type='range']::-moz-range-thumb {
- border: none;
- /* get rid of Firefox thumb border */
- width: 20px;
- height: 40px;
- border-radius: 0;
- /* get rid of Firefox corner rounding */
- pointer-events: auto;
- cursor: pointer;
- background: url("../icons/thumb.svg");
- background-repeat: no-repeat;
- background-position: center;
- box-shadow: none;
-}
\ No newline at end of file
diff --git a/public/css/_mapp.css b/public/css/_mapp.css
index b87958cb82..1b5f6c62b1 100644
--- a/public/css/_mapp.css
+++ b/public/css/_mapp.css
@@ -1,258 +1,17 @@
-@import url('./_colours.css');
+@import url('./base/_colours.css');
-*,
-*::after,
-*::before {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- -o-box-sizing: border-box;
- box-sizing: border-box;
- margin: 0;
- padding: 0;
- border-spacing: 0;
- font-family: inherit;
- font-size: inherit;
-}
-body {
- position: absolute;
- width: 100%;
- height: 100%;
-}
+@import url('./layout/_ol.css');
-.display-none {
- display: none !important;
-}
+@import url('./layout/_map_attribution.css');
-.hover:hover {
- cursor: pointer;
-}
+@import url('./layout/_legend.css');
-.box-shadow {
- border: 1px solid #eee;
- box-shadow: 2px 2px 4px var(--color-primary-light);
-}
+@import url('./layout/_infotip.css');
-.ol-scale-line {
- position: static;
- background: none;
-}
+@import url('./layout/_popup.css');
-.ol-scale-line-inner {
- border: 2px solid #222;
- border-top: none;
- color: #222;
- text-align: center;
- margin: 1px;
- will-change: contents, width
-}
-.ol-unselectable,
-.ol-viewport {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-tap-highlight-color: transparent;
-}
-.ol-zoom {
- top: 0.5em;
- left: 0.5em;
- & .ol-zoom-in,
- & .ol-zoom-out {
- border-radius: 2px 2px 0 0;
- }
-}
-.ol-control {
- position: absolute;
- background-color: rgba(255,255,255,.4);
- border-radius: 4px;
- padding: 2px;
-
- & button {
- display: block;
- margin: 1px;
- padding: 0;
- color: #fff;
- font-weight: 700;
- text-decoration: none;
- font-size: inherit;
- text-align: center;
- height: 1.375em;
- width: 1.375em;
- line-height: .4em;
- background-color: rgba(0,60,136,.5);
- border: none;
- border-radius: 2px;
- }
-}
-
-.infotip {
- position: fixed;
- z-index: 998;
- margin: 0;
- padding: 5px;
- background-color: white;
- opacity: 0;
- transition-property: opacity;
- transition-duration: 0.3s;
- transition-delay: 0.2s;
-}
-
-.popup {
- position: absolute;
- background-color: white;
- bottom: 12px;
- transform: translate(-50%, 0);
-
- &::after,
- &::before {
- border: solid transparent;
- content: " ";
- position: absolute;
- pointer-events: none;
- }
-
- &::after {
- border-top-color: white;
- border-width: 10px;
- left: 50%;
- margin-left: -10px;
- }
-
- & li{
- padding: 5px 10px;
- white-space: nowrap;
- line-height: 1.5;
- list-style-type: none;
- }
-
- & li:hover {
- background: var(--color-light-secondary);
- cursor: pointer;
- }
-
- .list {
- max-width: 66vw;
- max-height: 300px;
- overflow-x: hidden;
- }
-}
-
-a > img {
- height: 100%;
-}
-
-.map-attribution {
- position: absolute;
- display: flex;
- justify-content: space-between;
- align-items: end;
- bottom: 0;
- right: 0;
- width: 100%;
- padding: 5px;
- pointer-events: none;
- user-select: none;
-}
-
-.attribution-links {
- text-align: right;
- font-size: 95%;
-
- & a {
- pointer-events: auto;
- margin-left: 5px;
- display: inline-block;
- white-space: nowrap;
- line-height: 1;
- background: #fff9;
- border-bottom: 2px solid var(--color-primary-light);
- }
-}
-
-.legend {
-
- & .contents-wrapper,
- &.content .contents-wrapper {
- margin-top: 0.5em;
- gap: 0.5em;
-
- &>.contents {
- display: contents;
- }
-
- &.label {
- grid-column: 2;
- }
-
- &.flex {
- display: flex;
- flex-wrap: wrap;
- flex-grow: 1;
- justify-content: start;
-
- & .contents {
- display: block;
- flex-basis: 30%;
- flex-shrink: 1;
-
- &.center {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- margin-bottom: 1em;
- text-align: center;
- }
-
- &.row {
- display: flex;
- align-items: center;
- margin-bottom: 1em;
- }
-
- &.horizontal {
- display: flex;
- align-items: center;
- flex-direction: column;
- flex-basis: auto;
- flex-grow: 1;
- }
- }
-
- &.nowrap {
- flex-wrap: nowrap;
-
- & .contents {
- justify-content: flex-start;
-
- & .label {
- text-align: center;
- }
- }
- }
- }
-
- &.grid {
- display: grid;
- grid-template-columns: min-content;
- align-items: center;
- justify-content: start;
- }
- }
-
- & .switch {
- cursor: pointer;
- }
-
- & .switch.disabled {
- /* text-decoration: line-through; */
- opacity: 0.5;
- }
-}
\ No newline at end of file
diff --git a/public/css/_tabulator.scss b/public/css/_tabulator.scss
deleted file mode 100644
index 93117959d4..0000000000
--- a/public/css/_tabulator.scss
+++ /dev/null
@@ -1,1404 +0,0 @@
-
-//Main Theme Variables
-$backgroundColor: #888 !default; //background color of tabulator
-$borderColor:#999 !default; //border to tabulator
-$textSize:14px !default; //table text size
-
-//header theming
-$headerBackgroundColor:#e6e6e6 !default; //border to tabulator
-$headerTextColor:#555 !default; //header text color
-$headerBorderColor:#aaa !default; //header border color
-$headerSeparatorColor:#999 !default; //header bottom separator color
-$headerMargin:4px !default; //padding round header
-
-//column header arrows
-$sortArrowActive: #666 !default;
-$sortArrowInactive: #bbb !default;
-
-//row theming
-$rowBackgroundColor:#fff !default; //table row background color
-$rowAltBackgroundColor:#EFEFEF !default; //table row background color
-$rowBorderColor:#aaa !default; //table border color
-$rowTextColor:#333 !default; //table text color
-$rowHoverBackground:#bbb !default; //row background color on hover
-
-$rowSelectedBackground: #9ABCEA !default; //row background color when selected
-$rowSelectedBackgroundHover: #769BCC !default;//row background color when selected and hovered
-
-$editBoxColor:#1D68CD !default; //border color for edit boxes
-$errorColor:#dd0000 !default; //error indication
-
-//footer theming
-$footerBackgroundColor:#e6e6e6 !default; //border to tabulator
-$footerTextColor:#555 !default; //footer text color
-$footerBorderColor:#aaa !default; //footer border color
-$footerSeparatorColor:#999 !default; //footer bottom separator color
-$footerActiveColor:#d00 !default; //footer bottom active text color
-
-
-
-//Tabulator Containing Element
-.tabulator{
- position: relative;
-
- border: 1px solid $borderColor;
-
- background-color: $backgroundColor;
-
- font-size:$textSize;
- text-align: left;
- overflow:hidden;
-
- -webkit-transform: translateZ(0);
- -moz-transform: translateZ(0);
- -ms-transform: translateZ(0);
- -o-transform: translateZ(0);
- transform: translateZ(0);
-
- &[tabulator-layout="fitDataFill"]{
- .tabulator-tableholder{
- .tabulator-table{
- min-width:100%;
- }
- }
- }
-
- &[tabulator-layout="fitDataTable"]{
- display: inline-block;
- }
-
- &.tabulator-block-select{
- user-select: none;
- }
-
- //column header containing element
- .tabulator-header{
- position:relative;
- box-sizing: border-box;
-
- width:100%;
-
- border-bottom:1px solid $headerSeparatorColor;
- background-color: $headerBackgroundColor;
- color: $headerTextColor;
- font-weight:bold;
-
- white-space: nowrap;
- overflow:hidden;
-
- -moz-user-select: none;
- -khtml-user-select: none;
- -webkit-user-select: none;
- -o-user-select: none;
-
- &.tabulator-header-hidden{
- display:none;
- }
-
- //individual column header element
- .tabulator-col{
- display:inline-flex;
- position:relative;
- box-sizing:border-box;
-
- flex-direction: column;
- justify-content: flex-start;
-
- border-right:1px solid $headerBorderColor;
- background:$headerBackgroundColor;
-
- text-align:left;
- vertical-align: bottom;
- overflow: hidden;
-
- &.tabulator-moving{
- position: absolute;
- border:1px solid $headerSeparatorColor;
- background:darken($headerBackgroundColor, 10%);
- pointer-events: none;
- }
-
- //hold content of column header
- .tabulator-col-content{
- box-sizing:border-box;
- position: relative;
- padding:4px;
-
- //header menu button
- .tabulator-header-popup-button{
- padding: 0 8px;
-
- &:hover{
- cursor: pointer;
- opacity: .6;
- }
- }
-
- //hold title and sort arrow
- .tabulator-col-title-holder{
- position: relative;
- }
-
- //hold title of column header
- .tabulator-col-title{
- box-sizing:border-box;
- width: 100%;
-
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- vertical-align:bottom;
-
- //element to hold title editor
- .tabulator-title-editor{
- box-sizing: border-box;
- width: 100%;
-
- border:1px solid #999;
-
- padding:1px;
-
- background: #fff;
- }
-
- .tabulator-header-popup-button + .tabulator-title-editor{
- width:calc(100% - 22px);
- }
- }
-
- //column sorter arrow
- .tabulator-col-sorter{
- display: flex;
- align-items: center;
-
- position: absolute;
- top:0;
- bottom:0;
- right:4px;
-
- .tabulator-arrow{
- width: 0;
- height: 0;
- border-left: 6px solid transparent;
- border-right: 6px solid transparent;
- border-bottom: 6px solid $sortArrowInactive;
- }
- }
-
- }
-
- //complex header column group
- &.tabulator-col-group{
-
- //gelement to hold sub columns in column group
- .tabulator-col-group-cols{
- position:relative;
- display: flex;
-
- border-top:1px solid $headerBorderColor;
- overflow: hidden;
-
- margin-right:-1px;
- }
- }
-
- //header filter containing element
- .tabulator-header-filter{
- position: relative;
- box-sizing: border-box;
- margin-top:2px;
- width:100%;
- text-align: center;
-
- //styling adjustment for inbuilt editors
- textarea{
- height:auto !important;
- }
-
- svg{
- margin-top: 3px;
- }
-
- input{
- &::-ms-clear {
- width : 0;
- height: 0;
- }
- }
- }
-
- //styling child elements for sortable columns
- &.tabulator-sortable{
- .tabulator-col-title{
- padding-right:25px;
- }
-
- &:hover{
- cursor:pointer;
- background-color:darken($headerBackgroundColor, 10%);
- }
-
- &[aria-sort="none"]{
- .tabulator-col-content .tabulator-col-sorter{
- color: $sortArrowInactive;
-
- .tabulator-arrow{
- border-top: none;
- border-bottom: 6px solid $sortArrowInactive;
- }
- }
- }
-
- &[aria-sort="ascending"]{
- .tabulator-col-content .tabulator-col-sorter{
- color: $sortArrowActive;
-
- .tabulator-arrow{
- border-top: none;
- border-bottom: 6px solid $sortArrowActive;
-
- }
- }
- }
-
- &[aria-sort="descending"]{
- .tabulator-col-content .tabulator-col-sorter{
- color: $sortArrowActive;
-
- .tabulator-arrow{
- border-bottom: none;
- border-top: 6px solid $sortArrowActive;
- color: $sortArrowActive;
- }
- }
- }
- }
-
-
- &.tabulator-col-vertical{
- .tabulator-col-content{
- .tabulator-col-title{
- writing-mode: vertical-rl;
- text-orientation: mixed;
-
- display:flex;
- align-items:center;
- justify-content:center;
- }
- }
-
- &.tabulator-col-vertical-flip{
- .tabulator-col-title{
- transform: rotate(180deg);
- }
- }
-
- &.tabulator-sortable{
- .tabulator-col-title{
- padding-right:0;
- padding-top:20px;
- }
-
- &.tabulator-col-vertical-flip{
- .tabulator-col-title{
- padding-right:0;
- padding-bottom:20px;
- }
-
- }
-
- .tabulator-col-sorter{
- justify-content: center;
- left:0;
- right:0;
- top:4px;
- bottom:auto;
- }
- }
- }
- }
-
- .tabulator-frozen{
- position: absolute;
-
- // background-color: inherit;
-
- z-index: 10;
-
- &.tabulator-frozen-left{
- border-right:2px solid $rowBorderColor;
- }
-
- &.tabulator-frozen-right{
- border-left:2px solid $rowBorderColor;
- }
- }
-
-
- .tabulator-calcs-holder{
- box-sizing:border-box;
- min-width:600%;
-
- background:lighten($headerBackgroundColor, 5%) !important;
-
- .tabulator-row{
- background:lighten($headerBackgroundColor, 5%) !important;
-
- .tabulator-col-resize-handle{
- display: none;
- }
- }
-
- border-top:1px solid $rowBorderColor;
- border-bottom:1px solid $headerBorderColor;
-
- overflow: hidden;
- }
-
- .tabulator-frozen-rows-holder{
- min-width:600%;
-
- &:empty{
- display: none;
- }
- }
- }
-
- //scrolling element to hold table
- .tabulator-tableholder{
- position:relative;
- width:100%;
- white-space: nowrap;
- overflow:auto;
- -webkit-overflow-scrolling: touch;
-
- &:focus{
- outline: none;
- }
-
- //default placeholder element
- .tabulator-placeholder{
- box-sizing:border-box;
- display: flex;
- align-items:center;
-
- &[tabulator-render-mode="virtual"]{
- min-height:100%;
- min-width:100%;
- }
-
- width:100%;
-
- .tabulator-placeholder-contents {
- display: inline-block;
- text-align: center;
-
- padding:10px;
-
- color:#ccc;
- font-weight: bold;
- font-size: 20px;
-
- white-space: normal;
- }
- }
-
- //element to hold table rows
- .tabulator-table{
- position:relative;
- display:inline-block;
- background-color:$rowBackgroundColor;
- white-space: nowrap;
- overflow:visible;
- color:$rowTextColor;
-
- //row element
- .tabulator-row{
- &.tabulator-calcs{
- font-weight: bold;
- background:darken($rowAltBackgroundColor, 5%) !important;
-
- &.tabulator-calcs-top{
- border-bottom:2px solid $rowBorderColor;
- }
-
- &.tabulator-calcs-bottom{
- border-top:2px solid $rowBorderColor;
- }
- }
- }
-
- }
- }
-
- //footer element
- .tabulator-footer{
- border-top:1px solid $footerSeparatorColor;
- background-color: $footerBackgroundColor;
-
- color: $footerTextColor;
- font-weight:bold;
- white-space:nowrap;
- user-select:none;
-
- -moz-user-select: none;
- -khtml-user-select: none;
- -webkit-user-select: none;
- -o-user-select: none;
-
- .tabulator-footer-contents {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-
- padding:5px 10px;
-
- &:empty{
- display: none;
- }
- }
-
- .tabulator-calcs-holder{
- box-sizing:border-box;
- width:calc(100% + 20px);
-
- text-align: left;
-
- background:lighten($footerBackgroundColor, 5%) !important;
- border-bottom:1px solid $rowBorderColor;
- border-top:1px solid $rowBorderColor;
-
- overflow: hidden;
-
- .tabulator-row{
- background:lighten($footerBackgroundColor, 5%) !important;
-
- .tabulator-col-resize-handle{
- display: none;
- }
- }
-
-
- &:only-child{
- margin-bottom:-5px;
- border-bottom:none;
- }
- }
-
- &>*+.tabulator-page-counter{
- margin-left:10px;
- }
-
- .tabulator-page-counter {
- font-weight: normal;
- }
-
- .tabulator-paginator{
- flex:1;
-
- text-align: right;
-
- color: $footerTextColor;
- font-family:inherit;
- font-weight:inherit;
- font-size:inherit;
- }
-
- //pagination container element
- .tabulator-page-size{
- display:inline-block;
-
- margin:0 5px;
- padding:2px 5px;
-
- border:1px solid $footerBorderColor;
- border-radius:3px;
- }
-
- .tabulator-pages{
- margin:0 7px;
- }
-
- //pagination button
- .tabulator-page{
- display:inline-block;
-
- margin:0 2px;
- padding:2px 5px;
-
- border:1px solid $footerBorderColor;
- border-radius:3px;
-
- background:rgba(255,255,255,.2);
-
- &.active{
- color:$footerActiveColor;
- }
-
- &:disabled{
- opacity:.5;
- }
-
- &:not(.disabled){
- &:hover{
- cursor:pointer;
- background:rgba(0,0,0,.2);
- color:#fff;
- }
- }
- }
- }
-
- //column resize handles
- .tabulator-col-resize-handle{
- position: relative;
- display: inline-block;
- width: 6px;
-
- margin-left: -3px;
- margin-right: -3px;
-
- z-index: 10;
- vertical-align: middle;
-
- &:hover{
- cursor:ew-resize;
- }
-
- &:last-of-type{
- width:3px;
- margin-right:0;
- }
- }
-
-
- //holding div that contains loader and covers tabulator element to prevent interaction
- .tabulator-alert{
- position:absolute;
- display: flex;
- align-items:center;
-
- top:0;
- left:0;
- z-index:100;
-
- height:100%;
- width:100%;
- background:rgba(0,0,0,.4);
- text-align:center;
-
- //loading message element
- .tabulator-alert-msg {
- display:inline-block;
-
- margin:0 auto;
- padding:10px 20px;
-
- border-radius:10px;
-
- background:#fff;
- font-weight:bold;
- font-size:16px;
-
- //loading message
- &.tabulator-alert-state-msg {
- border:4px solid #333;
- color:#000;
- }
-
- //error message
- &.tabulator-alert-state-error {
- border:4px solid #D00;
- color:#590000;
- }
- }
- }
-}
-
-//row element
-.tabulator-row{
- position: relative;
- box-sizing: border-box;
- min-height:$textSize + ($headerMargin * 2);
- background-color: $rowBackgroundColor;
-
-
- &.tabulator-row-even{
- background-color: $rowAltBackgroundColor;
- }
-
- &.tabulator-selectable:hover{
- background-color:$rowHoverBackground;
- cursor: pointer;
- }
-
- &.tabulator-selected{
- background-color:$rowSelectedBackground;
- }
-
- &.tabulator-selected:hover{
- background-color:$rowSelectedBackgroundHover;
- cursor: pointer;
- }
-
- &.tabulator-row-moving{
- border:1px solid #000;
- background:#fff;
- }
-
- &.tabulator-moving{
- position: absolute;
-
- border-top:1px solid $rowBorderColor;
- border-bottom:1px solid $rowBorderColor;
-
- pointer-events: none;
- z-index:15;
- }
-
- //row resize handles
- .tabulator-row-resize-handle{
- position:absolute;
- right:0;
- bottom:0;
- left:0;
- height:5px;
-
- &.prev{
- top:0;
- bottom:auto;
- }
-
- &:hover{
- cursor:ns-resize;
- }
- }
-
- .tabulator-frozen{
- display: inline-block;
- position: absolute;
-
- background-color: inherit;
-
- z-index: 10;
-
- &.tabulator-frozen-left{
- border-right:2px solid $rowBorderColor;
- }
-
- &.tabulator-frozen-right{
- border-left:2px solid $rowBorderColor;
- }
- }
-
- .tabulator-responsive-collapse{
- box-sizing:border-box;
-
- padding:5px;
-
- border-top:1px solid $rowBorderColor;
- border-bottom:1px solid $rowBorderColor;
-
- &:empty{
- display:none;
- }
-
- table{
- font-size:$textSize;
-
- tr{
- td{
- position: relative;
-
- &:first-of-type{
- padding-right:10px;
- }
- }
- }
- }
- }
-
- //cell element
- .tabulator-cell{
- display:inline-block;
- position: relative;
- box-sizing:border-box;
- padding:4px;
- border-right:1px solid $rowBorderColor;
- vertical-align:middle;
- white-space:nowrap;
- overflow:hidden;
- text-overflow:ellipsis;
-
- &.tabulator-editing{
- border:1px solid $editBoxColor;
- outline:none;
-
- padding: 0;
-
- input, select{
- border:1px;
- background:transparent;
- outline:none;
- }
- }
-
- &.tabulator-validation-fail{
- border:1px solid $errorColor;
-
- input, select{
- border:1px;
- background:transparent;
-
- color: $errorColor;
- }
- }
-
- //movable row handle
- &.tabulator-row-handle{
- display: inline-flex;
- align-items:center;
- justify-content:center;
-
- -moz-user-select: none;
- -khtml-user-select: none;
- -webkit-user-select: none;
- -o-user-select: none;
-
- //handle holder
- .tabulator-row-handle-box{
- width:80%;
-
- //Hamburger element
- .tabulator-row-handle-bar{
- width:100%;
- height:3px;
- margin-top:2px;
- background:#666;
- }
- }
- }
-
- .tabulator-data-tree-branch{
- display:inline-block;
- vertical-align:middle;
-
- height:9px;
- width:7px;
-
- margin-top:-9px;
- margin-right:5px;
-
- border-bottom-left-radius:1px;
-
- border-left:2px solid $rowBorderColor;
- border-bottom:2px solid $rowBorderColor;
- }
-
- .tabulator-data-tree-control{
-
- display:inline-flex;
- justify-content:center;
- align-items:center;
- vertical-align:middle;
-
- height:11px;
- width:11px;
-
- margin-right:5px;
-
- border:1px solid $rowTextColor;
- border-radius:2px;
- background:rgba(0, 0, 0, .1);
-
- overflow:hidden;
-
- &:hover{
- cursor:pointer;
- background:rgba(0, 0, 0, .2);
- }
-
- .tabulator-data-tree-control-collapse{
- display:inline-block;
- position: relative;
-
- height: 7px;
- width: 1px;
-
- background: transparent;
-
- &:after {
- position: absolute;
- content: "";
- left: -3px;
- top: 3px;
-
- height: 1px;
- width: 7px;
-
- background: $rowTextColor;
- }
- }
-
- .tabulator-data-tree-control-expand{
- display:inline-block;
- position: relative;
-
- height: 7px;
- width: 1px;
-
- background: $rowTextColor;
-
- &:after {
- position: absolute;
- content: "";
- left: -3px;
- top: 3px;
-
- height: 1px;
- width: 7px;
-
- background: $rowTextColor;
- }
- }
-
- }
-
- .tabulator-responsive-collapse-toggle{
- display: inline-flex;
- align-items:center;
- justify-content:center;
-
- -moz-user-select: none;
- -khtml-user-select: none;
- -webkit-user-select: none;
- -o-user-select: none;
-
- height:15px;
- width:15px;
-
- border-radius:20px;
- background:#666;
-
- color:$rowBackgroundColor;
- font-weight:bold;
- font-size:1.1em;
-
- &:hover{
- opacity:.7;
- }
-
- &.open{
- .tabulator-responsive-collapse-toggle-close{
- display:initial;
- }
-
- .tabulator-responsive-collapse-toggle-open{
- display:none;
- }
- }
-
- .tabulator-responsive-collapse-toggle-close{
- display:none;
- }
- }
-
- .tabulator-traffic-light{
- display: inline-block;
- height:14px;
- width:14px;
-
- border-radius:14px;
- }
- }
-
- //row grouping element
- &.tabulator-group{
- box-sizing:border-box;
- border-bottom:1px solid #999;
- border-right:1px solid $rowBorderColor;
- border-top:1px solid #999;
- padding:5px;
- padding-left:10px;
- background:#ccc;
- font-weight:bold;
-
- min-width: 100%;
-
- &:hover{
- cursor:pointer;
- background-color:rgba(0,0,0,.1);
- }
-
- &.tabulator-group-visible{
-
- .tabulator-arrow{
- margin-right:10px;
- border-left: 6px solid transparent;
- border-right: 6px solid transparent;
- border-top: 6px solid $sortArrowActive;
- border-bottom: 0;
- }
-
- }
-
- &.tabulator-group-level-1{
- padding-left:30px;
- }
-
- &.tabulator-group-level-2{
- padding-left:50px;
- }
-
- &.tabulator-group-level-3{
- padding-left:70px;
- }
-
- &.tabulator-group-level-4{
- padding-left:90px;
- }
-
- &.tabulator-group-level-5{
- padding-left:110px;
- }
-
- .tabulator-group-toggle{
- display: inline-block;
- }
-
- //sorting arrow
- .tabulator-arrow{
- display: inline-block;
- width: 0;
- height: 0;
- margin-right:16px;
- border-top: 6px solid transparent;
- border-bottom: 6px solid transparent;
- border-right: 0;
- border-left: 6px solid $sortArrowActive;
- vertical-align:middle;
- }
-
- span{
- margin-left:10px;
- color:#d00;
- }
- }
-
-}
-
-.tabulator-popup-container{
- position: absolute;
- display:inline-block;
- box-sizing:border-box;
-
- background:$rowBackgroundColor;
- border:1px solid $rowBorderColor;
- box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2);
-
- font-size:$textSize;
-
- overflow-y:auto;
- -webkit-overflow-scrolling: touch;
-
- z-index: 10000;
-}
-
-.tabulator-popup{
- padding:5px;
-
- border-radius: 3px;
-}
-
-.tabulator-tooltip{
- max-width: Min(500px, 100%);
-
- padding:3px 5px;
-
- border-radius: 2px;
- box-shadow:none;
-
- font-size:12px;
-
- pointer-events: none;
-}
-
-.tabulator-menu{
- .tabulator-menu-item{
- position:relative;
- box-sizing:border-box;
-
- padding:5px 10px;
-
- user-select: none;
-
- &.tabulator-menu-item-disabled{
- opacity: .5;
- }
-
- &:not(.tabulator-menu-item-disabled):hover{
- cursor: pointer;
- background: $rowAltBackgroundColor;
- }
-
- &.tabulator-menu-item-submenu{
- padding-right:25px;
-
- &::after {
- display: inline-block;
- position: absolute;
-
- top: calc(5px + .4em);
- right: 10px;
- height: 7px;
- width: 7px;
-
- content: '';
-
- border-width: 1px 1px 0 0;
- border-style: solid;
- border-color: $rowBorderColor;
- vertical-align: top;
-
- transform: rotate(45deg);
- }
- }
- }
-
- .tabulator-menu-separator{
- border-top:1px solid $rowBorderColor;
- }
-}
-
-.tabulator-edit-list{
- max-height:200px;
-
- font-size:$textSize;
-
- overflow-y:auto;
- -webkit-overflow-scrolling: touch;
-
- .tabulator-edit-list-item{
- padding:4px;
-
- color:$rowTextColor;
- outline:none;
-
- &.active{
- color:$rowBackgroundColor;
- background:$editBoxColor;
-
- &.focused{
- outline:1px solid rgba($rowBackgroundColor, .5);
- }
- }
-
- &.focused{
- outline:1px solid $editBoxColor;
- }
-
- &:hover{
- cursor:pointer;
-
- color:$rowBackgroundColor;
- background:$editBoxColor;
- }
- }
-
- .tabulator-edit-list-placeholder{
- padding:4px;
-
- color:$rowTextColor;
- text-align: center;
- }
-
- .tabulator-edit-list-group{
- border-bottom:1px solid $rowBorderColor;
-
- padding:4px;
- padding-top:6px;
-
- color:$rowTextColor;
- font-weight:bold;
-
- }
-
- .tabulator-edit-list-item, .tabulator-edit-list-group{
- &.tabulator-edit-list-group-level-2{
- padding-left:12px;
- }
-
- &.tabulator-edit-list-group-level-3{
- padding-left:20px;
- }
-
- &.tabulator-edit-list-group-level-4{
- padding-left:28px;
- }
-
- &.tabulator-edit-list-group-level-5{
- padding-left:36px;
- }
- }
-}
-
-
-//RTL Styling
-
-.tabulator.tabulator-ltr{
- direction: ltr;
-}
-
-.tabulator.tabulator-rtl{
- text-align: initial;
- direction: rtl;
-
- .tabulator-header {
- .tabulator-col{
- text-align: initial;
- border-left:1px solid $headerBorderColor;
- border-right:initial;
-
- &.tabulator-col-group{
- .tabulator-col-group-cols{
- margin-right:initial;
- margin-left:-1px;
- }
- }
-
- &.tabulator-sortable{
- .tabulator-col-title{
- padding-right:0;
- padding-left:25px;
- }
- }
-
- .tabulator-col-content{
- .tabulator-col-sorter{
- left:8px;
- right:initial;
- }
- }
- }
- }
-
- .tabulator-row{
- .tabulator-cell{
- border-right:initial;
- border-left:1px solid $rowBorderColor;
-
- .tabulator-data-tree-branch{
- margin-right:initial;
- margin-left:5px;
-
- border-bottom-left-radius:initial;
- border-bottom-right-radius:1px;
-
- border-left:initial;
- border-right:2px solid $rowBorderColor;
- }
-
- .tabulator-data-tree-control{
- margin-right:initial;
- margin-left:5px;
- }
- }
- }
-
- .tabulator-footer {
- .tabulator-calcs-holder{
- text-align: initial;
- }
-
- }
-
-}
-
-
-// Table print styling
-
-.tabulator-print-fullscreen{
- position: absolute;
- top:0;
- bottom:0;
- left:0;
- right:0;
-
- z-index: 10000;
-}
-
-body.tabulator-print-fullscreen-hide>*:not(.tabulator-print-fullscreen){
- display:none !important;
-}
-
-.tabulator-print-table{
- border-collapse: collapse;
-
- .tabulator-data-tree-branch{
- display:inline-block;
- vertical-align:middle;
-
- height:9px;
- width:7px;
-
- margin-top:-9px;
- margin-right:5px;
-
- border-bottom-left-radius:1px;
-
- border-left:2px solid $rowBorderColor;
- border-bottom:2px solid $rowBorderColor;
- }
-
- //row grouping element
- .tabulator-print-table-group{
- box-sizing:border-box;
- border-bottom:1px solid #999;
- border-right:1px solid $rowBorderColor;
- border-top:1px solid #999;
- padding:5px;
- padding-left:10px;
- background:#ccc;
- font-weight:bold;
-
- min-width: 100%;
-
- &:hover{
- cursor:pointer;
- background-color:rgba(0,0,0,.1);
- }
-
- &.tabulator-group-visible{
-
- .tabulator-arrow{
- margin-right:10px;
- border-left: 6px solid transparent;
- border-right: 6px solid transparent;
- border-top: 6px solid $sortArrowActive;
- border-bottom: 0;
- }
-
- }
-
- &.tabulator-group-level-1{
- td{
- padding-left:30px !important;
- }
- }
-
- &.tabulator-group-level-2{
- td{
- padding-left:50px !important;
- }
- }
-
- &.tabulator-group-level-3{
- td{
- padding-left:70px !important;
- }
- }
-
- &.tabulator-group-level-4{
- td{
- padding-left:90px !important;
- }
- }
-
- &.tabulator-group-level-5{
- td{
- padding-left:110px !important;
- }
- }
-
- .tabulator-group-toggle{
- display: inline-block;
- }
-
- //sorting arrow
- .tabulator-arrow{
- display: inline-block;
- width: 0;
- height: 0;
- margin-right:16px;
- border-top: 6px solid transparent;
- border-bottom: 6px solid transparent;
- border-right: 0;
- border-left: 6px solid $sortArrowActive;
- vertical-align:middle;
- }
-
- span{
- margin-left:10px;
- color:#d00;
- }
- }
-
- .tabulator-data-tree-control{
-
- display:inline-flex;
- justify-content:center;
- align-items:center;
- vertical-align:middle;
-
- height:11px;
- width:11px;
-
- margin-right:5px;
-
- border:1px solid $rowTextColor;
- border-radius:2px;
- background:rgba(0, 0, 0, .1);
-
- overflow:hidden;
-
- &:hover{
- cursor:pointer;
- background:rgba(0, 0, 0, .2);
- }
-
- .tabulator-data-tree-control-collapse{
- display:inline-block;
- position: relative;
-
- height: 7px;
- width: 1px;
-
- background: transparent;
-
- &:after {
- position: absolute;
- content: "";
- left: -3px;
- top: 3px;
-
- height: 1px;
- width: 7px;
-
- background: $rowTextColor;
- }
- }
-
- .tabulator-data-tree-control-expand{
- display:inline-block;
- position: relative;
-
- height: 7px;
- width: 1px;
-
- background: $rowTextColor;
-
- &:after {
- position: absolute;
- content: "";
- left: -3px;
- top: 3px;
-
- height: 1px;
- width: 7px;
-
- background: $rowTextColor;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/public/css/_ui.css b/public/css/_ui.css
index eed720809c..cdc6c437fa 100644
--- a/public/css/_ui.css
+++ b/public/css/_ui.css
@@ -1,192 +1,50 @@
-@import url('./_colours.css');
-
-@import url('./_button.css');
-
-@import url('./_drawer.css');
-
-@import url('./_dialog.css');
-
-@import url('./_font.css');
-
-@import url('./_icons.css');
-
-@import url('./_inputs.css');
-
-@import url('./_layerview.css');
-
-@import url('./_locationview.css');
-
-@import url('./_tabview.css');
-
-::-webkit-scrollbar {
- width: 7px;
- height: 7px;
- border-radius: 2px;
-}
-
-::-webkit-scrollbar-track {
- background: var(--color-primary-light);
- border-radius: 2px;
-}
-
-::-webkit-scrollbar-thumb {
- background: var(--color-primary);
- border-radius: 2px;
-}
-
-::-webkit-scrollbar-corner {
- background: transparent;
- border-radius: 2px;
-}
-
-.no-select {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-.flex-spacer {
- display: flex;
- align-items: center;
-
- &> :nth-child(2) {
- margin-left: auto;
- }
-}
-
-.link-with-img>* {
- height: 1.2em;
- line-height: 1.2em;
- display: inline-block;
- vertical-align: middle;
-}
-
-.link-with-img>button,
-.link-with-img>.mask-icon,
-.link-with-img>.bg-icon {
- width: 1.5em;
-}
-
-.dataview-mask {
- width: 100%;
- height: 100%;
- text-align: center;
- line-height: 2
-}
-
-.interface-mask {
- position: fixed;
- top: 0;
- width: 100%;
- height: 100%;
- z-index: 999999;
- background-color: #eeea;
-
- &>.bg-image {
- margin: 5%;
- height: 90%;
- width: 90%;
- background-repeat: no-repeat;
- background-size: contain;
- background-position: center;
-
- &>.btn-close {
- position: absolute;
- top: 5%;
- right: 5%;
- width: 50px;
- height: 50px;
- background-color: var(--color-no);
- }
- }
-}
-
-.flex-col {
- display: flex;
- flex-direction: column;
- gap: 5px;
-}
-
-.pill-container {
- display: flex;
- gap: 4px;
- flex-flow: row wrap;
- padding: 0.5em 0;
-}
-
-.pill-container .pill {
- cursor: default;
- padding: 1px 1px 1px 2px;
- border-radius: 2px;
- font-size: 0.9em;
- font-weight: bold;
- color: var(--color-light);
- background-color: var(--color-primary);
- user-select: none;
-}
-
-.pill-container .pill button {
- cursor: pointer;
- font-size: 0.8em;
- padding: 0 2px;
-}
-
-.mask-icon {
- background-color: var(--color-primary-light);
-
- &.on {
- background-color: var(--color-on);
- }
-
- &.no {
- background-color: var(--color-no);
- }
-}
-
-.primary-colour {
- color: var(--color-primary);
-}
-
-.primary-background {
- color: white;
- background-color: var(--color-primary);
-}
-
-.light-background {
- background-color: var(--color-light);
-}
-
-.lighter-background {
- background-color: var(--color-light-secondary);
-}
-
-.off-black {
- color: var(--color-off-black);
-}
-
-.off-black-background {
- color: white;
- background-color: var(--color-off-black);
-}
-
-.on-colour {
- color: var(--color-on);
-}
-
-.no-colour {
- color: var(--color-no);
-}
-
-.val-changed input {
- background-color: var(--color-changed)
-}
-
-.val-changed textarea {
- background-color: var(--color-changed)
-}
-
-.val-changed button {
- background-color: var(--color-changed)
-}
\ No newline at end of file
+@import url('./base/_colours.css');
+
+@import url('./base/_common.css');
+
+@import url('./base/_button.css');
+
+@import url('./base/_font.css');
+
+@import url('./base/_globals.css');
+
+@import url('./base/_icons.css');
+
+@import url('./base/_inputs.css');
+
+
+@import url('./elements/_alert_confirm.css');
+
+@import url('./elements/_btnPanel.css');
+
+@import url('./elements/_chkbox.css');
+
+@import url('./elements/_dialog.css');
+
+@import url('./elements/_drawer.css');
+
+@import url('./elements/_dropdown.css');
+
+@import url('./elements/_pills.css');
+
+@import url('./elements/_searchbox.css');
+
+@import url('./elements/_slider.css');
+
+
+@import url('./layout/_layerview.css');
+
+@import url('./layout/_locationview.css');
+
+@import url('./layout/_tabview.css');
+
+@import url('./layout/_toolbars.css');
+
+
+
+
+
+
+
+
+
diff --git a/public/css/base/_button.css b/public/css/base/_button.css
new file mode 100644
index 0000000000..f0627e7132
--- /dev/null
+++ b/public/css/base/_button.css
@@ -0,0 +1,64 @@
+button {
+ border: none;
+ outline: none;
+ background: none;
+ text-align: center;
+
+ &.mask-icon,
+ & >.mask-icon {
+ background-color: var(--color-primary)
+ }
+
+ &.mask-icon.active,
+ &.active>.mask-icon,
+ & >.mask-icon.active {
+ background-color: var(--color-on)
+ }
+
+ &:hover {
+ cursor: pointer;
+ }
+
+ &:disabled {
+ opacity: 0.3;
+ &:hover {
+ cursor: not-allowed;
+ }
+ }
+
+ &.wide {
+ width: 100%;
+ }
+
+ &.flat {
+ border-radius: 3px;
+ border-bottom: 1px solid var(--color-light-secondary);
+ padding: 0.3em;
+
+ &.active {
+ border-bottom: 3px solid var(--color-on);
+ }
+ }
+
+ &.underline {
+ display: none;
+ margin-bottom: 5px;
+ text-decoration: underline
+ }
+
+ &.raised {
+ border-radius: 3px;
+ border: 1px solid var(--color-light-secondary);
+ box-shadow: 1px 1px 2px var(--color-light-secondary);
+ padding: 0.3em;
+
+ &.active {
+ box-shadow: none;
+ }
+ }
+
+ &.active {
+ background-color: var(--color-on);
+ }
+}
+
diff --git a/public/css/base/_colours.css b/public/css/base/_colours.css
new file mode 100644
index 0000000000..cc3cb49104
--- /dev/null
+++ b/public/css/base/_colours.css
@@ -0,0 +1,58 @@
+:root {
+
+ --color-off-black: #3f3f3f;
+
+ --color-primary: #003D57;
+
+ --color-primary-light: #939faa;
+
+ --color-light: #ffffff;
+
+ --color-light-secondary: #f2f2f2;
+
+ --color-light-tertiary: #fafafa;
+
+ --color-mid: #e3e3e3;
+
+ --color-on: #E18335;
+
+ --color-no: #A21309;
+
+ --color-changed: #ffffa7;
+
+}
+
+
+.primary-colour {
+ color: var(--color-primary);
+}
+
+.primary-background {
+ color: white;
+ background-color: var(--color-primary);
+}
+
+.light-background {
+ background-color: var(--color-light);
+}
+
+.lighter-background {
+ background-color: var(--color-light-secondary);
+}
+
+.off-black {
+ color: var(--color-off-black);
+}
+
+.off-black-background {
+ color: white;
+ background-color: var(--color-off-black);
+}
+
+.on-colour {
+ color: var(--color-on);
+}
+
+.no-colour {
+ color: var(--color-no);
+}
\ No newline at end of file
diff --git a/public/css/base/_common.css b/public/css/base/_common.css
new file mode 100644
index 0000000000..add052ca64
--- /dev/null
+++ b/public/css/base/_common.css
@@ -0,0 +1,49 @@
+.display-none {
+ display: none !important;
+}
+
+.hover:hover {
+ cursor: pointer;
+}
+
+.box-shadow {
+ border: 1px solid #eee;
+ box-shadow: 2px 2px 4px var(--color-primary-light);
+}
+
+.bold {
+ font-weight: bold;
+}
+
+.no-select {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.link-with-img>* {
+ height: 1.2em;
+ line-height: 1.2em;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.link-with-img>button,
+.link-with-img>.mask-icon,
+.link-with-img>.bg-icon {
+ width: 1.5em;
+}
+
+.val-changed input {
+ background-color: var(--color-changed)
+ }
+
+.val-changed textarea {
+ background-color: var(--color-changed)
+}
+
+.val-changed button {
+ background-color: var(--color-changed)
+}
\ No newline at end of file
diff --git a/public/css/base/_font.css b/public/css/base/_font.css
new file mode 100644
index 0000000000..48635f8a66
--- /dev/null
+++ b/public/css/base/_font.css
@@ -0,0 +1,5 @@
+a.mask-icon,
+ a>.mask-icon {
+ background-color: var(--color-primary);
+ }
+
diff --git a/public/css/_font.css b/public/css/base/_globals.css
similarity index 62%
rename from public/css/_font.css
rename to public/css/base/_globals.css
index 808409e093..93cf5febd5 100644
--- a/public/css/_font.css
+++ b/public/css/base/_globals.css
@@ -6,15 +6,25 @@ body {
color: var(--color-off-black);
}
+*,
+*::after,
+*::before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ -o-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ border-spacing: 0;
+ font-family: inherit;
+ font-size: inherit;
+}
+
a {
text-decoration: none;
font-weight: bold;
color: var(--color-primary);
-
- &.mask-icon,
- &>.mask-icon {
- background-color: var(--color-primary);
- }
}
li {
@@ -36,6 +46,6 @@ h3 {
font-weight: 600;
}
-.bold {
- font-weight: bold;
-}
\ No newline at end of file
+a > img {
+ height: 100%;
+}
diff --git a/public/css/base/_icons.css b/public/css/base/_icons.css
new file mode 100644
index 0000000000..6455dfe38e
--- /dev/null
+++ b/public/css/base/_icons.css
@@ -0,0 +1,788 @@
+.bg-icon {
+ background-repeat: no-repeat;
+ background-size: contain;
+ -webkit-background-size: contain;
+
+ &.pos-center {
+ background-position: center;
+ }
+ &.pos-right {
+ background-position: right;
+ }
+ &.pos-left {
+ background-position: left;
+ }
+}
+
+.mask-icon {
+
+ background-color: var(--color-primary-light);
+
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-size: contain;
+
+ &.pos-center {
+ mask-position: center;
+ -webkit-mask-position: center;
+ }
+ &.pos-right {
+ mask-position: right;
+ -webkit-mask-position: right;
+ }
+ &.pos-left {
+ mask-position: left;
+ -webkit-mask-position: left;
+ }
+
+ &.on {
+ background-color: var(--color-on);
+ }
+
+ &.no {
+ background-color: var(--color-no);
+ }
+}
+
+.add {
+ &.bg-icon {
+ background-image: url("../../icons/icon-add.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-add.svg");
+ mask-image: url("../../icons/icon-add.svg");
+ }
+}
+
+.add-chart {
+ &.bg-icon {
+ background-image: url("../../icons/icon-add-chart.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-add-chart.svg");
+ mask-image: url("../../icons/icon-add-chart.svg");
+ }
+}
+
+.add-document {
+ &.bg-icon {
+ background-image: url("../../icons/icon-add-document.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-add-document.svg");
+ mask-image: url("../../icons/icon-add-document.svg");
+ }
+}
+
+.add-photo {
+ &.bg-icon {
+ background-image: url("../../icons/icon-add-photo.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-add-photo.svg");
+ mask-image: url("../../icons/icon-add-photo.svg");
+ }
+}
+
+.area {
+ &.bg-icon {
+ background-image: url("../../icons/icon-area.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-area.svg");
+ mask-image: url("../../icons/icon-area.svg");
+ }
+}
+
+.arrow-down {
+ &.bg-icon {
+ background-image: url("../../icons/icon-arrow-down.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-arrow-down.svg");
+ mask-image: url("../../icons/icon-arrow-down.svg");
+ }
+}
+
+.arrow-up {
+ &.bg-icon {
+ background-image: url("../../icons/icon-arrow-up.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-arrow-up.svg");
+ mask-image: url("../../icons/icon-arrow-up.svg");
+ }
+}
+
+.bar-chart {
+ &.bg-icon {
+ background-image: url("../../icons/icon-bar-chart.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-bar-chart.svg");
+ mask-image: url("../../icons/icon-bar-chart.svg");
+ }
+}
+
+.bubble-chart {
+ &.bg-icon {
+ background-image: url("../../icons/icon-bubble-chart.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-bubble-chart.svg");
+ mask-image: url("../../icons/icon-bubble-chart.svg");
+ }
+}
+
+.bug-report {
+ &.bg-icon {
+ background-image: url("../../icons/icon-bug-report.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-bug-report.svg");
+ mask-image: url("../../icons/icon-bug-report.svg");
+ }
+}
+
+.build {
+ &.bg-icon {
+ background-image: url("../../icons/icon-build.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-build.svg");
+ mask-image: url("../../icons/icon-build.svg");
+ }
+}
+
+.car {
+ &.bg-icon {
+ background-image: url("../../icons/icon-car.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-car.svg");
+ mask-image: url("../../icons/icon-car.svg");
+ }
+}
+
+.circle-dot {
+ &.bg-icon {
+ background-image: url("../../icons/icon-circle-dot.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-circle-dot.svg");
+ mask-image: url("../../icons/icon-circle-dot.svg");
+ }
+}
+
+.city {
+ &.bg-icon {
+ background-image: url("../../icons/icon-city.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-city.svg");
+ mask-image: url("../../icons/icon-city.svg");
+ }
+}
+
+.copy {
+ &.bg-icon {
+ background-image: url("../../icons/icon-copy.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-copy.svg");
+ mask-image: url("../../icons/icon-copy.svg");
+ }
+}
+
+.close {
+ &.bg-icon {
+ background-image: url("../../icons/icon-close.svg");
+
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-close.svg");
+ mask-image: url("../../icons/icon-close.svg");
+ }
+}
+
+.cloud-upload {
+ &.bg-icon {
+ background-image: url("../../icons/icon-cloud-upload.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-cloud-upload.svg");
+ mask-image: url("../../icons/icon-cloud-upload.svg");
+ }
+}
+
+.description {
+ &.bg-icon {
+ background-image: url("../../icons/icon-description.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-description.svg");
+ mask-image: url("../../icons/icon-description.svg");
+ }
+}
+
+.done {
+ &.bg-icon {
+ background-image: url("../../icons/icon-done.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-done.svg");
+ mask-image: url("../../icons/icon-done.svg");
+ }
+}
+
+.donut-small {
+ &.bg-icon {
+ background-image: url("../../icons/icon-donut-small.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-donut-small.svg");
+ mask-image: url("../../icons/icon-donut-small.svg");
+ }
+}
+
+.drop-down {
+ &.bg-icon {
+ background-image: url("../../icons/icon-drop-down.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-drop-down.svg");
+ mask-image: url("../../icons/icon-drop-down.svg");
+ }
+}
+
+.drop-up {
+ &.bg-icon {
+ background-image: url("../../icons/icon-drop-up.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-drop-up.svg");
+ mask-image: url("../../icons/icon-drop-up.svg");
+ }
+}
+
+.edit {
+ &.bg-icon {
+ background-image: url("../../icons/icon-edit.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-edit.svg");
+ mask-image: url("../../icons/icon-edit.svg");
+ }
+}
+
+.event-note {
+ &.bg-icon {
+ background-image: url("../../icons/icon-event-note.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-event-note.svg");
+ mask-image: url("../../icons/icon-event-note.svg");
+ }
+}
+
+.face {
+ &.bg-icon {
+ background-image: url("../../icons/icon-face.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-face.svg");
+ mask-image: url("../../icons/icon-face.svg");
+ }
+}
+
+.feature-info {
+ &.bg-icon {
+ background-image: url("../../icons/icon-feature-info.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-feature-info.svg");
+ mask-image: url("../../icons/icon-feature-info.svg");
+ }
+}
+
+.filter-list {
+ &.bg-icon {
+ background-image: url("../../icons/icon-filter-list.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-filter-list.svg");
+ mask-image: url("../../icons/icon-filter-list.svg");
+ }
+}
+
+.fullscreen {
+ &.bg-icon {
+ background-image: url("../../icons/icon-fullscreen.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-fullscreen.svg");
+ mask-image: url("../../icons/icon-fullscreen.svg");
+ }
+}
+
+.gps-not-fixed {
+ &.bg-icon {
+ background-image: url("../../icons/icon-gps_not_fixed.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-gps_not_fixed.svg");
+ mask-image: url("../../icons/icon-gps_not_fixed.svg");
+ }
+}
+
+.layers {
+ &.bg-icon {
+ background-image: url("../../icons/icon-layers.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-layers.svg");
+ mask-image: url("../../icons/icon-layers.svg");
+ }
+}
+
+.line {
+ &.bg-icon {
+ background-image: url("../../icons/icon-line.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-line.svg");
+ mask-image: url("../../icons/icon-line.svg");
+ }
+}
+
+.location {
+ &.bg-icon {
+ background-image: url("../../icons/icon-location.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-location.svg");
+ mask-image: url("../../icons/icon-location.svg");
+ }
+}
+
+.location-tick {
+ &.bg-icon {
+ background-image: url("../../icons/icon-location-tick.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-location-tick.svg");
+ mask-image: url("../../icons/icon-location-tick.svg");
+ }
+}
+
+.lock-closed {
+ &.bg-icon {
+ background-image: url("../../icons/icon-lock-closed.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-lock-closed.svg");
+ mask-image: url("../../icons/icon-lock-closed.svg");
+ }
+}
+
+.lock-open {
+ &.bg-icon {
+ background-image: url("../../icons/icon-lock-open.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-lock-open.svg");
+ mask-image: url("../../icons/icon-lock-open.svg");
+ }
+}
+
+.logout {
+ &.bg-icon {
+ background-image: url("../../icons/icon-logout.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-logout.svg");
+ mask-image: url("../../icons/icon-logout.svg");
+ }
+}
+
+.map {
+ &.bg-icon {
+ background-image: url("../../icons/icon-map.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-map.svg");
+ mask-image: url("../../icons/icon-map.svg");
+ }
+}
+
+.maps-ugc {
+ &.bg-icon {
+ background-image: url("../../icons/icon-maps-ugc.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-maps-ugc.svg");
+ mask-image: url("../../icons/icon-maps-ugc.svg");
+ }
+}
+
+.multiline-chart {
+ &.bg-icon {
+ background-image: url("../../icons/icon-multiline-chart.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-multiline-chart.svg");
+ mask-image: url("../../icons/icon-multiline-chart.svg");
+ }
+}
+
+.notes {
+ &.bg-icon {
+ background-image: url("../../icons/icon-notes.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-notes.svg");
+ mask-image: url("../../icons/icon-notes.svg");
+ }
+}
+
+.open-in-new {
+ &.bg-icon {
+ background-image: url("../../icons/icon-open-in-new.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-open-in-new.svg");
+ mask-image: url("../../icons/icon-open-in-new.svg");
+ }
+}
+
+.pageview {
+ &.bg-icon {
+ background-image: url("../../icons/icon-pageview.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-pageview.svg");
+ mask-image: url("../../icons/icon-pageview.svg");
+ }
+}
+
+.people {
+ &.bg-icon {
+ background-image: url("../../icons/icon-people.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-people.svg");
+ mask-image: url("../../icons/icon-people.svg");
+ }
+}
+
+.pie-chart {
+ &.bg-icon {
+ background-image: url("../../icons/icon-pie-chart.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-pie-chart.svg");
+ mask-image: url("../../icons/icon-pie-chart.svg");
+ }
+}
+
+.radio-button-checked {
+ &.bg-icon {
+ background-image: url("../../icons/icon-radio-button-checked.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-radio-button-checked.svg");
+ mask-image: url("../../icons/icon-radio-button-checked.svg");
+ }
+}
+
+.remove {
+ &.bg-icon {
+ background-image: url("../../icons/icon-remove.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-remove.svg");
+ mask-image: url("../../icons/icon-remove.svg");
+ }
+}
+
+.reply {
+ &.bg-icon {
+ background-image: url("../../icons/icon-reply.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-reply.svg");
+ mask-image: url("../../icons/icon-reply.svg");
+ }
+}
+
+.restore {
+ &.bg-icon {
+ background-image: url("../../icons/icon-restore.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-restore.svg");
+ mask-image: url("../../icons/icon-restore.svg");
+ }
+}
+
+.room {
+ &.bg-icon {
+ background-image: url("../../icons/icon-room.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-room.svg");
+ mask-image: url("../../icons/icon-room.svg");
+ }
+}
+
+.save {
+ &.bg-icon {
+ background-image: url("../../icons/icon-save.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-save.svg");
+ mask-image: url("../../icons/icon-save.svg");
+ }
+}
+
+.scatter-plot {
+ &.bg-icon {
+ background-image: url("../../icons/icon-scatter-plot.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-scatter-plot.svg");
+ mask-image: url("../../icons/icon-scatter-plot.svg");
+ }
+}
+
+.school {
+ &.bg-icon {
+ background-image: url("../../icons/icon-school.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-school.svg");
+ mask-image: url("../../icons/icon-school.svg");
+ }
+}
+
+.search {
+ &.bg-icon {
+ background-image: url("../../icons/icon-search.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-search.svg");
+ mask-image: url("../../icons/icon-search.svg");
+ }
+}
+
+.settings {
+ &.bg-icon {
+ background-image: url("../../icons/icon-settings.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-settings.svg");
+ mask-image: url("../../icons/icon-settings.svg");
+ }
+}
+
+.show-chart {
+ &.bg-icon {
+ background-image: url("../../icons/icon-show-chart.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-show-chart.svg");
+ mask-image: url("../../icons/icon-show-chart.svg");
+ }
+}
+
+.straighten {
+ &.bg-icon {
+ background-image: url("../../icons/icon-straighten.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-straighten.svg");
+ mask-image: url("../../icons/icon-straighten.svg");
+ }
+}
+
+.supervisor-account {
+ &.bg-icon {
+ background-image: url("../../icons/icon-supervisor-account.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-supervisor-account.svg");
+ mask-image: url("../../icons/icon-supervisor-account.svg");
+ }
+}
+
+.tick-done {
+ &.bg-icon {
+ background-image: url("../../icons/icon-tick-done.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-tick-done.svg");
+ mask-image: url("../../icons/icon-tick-done.svg");
+ }
+}
+
+.tick-done-all {
+ &.bg-icon {
+ background-image: url("../../icons/icon-tick-done-all.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-tick-done-all.svg");
+ mask-image: url("../../icons/icon-tick-done-all.svg");
+ }
+}
+
+.toggle {
+ &.bg-icon {
+ background-image: url("../../icons/icon-toggle-off.svg");
+ &.on {
+ background-image: url("../../icons/icon-toggle-on.svg");
+ }
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-toggle-off.svg");
+ mask-image: url("../../icons/icon-toggle-off.svg");
+ &.on {
+ -webkit-mask-image: url("../../icons/icon-toggle-on.svg");
+ mask-image: url("../../icons/icon-toggle-on.svg");
+ }
+ }
+ &.disabled {
+ opacity: 0.5;
+ pointer-events: none;
+ }
+}
+
+.touch-app {
+ &.bg-icon {
+ background-image: url("../../icons/icon-touch-app.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-touch-app.svg");
+ mask-image: url("../../icons/icon-touch-app.svg");
+ }
+}
+
+.translate {
+ &.bg-icon {
+ background-image: url("../../icons/icon-translate.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-translate.svg");
+ mask-image: url("../../icons/icon-translate.svg");
+ }
+}
+
+.trash {
+ &.bg-icon {
+ background-image: url("../../icons/icon-trash.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-trash.svg");
+ mask-image: url("../../icons/icon-trash.svg");
+ }
+}
+
+.vertical-align-bottom {
+ &.bg-icon {
+ background-image: url("../../icons/icon-vertical-align-bottom.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-vertical-align-bottom.svg");
+ mask-image: url("../../icons/icon-vertical-align-bottom.svg");
+ }
+}
+
+.vertical-align-top {
+ &.bg-icon {
+ background-image: url("../../icons/icon-vertical-align-top.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-vertical-align-top.svg");
+ mask-image: url("../../icons/icon-vertical-align-top.svg");
+ }
+}
+
+.view-list {
+ &.bg-icon {
+ background-image: url("../../icons/icon-view-list.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-view-list.svg");
+ mask-image: url("../../icons/icon-view-list.svg");
+ }
+}
+
+.visibility-off {
+ &.bg-icon {
+ background-image: url("../../icons/icon-visibility-off.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-visibility-off.svg");
+ mask-image: url("../../icons/icon-visibility-off.svg");
+ }
+}
+
+.warning {
+ &.bg-icon {
+ background-image: url("../../icons/icon-warning.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-warning.svg");
+ mask-image: url("../../icons/icon-warning.svg");
+ }
+}
+
+.wysiwyg {
+ &.bg-icon {
+ background-image: url("../../icons/icon-wysiwyg.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-wysiwyg.svg");
+ mask-image: url("../../icons/icon-wysiwyg.svg");
+ }
+}
+
+.info {
+ &.bg-icon {
+ background-image: url("../../icons/icon-info.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-info.svg");
+ mask-image: url("../../icons/icon-info.svg");
+ }
+}
+
+.question-mark {
+ &.bg-icon {
+ background-image: url("../../icons/icon-question-mark.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-question-mark.svg");
+ mask-image: url("../../icons/icon-question-mark.svg");
+ }
+}
+
+.lightbulb {
+ &.bg-icon {
+ background-image: url("../../icons/icon-lightbulb.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-lightbulb.svg");
+ mask-image: url("../../icons/icon-lightbulb.svg");
+ }
+}
+
+.info-report {
+ &.bg-icon {
+ background-image: url("../../icons/icon-info-report.svg");
+ }
+ &.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-info-report.svg");
+ mask-image: url("../../icons/icon-info-report.svg");
+ }
+}
\ No newline at end of file
diff --git a/public/css/base/_inputs.css b/public/css/base/_inputs.css
new file mode 100644
index 0000000000..4a7a65aa7f
--- /dev/null
+++ b/public/css/base/_inputs.css
@@ -0,0 +1,83 @@
+input {
+ width: 100%;
+
+ &:focus {
+ outline: none;
+ }
+}
+
+input.invalid {
+ opacity: 0.5;
+ outline: 1px solid var(--color-no);
+}
+
+input::placeholder {
+ text-align: left;
+}
+
+input::-moz-focus-inner,
+input::-moz-focus-outer {
+ border: 0;
+}
+
+textarea {
+ width: 100%;
+ resize: none;
+ border: none;
+ border-bottom: 0.5px dotted;
+ background-color: var(--color-light-secondary);
+}
+
+input[type=number] {
+ -moz-appearance: textfield;
+ appearance: textfield;
+ text-align: right;
+}
+
+input[type=number]::-webkit-inner-spin-button,
+input[type=number]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+input[type=search],
+input[type=date],
+input[type=time],
+input[type=datetime-local] {
+ border: 1px solid #ccc;
+ padding: 5px;
+
+ &:focus {
+ cursor: text;
+ }
+}
+
+input[type=text],
+input[type=number] {
+ padding: 5px;
+ border: none;
+ background-color: var(--color-light-secondary);
+ border-bottom: 0.5px dotted;
+ display: inline-block;
+ width: 100%;
+ min-width: 2.4ch;
+
+ &:focus {
+ cursor: text;
+ }
+}
+
+input[type=search]:focus+ul,
+input[type=search]+ul:active {
+ display: block;
+}
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration:hover,
+input[type="search"]::-webkit-search-cancel-button:hover {
+ cursor: pointer;
+}
+
+
+
+
diff --git a/public/css/elements/_alert_confirm.css b/public/css/elements/_alert_confirm.css
new file mode 100644
index 0000000000..ee683f849f
--- /dev/null
+++ b/public/css/elements/_alert_confirm.css
@@ -0,0 +1,54 @@
+dialog.alert-confirm {
+ width: 350px;
+ max-height: 70%;
+ z-index: 1001;
+ user-select: none;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+
+ &:focus {
+ outline: none;
+ }
+
+ h4 {
+ padding: 0.5em 1em;
+ background-color: var(--color-primary);
+ border-bottom: solid 2px var(--color-primary-light);
+ color: var(--color-light)
+ }
+
+ .content {
+ padding: 1em;
+ }
+
+ p {
+ white-space: pre;
+ text-wrap: pretty;
+ text-align: center;
+ padding: 1em;
+ }
+
+ .buttons {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ grid-gap: 0.2em
+ }
+
+ button {
+ float: right;
+ font-size: 0.9em;
+ color: var(--color-primary);
+ z-index: 1005;
+ }
+}
+
+
+@media only screen and (max-width: 768px) {
+
+ dialog.alert-confirm {
+ min-width: 350px;
+ max-width: 70%;
+ }
+}
\ No newline at end of file
diff --git a/public/css/elements/_btnPanel.css b/public/css/elements/_btnPanel.css
new file mode 100644
index 0000000000..62c44fcf69
--- /dev/null
+++ b/public/css/elements/_btnPanel.css
@@ -0,0 +1,79 @@
+.btn-panel {
+ width: 100%;
+ padding: 0.3em 0.5em;
+ background-color: white;
+ border: 1px solid var(--color-light-secondary);
+ border-radius: 3px;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+
+ & .header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ overflow: hidden;
+ pointer-events: none;
+
+ & h3 {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+ }
+
+ & .mask-icon {
+ width: 1.5em;
+ height: 1.5em;
+ -webkit-mask-position: right;
+ mask-position: right;
+ }
+
+ & .panel {
+ display: block;
+ position: absolute;
+ width: 100%;
+ bottom: 15em;
+ left: 0;
+ right: 0;
+ z-index: 99;
+ color: black;
+ background: white;
+ overflow: hidden;
+ padding: 1em 1.5em;
+ opacity: 0;
+ border-radius: 3px;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ pointer-events: none;
+ transition: 0.2s ease-in-out;
+
+ & .content {
+ padding: 1em;
+ }
+
+ &::after {
+ content: initial;
+ }
+ }
+
+ &.active {
+ background-color: var(--color-primary);
+ color: #fff;
+
+ & .mask-icon {
+ background-color: #fff;
+ }
+
+ & .panel {
+ bottom: 2em;
+ pointer-events: auto;
+ opacity: 1;
+ }
+
+ &.downward .panel {
+ bottom: -7em;
+ /* places adjacent to the bottom border of parent */
+ }
+ }
+
+ &.downward .panel {
+ bottom: -15em;
+ }
+}
\ No newline at end of file
diff --git a/public/css/elements/_chkbox.css b/public/css/elements/_chkbox.css
new file mode 100644
index 0000000000..760af286eb
--- /dev/null
+++ b/public/css/elements/_chkbox.css
@@ -0,0 +1,51 @@
+label.checkbox {
+ display: block;
+
+ &.disabled {
+ opacity: 0.3;
+ pointer-events: none;
+ }
+
+ &.inline {
+ display: inline-block;
+ }
+
+ &>span {
+ vertical-align: middle;
+ }
+
+ &.inline+span {
+ vertical-align: middle;
+ }
+
+ &>input {
+ display: none;
+ }
+
+ &>div {
+ display: inline-block;
+ vertical-align: middle;
+ height: 1em;
+ min-height: 12px;
+ width: 1em;
+ min-width: 12px;
+ margin-right: 0.5em;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ -webkit-background-size: contain;
+ background-image: url("../../icons/icon-checkbox-unchecked.svg");
+ }
+
+ &>div:hover {
+ cursor: pointer;
+ }
+
+ & input:checked+div {
+ background-image: url("../../icons/icon-checkbox-checked.svg");
+ }
+
+ & input:disabled~* {
+ opacity: 0.4;
+ }
+ }
\ No newline at end of file
diff --git a/public/css/elements/_dialog.css b/public/css/elements/_dialog.css
new file mode 100644
index 0000000000..8142e478da
--- /dev/null
+++ b/public/css/elements/_dialog.css
@@ -0,0 +1,80 @@
+.headerDrag {
+ cursor: grab;
+}
+
+
+dialog {
+
+ &>button.close {
+ position: absolute;
+ top: 0em;
+ right: 0em;
+ height: 1em;
+ width: 1em;
+ margin: 0.4em;
+
+ }
+
+ &>header {
+ display: flex;
+ justify-content: space-between;
+
+ &>:nth-child(2) {
+ margin-left: auto;
+ }
+ }
+
+ &.dialog {
+ position: absolute;
+ border: none !important;
+ border-radius: 2px;
+ cursor: grab;
+ user-select: none;
+ padding: 5px;
+ overflow: unset !important;
+ isolation: isolate;
+ }
+
+ &.modal {
+ position: fixed;
+ border: none !important;
+ border-radius: 2px;
+ text-wrap: wrap;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 9999;
+ }
+
+ header {
+ & button {
+ height: 1em;
+ width: 1em;
+ margin: 0.4em;
+ }
+ }
+
+ .minimize-btn.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-remove.svg");
+ mask-image: url("../../icons/icon-remove.svg");
+ }
+
+ &.minimized {
+
+ .content {
+ display: none;
+ }
+
+ .minimize-btn.mask-icon {
+ -webkit-mask-image: url("../../icons/icon-fullscreen.svg");
+ mask-image: url("../../icons/icon-fullscreen.svg");
+ }
+
+ }
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/public/css/_drawer.css b/public/css/elements/_drawer.css
similarity index 86%
rename from public/css/_drawer.css
rename to public/css/elements/_drawer.css
index 6a3708e3c3..5e339a5647 100644
--- a/public/css/_drawer.css
+++ b/public/css/elements/_drawer.css
@@ -16,8 +16,8 @@
}
&.expandable>.header>.mask-icon.expander {
- -webkit-mask-image: url("../icons/icon-arrow-down.svg");
- mask-image: url("../icons/icon-arrow-down.svg");
+ -webkit-mask-image: url("../../icons/icon-arrow-down.svg");
+ mask-image: url("../../icons/icon-arrow-down.svg");
}
&.expandable:not(.expanded)>*:not(.header) {
@@ -25,8 +25,8 @@
}
&.expanded>.header>.mask-icon.expander {
- -webkit-mask-image: url("../icons/icon-arrow-up.svg");
- mask-image: url("../icons/icon-arrow-up.svg");
+ -webkit-mask-image: url("../../icons/icon-arrow-up.svg");
+ mask-image: url("../../icons/icon-arrow-up.svg");
}
&.disabled {
diff --git a/public/css/elements/_dropdown.css b/public/css/elements/_dropdown.css
new file mode 100644
index 0000000000..771008b77f
--- /dev/null
+++ b/public/css/elements/_dropdown.css
@@ -0,0 +1,91 @@
+.dropdown {
+ width: 100%;
+ overflow: visible;
+ position: relative;
+ background-color: white;
+ box-shadow: var(--color-mid) 0px 8px 24px;
+
+ &:disabled {
+ pointer-events: none;
+ opacity: 0.4;
+ }
+
+ &>.head {
+ padding: 5px;
+ display: flex;
+ align-items: center;
+
+ &>:first-child {
+ pointer-events: none;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
+ &>.icon {
+ pointer-events: none;
+ margin-left: auto;
+ width: 1.5em;
+ content: url("../../icons/icon-drop-down.svg");
+ }
+ }
+
+ &>ul {
+ display: none;
+ position: absolute;
+ max-height: 500px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ margin-top: -1px;
+ text-align: left;
+ background-color: white;
+ z-index: 997;
+
+ &>li {
+ padding: 5px;
+ }
+
+ &>li:hover {
+ background-color: var(--color-primary-light);
+ cursor: pointer;
+ }
+
+ &>li.selected {
+ background-color: var(--color-light-secondary);
+ }
+
+ & .label {
+ padding: 0 6px;
+ border-radius: 2px;
+ color: var(--color-light);
+ font-size: 80%;
+ font-weight: bold;
+ background-color: var(--color-primary);
+ }
+ }
+
+ &.active>ul {
+ display: block;
+
+ &>.head>.icon {
+ content: url("../../icons/icon-drop-up.svg");
+ }
+ }
+
+ &.dropdown-reverse>ul {
+ bottom: 30px;
+ }
+ }
+
+
+ @media print {
+ .dropdown {
+ box-shadow: none;
+
+ &>.head>.icon {
+ display: none;
+ }
+ }
+
+ }
\ No newline at end of file
diff --git a/public/css/elements/_pills.css b/public/css/elements/_pills.css
new file mode 100644
index 0000000000..2c40678b67
--- /dev/null
+++ b/public/css/elements/_pills.css
@@ -0,0 +1,27 @@
+.pill-container {
+ display: flex;
+ gap: 4px;
+ flex-flow: row wrap;
+ padding: 0.5em 0;
+
+ .pill {
+
+ cursor: default;
+ padding: 1px 1px 1px 2px;
+ border-radius: 2px;
+ font-size: 0.9em;
+ font-weight: bold;
+ color: var(--color-light);
+ background-color: var(--color-primary);
+ user-select: none;
+
+ button {
+
+ cursor: pointer;
+ font-size: 0.8em;
+ padding: 0 2px;
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/public/css/elements/_searchbox.css b/public/css/elements/_searchbox.css
new file mode 100644
index 0000000000..429b2a149e
--- /dev/null
+++ b/public/css/elements/_searchbox.css
@@ -0,0 +1,47 @@
+.searchbox {
+ width: 100%;
+ overflow: visible;
+ position: relative;
+ background-color: white;
+ box-shadow: var(--color-mid) 0px 8px 24px;
+
+ &>ul {
+ display: none;
+ max-height: 500px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ margin-top: -1px;
+ text-align: left;
+ background-color: white;
+ z-index: 999;
+
+ &>li {
+ padding: 5px;
+ }
+
+ &>li:hover {
+ background-color: var(--color-primary-light);
+ cursor: pointer;
+ }
+
+ &>li.selected {
+ background-color: var(--color-light-secondary);
+ }
+
+ & .label {
+ padding: 0 6px;
+ border-radius: 2px;
+ color: var(--color-light);
+ font-size: 80%;
+ font-weight: bold;
+ background-color: var(--color-primary);
+ }
+ }
+ }
+
+ @media print {
+ .searchbox {
+ box-shadow: none;
+ }
+ }
\ No newline at end of file
diff --git a/public/css/elements/_slider.css b/public/css/elements/_slider.css
new file mode 100644
index 0000000000..a376b0cc18
--- /dev/null
+++ b/public/css/elements/_slider.css
@@ -0,0 +1,123 @@
+
+.input-range {
+ --dif: calc(var(--max) - var(--min));
+ display: grid;
+ grid-template-columns: 50% 50%;
+ position: relative;
+ width: 100%;
+
+ & .label-row {
+ grid-row: 1;
+ grid-column: 1/3;
+ }
+
+ & .track-bg {
+ grid-row: 2;
+ grid-column: 1/3;
+ background: linear-gradient(0deg, transparent 0 45%, var(--color-primary-light) 45% 55%, transparent 55% 100%);
+ z-index: 1;
+ }
+
+ &.single::after {
+ grid-column: 1/3;
+ grid-row: 2;
+ background: linear-gradient(0deg, transparent 0 45%, var(--color-primary) 45% 55%, transparent 55% 100%);
+ content: '';
+ z-index: 2;
+ width: calc((var(--a) - var(--min)) / var(--dif) * (100% - 10px));
+ }
+
+ &.multi {
+ &>.label-row {
+ display: flex;
+ justify-content: space-between;
+
+ &>div {
+ flex-grow: 1
+ }
+ }
+
+ &::before,
+ &::after {
+ grid-column: 1/3;
+ grid-row: 2;
+ background: linear-gradient(0deg, transparent 0 45%, var(--color-primary) 45% 55%, transparent 55% 100%);
+ content: '';
+ z-index: 2;
+ }
+
+ &::before {
+ margin-left: calc(10px + (var(--a) - var(--min)) / var(--dif) * (100% - 10px));
+ width: calc((var(--b) - var(--a)) / var(--dif) * (100% - 10px));
+ }
+
+ &::after {
+ margin-left: calc(10px + (var(--b) - var(--min)) / var(--dif) * (100% - 10px));
+ width: calc((var(--a) - var(--b)) / var(--dif) * (100% - 10px));
+ }
+ }
+
+ & input[type='range'] {
+ -webkit-appearance: none;
+ appearance: none;
+ grid-column: 1/3;
+ grid-row: 2;
+ z-index: 3;
+ top: 0;
+ left: 0;
+ margin: 0;
+ background: none;
+ /* get rid of white Chrome background */
+ pointer-events: none;
+ }
+
+ &.disabled {
+ opacity: 0.5;
+ pointer-events: none;
+ }
+ }
+
+ .input-range input[type='range']::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 100%;
+ background: none;
+ /* get rid of Firefox track background */
+ }
+
+ .input-range input[type='range']::-moz-range-track {
+ width: 100%;
+ height: 100%;
+ background: none;
+ /* get rid of Firefox track background */
+ }
+
+ .input-range input[type='range']::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ border: none;
+ /* get rid of Firefox thumb border */
+ width: 20px;
+ height: 40px;
+ border-radius: 0;
+ /* get rid of Firefox corner rounding */
+ pointer-events: auto;
+ cursor: pointer;
+ background: url("../../icons/thumb.svg");
+ background-repeat: no-repeat;
+ background-position: center;
+ box-shadow: none;
+ }
+
+ .input-range input[type='range']::-moz-range-thumb {
+ border: none;
+ /* get rid of Firefox thumb border */
+ width: 20px;
+ height: 40px;
+ border-radius: 0;
+ /* get rid of Firefox corner rounding */
+ pointer-events: auto;
+ cursor: pointer;
+ background: url("../../icons/thumb.svg");
+ background-repeat: no-repeat;
+ background-position: center;
+ box-shadow: none;
+ }
\ No newline at end of file
diff --git a/public/css/layout/_infotip.css b/public/css/layout/_infotip.css
new file mode 100644
index 0000000000..034bd44779
--- /dev/null
+++ b/public/css/layout/_infotip.css
@@ -0,0 +1,11 @@
+.infotip {
+ position: fixed;
+ z-index: 998;
+ margin: 0;
+ padding: 5px;
+ background-color: white;
+ opacity: 0;
+ transition-property: opacity;
+ transition-duration: 0.3s;
+ transition-delay: 0.2s;
+}
diff --git a/public/css/_layerview.css b/public/css/layout/_layerview.css
similarity index 100%
rename from public/css/_layerview.css
rename to public/css/layout/_layerview.css
diff --git a/public/css/layout/_legend.css b/public/css/layout/_legend.css
new file mode 100644
index 0000000000..0a0b24424d
--- /dev/null
+++ b/public/css/layout/_legend.css
@@ -0,0 +1,78 @@
+.legend {
+ & .contents-wrapper,
+ &.content .contents-wrapper {
+ margin-top: 0.5em;
+ gap: 0.5em;
+
+ & > .contents {
+ display: contents;
+ }
+
+ &.label {
+ grid-column: 2;
+ }
+
+ &.flex {
+ display: flex;
+ flex-wrap: wrap;
+ flex-grow: 1;
+ justify-content: start;
+
+ & .contents {
+ display: block;
+ flex-basis: 30%;
+ flex-shrink: 1;
+
+ &.center {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ margin-bottom: 1em;
+ text-align: center;
+ }
+
+ &.row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 1em;
+ }
+
+ &.horizontal {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ flex-basis: auto;
+ flex-grow: 1;
+ }
+ }
+
+ &.nowrap {
+ flex-wrap: nowrap;
+
+ & .contents {
+ justify-content: flex-start;
+
+ & .label {
+ text-align: center;
+ }
+ }
+ }
+ }
+
+ &.grid {
+ display: grid;
+ grid-template-columns: min-content;
+ align-items: center;
+ justify-content: start;
+ }
+ }
+
+ & .switch {
+ cursor: pointer;
+ }
+
+ & .switch.disabled {
+ opacity: 0.5;
+ }
+}
diff --git a/public/css/_locationview.css b/public/css/layout/_locationview.css
similarity index 95%
rename from public/css/_locationview.css
rename to public/css/layout/_locationview.css
index 59ef07759f..fdb420c2e6 100644
--- a/public/css/_locationview.css
+++ b/public/css/layout/_locationview.css
@@ -139,4 +139,13 @@
width: 100%;
height: 180px;
}
+}
+
+.flex-spacer {
+ display: flex;
+ align-items: center;
+
+ &> :nth-child(2) {
+ margin-left: auto;
+ }
}
\ No newline at end of file
diff --git a/public/css/layout/_map_attribution.css b/public/css/layout/_map_attribution.css
new file mode 100644
index 0000000000..a18e0cef13
--- /dev/null
+++ b/public/css/layout/_map_attribution.css
@@ -0,0 +1,33 @@
+body {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+.map-attribution {
+ position: absolute;
+ display: flex;
+ justify-content: space-between;
+ align-items: end;
+ bottom: 0;
+ right: 0;
+ width: 100%;
+ padding: 5px;
+ pointer-events: none;
+ user-select: none;
+
+ .attribution-links {
+ text-align: right;
+ font-size: 95%;
+
+ & a {
+ pointer-events: auto;
+ margin-left: 5px;
+ display: inline-block;
+ white-space: nowrap;
+ line-height: 1;
+ background: #fff9;
+ border-bottom: 2px solid var(--color-primary-light);
+ }
+ }
+}
diff --git a/public/css/layout/_ol.css b/public/css/layout/_ol.css
new file mode 100644
index 0000000000..b2855eae91
--- /dev/null
+++ b/public/css/layout/_ol.css
@@ -0,0 +1,57 @@
+.ol-scale-line {
+ position: static;
+ background: none;
+}
+
+.ol-scale-line-inner {
+ border: 2px solid #222;
+ border-top: none;
+ color: #222;
+ text-align: center;
+ margin: 1px;
+ will-change: contents, width
+}
+
+.ol-unselectable,
+.ol-viewport {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.ol-zoom {
+ top: 0.5em;
+ left: 0.5em;
+
+ & .ol-zoom-in,
+ & .ol-zoom-out {
+ border-radius: 2px 2px 0 0;
+ }
+}
+
+.ol-control {
+ position: absolute;
+ background-color: rgba(255, 255, 255, .4);
+ border-radius: 4px;
+ padding: 2px;
+
+ & button {
+ display: block;
+ margin: 1px;
+ padding: 0;
+ color: #fff;
+ font-weight: 700;
+ text-decoration: none;
+ font-size: inherit;
+ text-align: center;
+ height: 1.375em;
+ width: 1.375em;
+ line-height: .4em;
+ background-color: rgba(0, 60, 136, .5);
+ border: none;
+ border-radius: 2px;
+ }
+}
\ No newline at end of file
diff --git a/public/css/layout/_popup.css b/public/css/layout/_popup.css
new file mode 100644
index 0000000000..52a978e270
--- /dev/null
+++ b/public/css/layout/_popup.css
@@ -0,0 +1,39 @@
+.popup {
+ position: absolute;
+ background-color: white;
+ bottom: 12px;
+ transform: translate(-50%, 0);
+
+ &::after,
+ &::before {
+ border: solid transparent;
+ content: ' ';
+ position: absolute;
+ pointer-events: none;
+ }
+
+ &::after {
+ border-top-color: white;
+ border-width: 10px;
+ left: 50%;
+ margin-left: -10px;
+ }
+
+ & li {
+ padding: 5px 10px;
+ white-space: nowrap;
+ line-height: 1.5;
+ list-style-type: none;
+ }
+
+ & li:hover {
+ background: var(--color-light-secondary);
+ cursor: pointer;
+ }
+
+ .list {
+ max-width: 66vw;
+ max-height: 300px;
+ overflow-x: hidden;
+ }
+}
diff --git a/public/css/_tabview.css b/public/css/layout/_tabview.css
similarity index 100%
rename from public/css/_tabview.css
rename to public/css/layout/_tabview.css
diff --git a/public/css/layout/_toolbars.css b/public/css/layout/_toolbars.css
new file mode 100644
index 0000000000..39346520e1
--- /dev/null
+++ b/public/css/layout/_toolbars.css
@@ -0,0 +1,63 @@
+.btn-column {
+ display: grid;
+ grid-auto-rows: minmax(min-content, 4em);
+ padding: 0.7em;
+
+ & button,
+ &>div,
+ &>a {
+ width: 2em;
+ height: 2em;
+ }
+
+ & a>div,
+ & button>div {
+ height: 100%;
+ }
+
+ & button:disabled,
+ & a:disabled {
+ cursor: not-allowed;
+ }
+}
+
+.btn-row {
+ display: flex;
+
+ &>* {
+ margin: 10px 5px;
+ }
+}
+
+.flex-col {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+}
+
+.interface-mask {
+ position: fixed;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 999999;
+ background-color: #eeea;
+
+ &>.bg-image {
+ margin: 5%;
+ height: 90%;
+ width: 90%;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+
+ &>.btn-close {
+ position: absolute;
+ top: 5%;
+ right: 5%;
+ width: 50px;
+ height: 50px;
+ background-color: var(--color-no);
+ }
+ }
+ }
\ No newline at end of file
diff --git a/public/css/mapp.css b/public/css/mapp.css
index e66a286e94..516f6e186e 100644
--- a/public/css/mapp.css
+++ b/public/css/mapp.css
@@ -1,4 +1,4 @@
-/* public/css/_colours.css */
+/* public/css/base/_colours.css */
:root {
--color-off-black: #3f3f3f;
--color-primary: #003D57;
@@ -11,37 +11,34 @@
--color-no: #A21309;
--color-changed: #ffffa7;
}
-
-/* public/css/_mapp.css */
-*,
-*::after,
-*::before {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- -o-box-sizing: border-box;
- box-sizing: border-box;
- margin: 0;
- padding: 0;
- border-spacing: 0;
- font-family: inherit;
- font-size: inherit;
+.primary-colour {
+ color: var(--color-primary);
}
-body {
- position: absolute;
- width: 100%;
- height: 100%;
+.primary-background {
+ color: white;
+ background-color: var(--color-primary);
}
-.display-none {
- display: none !important;
+.light-background {
+ background-color: var(--color-light);
}
-.hover:hover {
- cursor: pointer;
+.lighter-background {
+ background-color: var(--color-light-secondary);
}
-.box-shadow {
- border: 1px solid #eee;
- box-shadow: 2px 2px 4px var(--color-primary-light);
+.off-black {
+ color: var(--color-off-black);
}
+.off-black-background {
+ color: white;
+ background-color: var(--color-off-black);
+}
+.on-colour {
+ color: var(--color-on);
+}
+.no-colour {
+ color: var(--color-no);
+}
+
+/* public/css/layout/_ol.css */
.ol-scale-line {
position: static;
background: none;
@@ -93,52 +90,11 @@ body {
border-radius: 2px;
}
}
-.infotip {
- position: fixed;
- z-index: 998;
- margin: 0;
- padding: 5px;
- background-color: white;
- opacity: 0;
- transition-property: opacity;
- transition-duration: 0.3s;
- transition-delay: 0.2s;
-}
-.popup {
+
+/* public/css/layout/_map_attribution.css */
+body {
position: absolute;
- background-color: white;
- bottom: 12px;
- transform: translate(-50%, 0);
- &::after,
- &::before {
- border: solid transparent;
- content: " ";
- position: absolute;
- pointer-events: none;
- }
- &::after {
- border-top-color: white;
- border-width: 10px;
- left: 50%;
- margin-left: -10px;
- }
- & li {
- padding: 5px 10px;
- white-space: nowrap;
- line-height: 1.5;
- list-style-type: none;
- }
- & li:hover {
- background: var(--color-light-secondary);
- cursor: pointer;
- }
- .list {
- max-width: 66vw;
- max-height: 300px;
- overflow-x: hidden;
- }
-}
-a > img {
+ width: 100%;
height: 100%;
}
.map-attribution {
@@ -152,20 +108,22 @@ a > img {
padding: 5px;
pointer-events: none;
user-select: none;
-}
-.attribution-links {
- text-align: right;
- font-size: 95%;
- & a {
- pointer-events: auto;
- margin-left: 5px;
- display: inline-block;
- white-space: nowrap;
- line-height: 1;
- background: #fff9;
- border-bottom: 2px solid var(--color-primary-light);
+ .attribution-links {
+ text-align: right;
+ font-size: 95%;
+ & a {
+ pointer-events: auto;
+ margin-left: 5px;
+ display: inline-block;
+ white-space: nowrap;
+ line-height: 1;
+ background: #fff9;
+ border-bottom: 2px solid var(--color-primary-light);
+ }
}
}
+
+/* public/css/layout/_legend.css */
.legend {
& .contents-wrapper,
&.content .contents-wrapper {
@@ -231,3 +189,54 @@ a > img {
opacity: 0.5;
}
}
+
+/* public/css/layout/_infotip.css */
+.infotip {
+ position: fixed;
+ z-index: 998;
+ margin: 0;
+ padding: 5px;
+ background-color: white;
+ opacity: 0;
+ transition-property: opacity;
+ transition-duration: 0.3s;
+ transition-delay: 0.2s;
+}
+
+/* public/css/layout/_popup.css */
+.popup {
+ position: absolute;
+ background-color: white;
+ bottom: 12px;
+ transform: translate(-50%, 0);
+ &::after,
+ &::before {
+ border: solid transparent;
+ content: " ";
+ position: absolute;
+ pointer-events: none;
+ }
+ &::after {
+ border-top-color: white;
+ border-width: 10px;
+ left: 50%;
+ margin-left: -10px;
+ }
+ & li {
+ padding: 5px 10px;
+ white-space: nowrap;
+ line-height: 1.5;
+ list-style-type: none;
+ }
+ & li:hover {
+ background: var(--color-light-secondary);
+ cursor: pointer;
+ }
+ .list {
+ max-width: 66vw;
+ max-height: 300px;
+ overflow-x: hidden;
+ }
+}
+
+/* public/css/_mapp.css */
diff --git a/public/css/ui.css b/public/css/ui.css
index 68c6520876..1da042b0b7 100644
--- a/public/css/ui.css
+++ b/public/css/ui.css
@@ -1,6 +1,6 @@
@import "https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,300;0,400;0,600;1,200;1,300&display=swap";
-/* public/css/_colours.css */
+/* public/css/base/_colours.css */
:root {
--color-off-black: #3f3f3f;
--color-primary: #003D57;
@@ -13,8 +13,76 @@
--color-no: #A21309;
--color-changed: #ffffa7;
}
+.primary-colour {
+ color: var(--color-primary);
+}
+.primary-background {
+ color: white;
+ background-color: var(--color-primary);
+}
+.light-background {
+ background-color: var(--color-light);
+}
+.lighter-background {
+ background-color: var(--color-light-secondary);
+}
+.off-black {
+ color: var(--color-off-black);
+}
+.off-black-background {
+ color: white;
+ background-color: var(--color-off-black);
+}
+.on-colour {
+ color: var(--color-on);
+}
+.no-colour {
+ color: var(--color-no);
+}
-/* public/css/_button.css */
+/* public/css/base/_common.css */
+.display-none {
+ display: none !important;
+}
+.hover:hover {
+ cursor: pointer;
+}
+.box-shadow {
+ border: 1px solid #eee;
+ box-shadow: 2px 2px 4px var(--color-primary-light);
+}
+.bold {
+ font-weight: bold;
+}
+.no-select {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.link-with-img > * {
+ height: 1.2em;
+ line-height: 1.2em;
+ display: inline-block;
+ vertical-align: middle;
+}
+.link-with-img > button,
+.link-with-img > .mask-icon,
+.link-with-img > .bg-icon {
+ width: 1.5em;
+}
+.val-changed input {
+ background-color: var(--color-changed);
+}
+.val-changed textarea {
+ background-color: var(--color-changed);
+}
+.val-changed button {
+ background-color: var(--color-changed);
+}
+
+/* public/css/base/_button.css */
button {
border: none;
outline: none;
@@ -67,292 +135,37 @@ button {
background-color: var(--color-on);
}
}
-.btn-column {
- display: grid;
- grid-auto-rows: minmax(min-content, 4em);
- padding: 0.7em;
- & button,
- & > div,
- & > a {
- width: 2em;
- height: 2em;
- }
- & a > div,
- & button > div {
- height: 100%;
- }
- & button:disabled,
- & a:disabled {
- cursor: not-allowed;
- }
-}
-.btn-row {
- display: flex;
- & > * {
- margin: 10px 5px;
- }
-}
-.btn-panel {
- width: 100%;
- padding: 0.3em 0.5em;
- background-color: white;
- border: 1px solid var(--color-light-secondary);
- border-radius: 3px;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- & .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- overflow: hidden;
- pointer-events: none;
- & h3 {
- text-overflow: ellipsis;
- overflow: hidden;
- }
- }
- & .mask-icon {
- width: 1.5em;
- height: 1.5em;
- -webkit-mask-position: right;
- mask-position: right;
- }
- & .panel {
- display: block;
- position: absolute;
- width: 100%;
- bottom: 15em;
- left: 0;
- right: 0;
- z-index: 99;
- color: black;
- background: white;
- overflow: hidden;
- padding: 1em 1.5em;
- opacity: 0;
- border-radius: 3px;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- pointer-events: none;
- transition: 0.2s ease-in-out;
- & .content {
- padding: 1em;
- }
- &::after {
- content: initial;
- }
- }
- &.active {
- background-color: var(--color-primary);
- color: #fff;
- & .mask-icon {
- background-color: #fff;
- }
- & .panel {
- bottom: 2em;
- pointer-events: auto;
- opacity: 1;
- }
- &.downward .panel {
- bottom: -7em;
- }
- }
- &.downward .panel {
- bottom: -15em;
- }
-}
-
-/* public/css/_drawer.css */
-.disabled > .drawer {
- opacity: 0.4;
- pointer-events: none;
-}
-.drawer {
- padding: 5px;
- background-color: var(--color-light-tertiary);
- &.expandable:not(.empty) > .header:hover {
- cursor: pointer;
- }
- &.expandable.empty > .header > .mask-icon.expander {
- display: none;
- }
- &.expandable > .header > .mask-icon.expander {
- -webkit-mask-image: url('data:image/svg+xml,');
- mask-image: url('data:image/svg+xml,');
- }
- &.expandable:not(.expanded) > *:not(.header) {
- display: none;
- }
- &.expanded > .header > .mask-icon.expander {
- -webkit-mask-image: url('data:image/svg+xml,');
- mask-image: url('data:image/svg+xml,');
- }
- &.disabled {
- opacity: 0.4;
- pointer-events: none;
- }
- & > .header {
- display: flex;
- align-items: center;
- & > :not(button):not(label):not(input) {
- pointer-events: none;
- }
- & > div,
- & > button {
- margin-left: 5px;
- width: 1.5em;
- height: 1.5em;
- }
- & > :nth-child(1) {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
- & > :nth-child(2) {
- margin-left: auto;
- }
- & > .mask-icon {
- mask-position: right;
- -webkit-mask-position: right;
- }
- }
- &.flat {
- border-radius: 2px;
- border: 1px solid var(--color-light-secondary);
- }
- &.raised {
- border-radius: 2px;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- border: 1px solid var(--color-light-secondary);
- }
- &.raised.empty {
- box-shadow: none;
- border: none;
- }
- &.expandable.expanded {
- box-shadow: none;
- border: none;
- }
- p {
- padding-left: 0.3em;
- padding-right: 0.3em;
- }
-}
-/* public/css/_dialog.css */
-.headerDrag {
- cursor: grab;
-}
-dialog > button.close {
- position: absolute;
- top: 0em;
- right: 0em;
- height: 1em;
- width: 1em;
- margin: 0.4em;
-}
-dialog.dialog {
- position: absolute;
- border: none !important;
- border-radius: 2px;
- cursor: grab;
- user-select: none;
- padding: 5px;
- overflow: unset !important;
- isolation: isolate;
-}
-dialog.modal {
- position: fixed;
- border: none !important;
- border-radius: 2px;
- text-wrap: wrap;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- z-index: 9999;
-}
-header {
- & button {
- height: 1em;
- width: 1em;
- margin: 0.4em;
- }
-}
-.dialog > header {
- display: flex;
- justify-content: space-between;
- & > :nth-child(2) {
- margin-left: auto;
- }
-}
-dialog.alert-confirm {
- width: 350px;
- max-height: 70%;
- z-index: 1001;
- user-select: none;
-}
-dialog.alert-confirm::-webkit-scrollbar {
- display: none;
-}
-dialog.alert-confirm:focus {
- outline: none;
-}
-dialog.alert-confirm h4 {
- padding: 0.5em 1em;
+/* public/css/base/_font.css */
+a.mask-icon,
+a > .mask-icon {
background-color: var(--color-primary);
- border-bottom: solid 2px var(--color-primary-light);
- color: var(--color-light);
-}
-dialog.alert-confirm .content {
- padding: 1em;
-}
-dialog.alert-confirm p {
- white-space: pre;
- text-wrap: pretty;
- text-align: center;
- padding: 1em;
-}
-dialog.alert-confirm .buttons {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- grid-gap: 0.2em;
-}
-dialog.alert-confirm button {
- float: right;
- font-size: 0.9em;
- color: var(--color-primary);
- z-index: 1005;
-}
-dialog.minimized .content {
- display: none;
-}
-dialog .minimize-btn.mask-icon {
- -webkit-mask-image: url('data:image/svg+xml,');
- mask-image: url('data:image/svg+xml,');
-}
-dialog.minimized .minimize-btn.mask-icon {
- -webkit-mask-image: url('data:image/svg+xml,');
- mask-image: url('data:image/svg+xml,');
-}
-@media only screen and (max-width: 768px) {
- dialog.alert-confirm {
- min-width: 350px;
- max-width: 70%;
- }
}
-/* public/css/_font.css */
+/* public/css/base/_globals.css */
body {
font-family: "Titillium Web", sans-serif;
font-size: 0.8em;
color: var(--color-off-black);
}
+*,
+*::after,
+*::before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ -o-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ border-spacing: 0;
+ font-family: inherit;
+ font-size: inherit;
+}
a {
text-decoration: none;
font-weight: bold;
color: var(--color-primary);
- &.mask-icon,
- & > .mask-icon {
- background-color: var(--color-primary);
- }
}
li {
list-style-type: none;
@@ -369,11 +182,11 @@ h3 {
font-size: 105%;
font-weight: 600;
}
-.bold {
- font-weight: bold;
+a > img {
+ height: 100%;
}
-/* public/css/_icons.css */
+/* public/css/base/_icons.css */
.bg-icon {
background-repeat: no-repeat;
background-size: contain;
@@ -389,6 +202,7 @@ h3 {
}
}
.mask-icon {
+ background-color: var(--color-primary-light);
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
@@ -405,6 +219,12 @@ h3 {
mask-position: left;
-webkit-mask-position: left;
}
+ &.on {
+ background-color: var(--color-on);
+ }
+ &.no {
+ background-color: var(--color-no);
+ }
}
.add {
&.bg-icon {
@@ -1075,7 +895,7 @@ h3 {
}
}
-/* public/css/_inputs.css */
+/* public/css/base/_inputs.css */
input {
width: 100%;
&:focus {
@@ -1102,6 +922,7 @@ textarea {
}
input[type=number] {
-moz-appearance: textfield;
+ appearance: textfield;
text-align: right;
}
input[type=number]::-webkit-inner-spin-button,
@@ -1141,6 +962,123 @@ input[type=search]::-webkit-search-decoration:hover,
input[type=search]::-webkit-search-cancel-button:hover {
cursor: pointer;
}
+
+/* public/css/elements/_alert_confirm.css */
+dialog.alert-confirm {
+ width: 350px;
+ max-height: 70%;
+ z-index: 1001;
+ user-select: none;
+ &::-webkit-scrollbar {
+ display: none;
+ }
+ &:focus {
+ outline: none;
+ }
+ h4 {
+ padding: 0.5em 1em;
+ background-color: var(--color-primary);
+ border-bottom: solid 2px var(--color-primary-light);
+ color: var(--color-light);
+ }
+ .content {
+ padding: 1em;
+ }
+ p {
+ white-space: pre;
+ text-wrap: pretty;
+ text-align: center;
+ padding: 1em;
+ }
+ .buttons {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ grid-gap: 0.2em;
+ }
+ button {
+ float: right;
+ font-size: 0.9em;
+ color: var(--color-primary);
+ z-index: 1005;
+ }
+}
+@media only screen and (max-width: 768px) {
+ dialog.alert-confirm {
+ min-width: 350px;
+ max-width: 70%;
+ }
+}
+
+/* public/css/elements/_btnPanel.css */
+.btn-panel {
+ width: 100%;
+ padding: 0.3em 0.5em;
+ background-color: white;
+ border: 1px solid var(--color-light-secondary);
+ border-radius: 3px;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ & .header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ overflow: hidden;
+ pointer-events: none;
+ & h3 {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ }
+ }
+ & .mask-icon {
+ width: 1.5em;
+ height: 1.5em;
+ -webkit-mask-position: right;
+ mask-position: right;
+ }
+ & .panel {
+ display: block;
+ position: absolute;
+ width: 100%;
+ bottom: 15em;
+ left: 0;
+ right: 0;
+ z-index: 99;
+ color: black;
+ background: white;
+ overflow: hidden;
+ padding: 1em 1.5em;
+ opacity: 0;
+ border-radius: 3px;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ pointer-events: none;
+ transition: 0.2s ease-in-out;
+ & .content {
+ padding: 1em;
+ }
+ &::after {
+ content: initial;
+ }
+ }
+ &.active {
+ background-color: var(--color-primary);
+ color: #fff;
+ & .mask-icon {
+ background-color: #fff;
+ }
+ & .panel {
+ bottom: 2em;
+ pointer-events: auto;
+ opacity: 1;
+ }
+ &.downward .panel {
+ bottom: -7em;
+ }
+ }
+ &.downward .panel {
+ bottom: -15em;
+ }
+}
+
+/* public/css/elements/_chkbox.css */
label.checkbox {
display: block;
&.disabled {
@@ -1179,46 +1117,151 @@ label.checkbox {
& input:checked + div {
background-image: url('data:image/svg+xml,%0A');
}
- & input:disabled ~ * {
+ & input:disabled ~ * {
+ opacity: 0.4;
+ }
+}
+
+/* public/css/elements/_dialog.css */
+.headerDrag {
+ cursor: grab;
+}
+dialog {
+ & > button.close {
+ position: absolute;
+ top: 0em;
+ right: 0em;
+ height: 1em;
+ width: 1em;
+ margin: 0.4em;
+ }
+ & > header {
+ display: flex;
+ justify-content: space-between;
+ & > :nth-child(2) {
+ margin-left: auto;
+ }
+ }
+ &.dialog {
+ position: absolute;
+ border: none !important;
+ border-radius: 2px;
+ cursor: grab;
+ user-select: none;
+ padding: 5px;
+ overflow: unset !important;
+ isolation: isolate;
+ }
+ &.modal {
+ position: fixed;
+ border: none !important;
+ border-radius: 2px;
+ text-wrap: wrap;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 9999;
+ }
+ header {
+ & button {
+ height: 1em;
+ width: 1em;
+ margin: 0.4em;
+ }
+ }
+ .minimize-btn.mask-icon {
+ -webkit-mask-image: url('data:image/svg+xml,');
+ mask-image: url('data:image/svg+xml,');
+ }
+ &.minimized {
+ .content {
+ display: none;
+ }
+ .minimize-btn.mask-icon {
+ -webkit-mask-image: url('data:image/svg+xml,');
+ mask-image: url('data:image/svg+xml,');
+ }
+ }
+}
+
+/* public/css/elements/_drawer.css */
+.disabled > .drawer {
+ opacity: 0.4;
+ pointer-events: none;
+}
+.drawer {
+ padding: 5px;
+ background-color: var(--color-light-tertiary);
+ &.expandable:not(.empty) > .header:hover {
+ cursor: pointer;
+ }
+ &.expandable.empty > .header > .mask-icon.expander {
+ display: none;
+ }
+ &.expandable > .header > .mask-icon.expander {
+ -webkit-mask-image: url('data:image/svg+xml,');
+ mask-image: url('data:image/svg+xml,');
+ }
+ &.expandable:not(.expanded) > *:not(.header) {
+ display: none;
+ }
+ &.expanded > .header > .mask-icon.expander {
+ -webkit-mask-image: url('data:image/svg+xml,');
+ mask-image: url('data:image/svg+xml,');
+ }
+ &.disabled {
opacity: 0.4;
+ pointer-events: none;
}
-}
-.searchbox {
- width: 100%;
- overflow: visible;
- position: relative;
- background-color: white;
- box-shadow: var(--color-mid) 0px 8px 24px;
- & > ul {
- display: none;
- max-height: 500px;
- overflow-y: auto;
- overflow-x: hidden;
- box-shadow: 1px 1px 3px var(--color-primary-light);
- margin-top: -1px;
- text-align: left;
- background-color: white;
- z-index: 999;
- & > li {
- padding: 5px;
+ & > .header {
+ display: flex;
+ align-items: center;
+ & > :not(button):not(label):not(input) {
+ pointer-events: none;
}
- & > li:hover {
- background-color: var(--color-primary-light);
- cursor: pointer;
+ & > div,
+ & > button {
+ margin-left: 5px;
+ width: 1.5em;
+ height: 1.5em;
}
- & > li.selected {
- background-color: var(--color-light-secondary);
+ & > :nth-child(1) {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
}
- & .label {
- padding: 0 6px;
- border-radius: 2px;
- color: var(--color-light);
- font-size: 80%;
- font-weight: bold;
- background-color: var(--color-primary);
+ & > :nth-child(2) {
+ margin-left: auto;
+ }
+ & > .mask-icon {
+ mask-position: right;
+ -webkit-mask-position: right;
}
}
+ &.flat {
+ border-radius: 2px;
+ border: 1px solid var(--color-light-secondary);
+ }
+ &.raised {
+ border-radius: 2px;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ border: 1px solid var(--color-light-secondary);
+ }
+ &.raised.empty {
+ box-shadow: none;
+ border: none;
+ }
+ &.expandable.expanded {
+ box-shadow: none;
+ border: none;
+ }
+ p {
+ padding-left: 0.3em;
+ padding-right: 0.3em;
+ }
}
+
+/* public/css/elements/_dropdown.css */
.dropdown {
width: 100%;
overflow: visible;
@@ -1293,10 +1336,75 @@ label.checkbox {
display: none;
}
}
+}
+
+/* public/css/elements/_pills.css */
+.pill-container {
+ display: flex;
+ gap: 4px;
+ flex-flow: row wrap;
+ padding: 0.5em 0;
+ .pill {
+ cursor: default;
+ padding: 1px 1px 1px 2px;
+ border-radius: 2px;
+ font-size: 0.9em;
+ font-weight: bold;
+ color: var(--color-light);
+ background-color: var(--color-primary);
+ user-select: none;
+ button {
+ cursor: pointer;
+ font-size: 0.8em;
+ padding: 0 2px;
+ }
+ }
+}
+
+/* public/css/elements/_searchbox.css */
+.searchbox {
+ width: 100%;
+ overflow: visible;
+ position: relative;
+ background-color: white;
+ box-shadow: var(--color-mid) 0px 8px 24px;
+ & > ul {
+ display: none;
+ max-height: 500px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ box-shadow: 1px 1px 3px var(--color-primary-light);
+ margin-top: -1px;
+ text-align: left;
+ background-color: white;
+ z-index: 999;
+ & > li {
+ padding: 5px;
+ }
+ & > li:hover {
+ background-color: var(--color-primary-light);
+ cursor: pointer;
+ }
+ & > li.selected {
+ background-color: var(--color-light-secondary);
+ }
+ & .label {
+ padding: 0 6px;
+ border-radius: 2px;
+ color: var(--color-light);
+ font-size: 80%;
+ font-weight: bold;
+ background-color: var(--color-primary);
+ }
+ }
+}
+@media print {
.searchbox {
box-shadow: none;
}
}
+
+/* public/css/elements/_slider.css */
.input-range {
--dif: calc(var(--max) - var(--min));
display: grid;
@@ -1363,6 +1471,7 @@ label.checkbox {
}
& input[type=range] {
-webkit-appearance: none;
+ appearance: none;
grid-column: 1/3;
grid-row: 2;
z-index: 3;
@@ -1413,7 +1522,7 @@ label.checkbox {
box-shadow: none;
}
-/* public/css/_layerview.css */
+/* public/css/layout/_layerview.css */
.drawer.layer-group,
.drawer.layer-view {
margin-top: 7px;
@@ -1469,7 +1578,7 @@ label.checkbox {
background: var(--color-light);
}
-/* public/css/_locationview.css */
+/* public/css/layout/_locationview.css */
.location-view.drawer {
margin-top: 5px;
border-radius: 5px;
@@ -1589,8 +1698,15 @@ label.checkbox {
height: 180px;
}
}
+.flex-spacer {
+ display: flex;
+ align-items: center;
+ & > :nth-child(2) {
+ margin-left: auto;
+ }
+}
-/* public/css/_tabview.css */
+/* public/css/layout/_tabview.css */
.tabview {
width: 100%;
height: 100%;
@@ -1656,54 +1772,36 @@ label.checkbox {
}
}
-/* public/css/_ui.css */
-::-webkit-scrollbar {
- width: 7px;
- height: 7px;
- border-radius: 2px;
-}
-::-webkit-scrollbar-track {
- background: var(--color-primary-light);
- border-radius: 2px;
-}
-::-webkit-scrollbar-thumb {
- background: var(--color-primary);
- border-radius: 2px;
-}
-::-webkit-scrollbar-corner {
- background: transparent;
- border-radius: 2px;
-}
-.no-select {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+/* public/css/layout/_toolbars.css */
+.btn-column {
+ display: grid;
+ grid-auto-rows: minmax(min-content, 4em);
+ padding: 0.7em;
+ & button,
+ & > div,
+ & > a {
+ width: 2em;
+ height: 2em;
+ }
+ & a > div,
+ & button > div {
+ height: 100%;
+ }
+ & button:disabled,
+ & a:disabled {
+ cursor: not-allowed;
+ }
}
-.flex-spacer {
+.btn-row {
display: flex;
- align-items: center;
- & > :nth-child(2) {
- margin-left: auto;
+ & > * {
+ margin: 10px 5px;
}
}
-.link-with-img > * {
- height: 1.2em;
- line-height: 1.2em;
- display: inline-block;
- vertical-align: middle;
-}
-.link-with-img > button,
-.link-with-img > .mask-icon,
-.link-with-img > .bg-icon {
- width: 1.5em;
-}
-.dataview-mask {
- width: 100%;
- height: 100%;
- text-align: center;
- line-height: 2;
+.flex-col {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
}
.interface-mask {
position: fixed;
@@ -1729,73 +1827,5 @@ label.checkbox {
}
}
}
-.flex-col {
- display: flex;
- flex-direction: column;
- gap: 5px;
-}
-.pill-container {
- display: flex;
- gap: 4px;
- flex-flow: row wrap;
- padding: 0.5em 0;
-}
-.pill-container .pill {
- cursor: default;
- padding: 1px 1px 1px 2px;
- border-radius: 2px;
- font-size: 0.9em;
- font-weight: bold;
- color: var(--color-light);
- background-color: var(--color-primary);
- user-select: none;
-}
-.pill-container .pill button {
- cursor: pointer;
- font-size: 0.8em;
- padding: 0 2px;
-}
-.mask-icon {
- background-color: var(--color-primary-light);
- &.on {
- background-color: var(--color-on);
- }
- &.no {
- background-color: var(--color-no);
- }
-}
-.primary-colour {
- color: var(--color-primary);
-}
-.primary-background {
- color: white;
- background-color: var(--color-primary);
-}
-.light-background {
- background-color: var(--color-light);
-}
-.lighter-background {
- background-color: var(--color-light-secondary);
-}
-.off-black {
- color: var(--color-off-black);
-}
-.off-black-background {
- color: white;
- background-color: var(--color-off-black);
-}
-.on-colour {
- color: var(--color-on);
-}
-.no-colour {
- color: var(--color-no);
-}
-.val-changed input {
- background-color: var(--color-changed);
-}
-.val-changed textarea {
- background-color: var(--color-changed);
-}
-.val-changed button {
- background-color: var(--color-changed);
-}
+
+/* public/css/_ui.css */
diff --git a/tests/lib/ui/Dataview.test.mjs b/tests/lib/ui/Dataview.test.mjs
new file mode 100644
index 0000000000..1618656d48
--- /dev/null
+++ b/tests/lib/ui/Dataview.test.mjs
@@ -0,0 +1,51 @@
+import { mockLocation } from '../../utils/location.js';
+/**
+ * ## lib.ui.Dataview
+ * @module ui/Dataview
+ */
+/**
+ * This function is used to test the Dataview method
+ * @function DataviewTest
+*/
+export async function DataviewTest(mapview) {
+ await codi.describe('UI: Dataview', async () => {
+ // Get the mocked location
+ const location = await mockLocation(mapview);
+ // Get the entry of type dataview
+ const entry = location.infoj.find(entry => entry.type === 'dataview');
+
+ await codi.it('dataview should have a show method', async () => {
+
+ codi.assertTrue(entry.show instanceof Function, 'The dataview entry has a show method.');
+
+ });
+
+ await codi.it('dataview btnRow should be display none initially', async () => {
+
+ codi.assertEqual(entry.btnRow.style.display, 'none', 'The dataview entry btnRow should be display none.');
+
+ });
+
+ await codi.it('dataview should have a hide method', async () => {
+
+ codi.assertTrue(entry.hide instanceof Function, 'The dataview entry has a hide method.');
+ });
+
+ await codi.it('dataview btnRow should be display true when show method called', async () => {
+
+ entry.show();
+ codi.assertEqual(entry.btnRow.style.display, 'flex', 'The dataview entry btnRow should be display flex.');
+
+ });
+
+ await codi.it('dataview btnRow should be display none when hide method called', async () => {
+
+ entry.hide();
+ codi.assertEqual(entry.btnRow.style.display, 'none', 'The dataview entry btnRow should be display none.');
+
+ });
+
+ // Remove the mocked location
+ location.remove();
+ });
+}
\ No newline at end of file