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,%0A %0A'); - mask-image: url('data:image/svg+xml,%0A %0A'); - } - &.expandable:not(.expanded) > *:not(.header) { - display: none; - } - &.expanded > .header > .mask-icon.expander { - -webkit-mask-image: url('data:image/svg+xml,%0A %0A'); - mask-image: url('data:image/svg+xml,%0A %0A'); - } - &.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,%0A%0A'); - mask-image: url('data:image/svg+xml,%0A%0A'); -} -dialog.minimized .minimize-btn.mask-icon { - -webkit-mask-image: url('data:image/svg+xml,%0A%0A'); - mask-image: url('data:image/svg+xml,%0A%0A'); -} -@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 %0A%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,%0A%0A'); + mask-image: url('data:image/svg+xml,%0A%0A'); + } + &.minimized { + .content { + display: none; + } + .minimize-btn.mask-icon { + -webkit-mask-image: url('data:image/svg+xml,%0A%0A'); + mask-image: url('data:image/svg+xml,%0A%0A'); + } + } +} + +/* 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,%0A %0A'); + mask-image: url('data:image/svg+xml,%0A %0A'); + } + &.expandable:not(.expanded) > *:not(.header) { + display: none; + } + &.expanded > .header > .mask-icon.expander { + -webkit-mask-image: url('data:image/svg+xml,%0A %0A'); + mask-image: url('data:image/svg+xml,%0A %0A'); + } + &.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