diff --git a/docs/pages/Tools/Draw/Draw.md b/docs/pages/Tools/Draw/Draw.md
index a4c8e238..8921623d 100644
--- a/docs/pages/Tools/Draw/Draw.md
+++ b/docs/pages/Tools/Draw/Draw.md
@@ -86,8 +86,13 @@ There are five files that are group editable with the correct permission. The gr
"default": "No"
},
{
- "type": "date",
+ "type": "incrementer",
"field": "g",
+ "default": "ID-#"
+ },
+ {
+ "type": "date",
+ "field": "h",
"format": "YYYY-MM-DDTHH:mm:ss",
"default": "2000-01-01T00:00:00" // Can be "NOW", "STARTTIME" or "ENDTIME" too for dynamic defaults
}
@@ -95,7 +100,7 @@ There are five files that are group editable with the correct permission. The gr
"example_2": [
{
"type": "checkbox",
- "field": "h",
+ "field": "i",
"default": false
}
]
diff --git a/src/essence/Ancillary/Coordinates.js b/src/essence/Ancillary/Coordinates.js
index e6b3d586..1f79af53 100644
--- a/src/essence/Ancillary/Coordinates.js
+++ b/src/essence/Ancillary/Coordinates.js
@@ -775,9 +775,10 @@ function urlClick(e) {
}
function toggleTimeUI() {
- const active = $(this).hasClass('active')
- $(this).toggleClass('active')
+ const active = $('#toggleTimeUI').hasClass('active')
+ $('#toggleTimeUI').toggleClass('active')
$('#timeUI').toggleClass('active')
+
const newBottom = active ? 0 : 40
const timeBottom = active ? -40 : 0
diff --git a/src/essence/Tools/Draw/DrawTool.js b/src/essence/Tools/Draw/DrawTool.js
index ccdc1f2a..25e6fa12 100644
--- a/src/essence/Tools/Draw/DrawTool.js
+++ b/src/essence/Tools/Draw/DrawTool.js
@@ -5,6 +5,7 @@ import DrawTool_History from './DrawTool_History'
import DrawTool_Publish from './DrawTool_Publish'
import DrawTool_Shapes from './DrawTool_Shapes'
import DrawTool_FileModal from './DrawTool_FileModal'
+import DrawTool_Templater from './DrawTool_Templater'
import $ from 'jquery'
import * as d3 from 'd3'
@@ -1077,6 +1078,19 @@ var DrawTool = {
)
},
addDrawing: function (body, callback, failure) {
+ // Add template property defaults
+ const file = DrawTool.getFileObjectWithId(body.file_id)
+ if (file?.template?.template && body?.properties) {
+ let newProps = JSON.parse(body.properties)
+ const templateDefaults = DrawTool_Templater.getTemplateDefaults(
+ file?.template?.template,
+ L_.layers.layer[`DrawTool_${body.file_id}`]
+ )
+
+ newProps = { ...newProps, ...templateDefaults }
+ body.properties = JSON.stringify(newProps)
+ }
+
if (body.file_id == null) {
CursorInfo.update(
'No file chosen. Please select or make a file for drawings.',
diff --git a/src/essence/Tools/Draw/DrawTool_Editing.js b/src/essence/Tools/Draw/DrawTool_Editing.js
index bcacc877..bcd1b4ea 100644
--- a/src/essence/Tools/Draw/DrawTool_Editing.js
+++ b/src/essence/Tools/Draw/DrawTool_Editing.js
@@ -2350,7 +2350,10 @@ var Editing = {
if (DrawTool.plugins?.Geologic?.custom?.resetGeologic)
DrawTool.plugins.Geologic.custom.resetGeologic()
- const templaterProperties = templater.getValues()
+ const templaterProperties = templater.getValues(
+ L_.layers.layer[DrawTool.lastContextLayerIndexFileId.layer],
+ properties
+ )
if (templaterProperties === false) return
if (!grouping) {
diff --git a/src/essence/Tools/Draw/DrawTool_Templater.css b/src/essence/Tools/Draw/DrawTool_Templater.css
index 619573dc..7b983b2c 100644
--- a/src/essence/Tools/Draw/DrawTool_Templater.css
+++ b/src/essence/Tools/Draw/DrawTool_Templater.css
@@ -276,3 +276,6 @@
.drawToolTemplaterLiBody_dropdown_default input[type='number'] {
width: 90px !important;
}
+.drawToolTemplaterLiBody_incrementer_default {
+ width: 100%;
+}
diff --git a/src/essence/Tools/Draw/DrawTool_Templater.js b/src/essence/Tools/Draw/DrawTool_Templater.js
index a7e5e66e..e98db8d2 100644
--- a/src/essence/Tools/Draw/DrawTool_Templater.js
+++ b/src/essence/Tools/Draw/DrawTool_Templater.js
@@ -23,6 +23,7 @@ const DrawTool_Templater = {
template.map((t, idx) => {
if( properties[t.field] != null) {
+ t._default = t.default
t.default = properties[t.field]
}
// prettier-ignore
@@ -92,6 +93,15 @@ const DrawTool_Templater = {
``,
``
].join('\n')
+ case 'incrementer':
+ return [
+ `
`,
+ `${t.field}:
`,
+ ``,
+ ``
+ ].join('\n')
default:
return null
}
@@ -211,9 +221,10 @@ const DrawTool_Templater = {
})
return {
- getValues: () => {
+ getValues: (layer, existingProperties) => {
const values = {}
const invalids = {}
+
template.forEach((t, idx) => {
switch (t.type) {
case 'checkbox':
@@ -341,6 +352,24 @@ const DrawTool_Templater = {
if (values[t.field] === 'Invalid Date')
values[t.field] = null
break
+ case 'incrementer':
+ values[t.field] = $(
+ `#${containerId} #drawToolTemplater_${idx} input`
+ ).val()
+
+ const nextIncrement =
+ DrawTool_Templater._getNextIncrement(
+ values[t.field],
+ t,
+ layer,
+ existingProperties
+ )
+
+ if (nextIncrement.error != null)
+ invalids[t.field] = nextIncrement.error
+ else values[t.field] = nextIncrement.newValue
+
+ break
default:
break
}
@@ -413,12 +442,85 @@ const DrawTool_Templater = {
)
return removedOffset
},
+
+ /**
+ *
+ * @param {*} value
+ * @param {*} t
+ * @param {*} layer
+ * @returns {newValue: Number, error: String}
+ */
+ _getNextIncrement(value, t, layer, existingProperties) {
+ const response = {
+ newValue: value,
+ error: null,
+ }
+
+ let usedValues = []
+ const split = (t._default || t.default).split('#')
+ const start = split[0]
+ const end = split[1]
+ for (var i = 0; i < layer.length; i++) {
+ if (layer[i] == null) continue
+ let geojson =
+ layer[i].feature ||
+ layer[i]._layers[Object.keys(layer[i]._layers)[0]].feature
+ if (geojson?.properties?.[t.field] != null) {
+ let featuresVal = geojson?.properties?.[t.field]
+
+ featuresVal = featuresVal.replace(start, '').replace(end, '')
+
+ if (featuresVal !== '#') {
+ featuresVal = parseInt(featuresVal)
+ usedValues.push(featuresVal)
+ }
+ }
+ }
+ if ((response.newValue || '').indexOf('#') !== -1) {
+ // Actually increment the incrementer for the first time
+ let bestVal = 0
+ usedValues.sort(function (a, b) {
+ return a - b
+ })
+ usedValues = [...new Set(usedValues)] // makes it unique
+ usedValues.forEach((v) => {
+ if (bestVal === v) bestVal++
+ })
+ response.newValue = response.newValue.replace('#', bestVal)
+ } else if (existingProperties) {
+ let numVal = response.newValue.replace(start, '').replace(end, '')
+ if (numVal != '#') {
+ numVal = parseInt(numVal)
+ if (existingProperties[t.field] === response.newValue) {
+ // In case of a resave, make sure the id exists only once
+ let count = 0
+ usedValues.forEach((v) => {
+ if (numVal === v) count++
+ })
+ if (count > 1)
+ response.error = `Incrementing field: '${t.field}' is not unique`
+ } else {
+ // In case a manual change, make sure the id is unique
+ if (usedValues.indexOf(numVal) !== -1)
+ response.error = `Incrementing field: '${t.field}' is not unique`
+ }
+ }
+ }
+
+ // Check that the field still matches the surrounding string
+ const incRegex = new RegExp(`^${start}\\d+${end}$`)
+ if (incRegex.test(response.newValue) == false) {
+ response.error = `Incrementing field: '${t.field}' must follow syntax: '${start}{#}${end}'`
+ }
+ return response
+ },
_templateInDesignIdx: 0,
_templateInDesign: {},
_TEMPLATE_TYPES: [
'checkbox',
'date',
'dropdown',
+ 'incrementer',
'number',
'slider',
'text',
@@ -697,6 +799,17 @@ const DrawTool_Templater = {
""
]
break
+ case 'incrementer':
+ // prettier-ignore
+ typeMarkup = [
+ ``,
+ `
`,
+ `
Value with a single '#' to place an incrementing number:
`,
+ `
`,
+ "
",
+ "
"
+ ]
+ break
default:
break
}
@@ -788,6 +901,7 @@ const DrawTool_Templater = {
).val()
const items = []
+ const invalids = {}
$(`#${containerId} #drawToolTemplaterDesignContent > li`).each(
function () {
const item = {}
@@ -919,6 +1033,21 @@ const DrawTool_Templater = {
)
.prop('checked')
break
+ case 'incrementer':
+ item.default = $(this)
+ .find(
+ '.drawToolTemplaterLiBody_incrementer_default input'
+ )
+ .val()
+
+ if (
+ ((item.default || '').match(/#/g) || []).length != 1
+ ) {
+ invalids[
+ item.field
+ ] = `'${item.field}' must contain exactly one '#' symbol`
+ }
+ break
default:
break
}
@@ -963,6 +1092,7 @@ const DrawTool_Templater = {
return false
}
}
+
for (let i = 0; i < template.template.length; i++) {
const t = template.template[i]
if (t.field == null || t.field == '') {
@@ -993,7 +1123,7 @@ const DrawTool_Templater = {
} catch (error) {
// no good
CursorInfo.update(
- `Template cannot contain invalid reges: ${t.regex}`,
+ `Template cannot contain invalid regex: ${t.regex}`,
6000,
true,
{ x: 305, y: 6 },
@@ -1003,6 +1133,17 @@ const DrawTool_Templater = {
return false
}
}
+ if (invalids[t.field] != null) {
+ CursorInfo.update(
+ `Template field: ${invalids[t.field]}`,
+ 6000,
+ true,
+ { x: 305, y: 6 },
+ '#e9ff26',
+ 'black'
+ )
+ return false
+ }
}
return template
},
@@ -1072,6 +1213,45 @@ const DrawTool_Templater = {
}
return true
},
+ getTemplateDefaults: function (template, layer) {
+ const defaultProps = {}
+
+ template.forEach((t, idx) => {
+ if (t.field != null && t.default != null && t.default != '') {
+ let f = t.field
+ let v = t.default
+ switch (t.type) {
+ case 'incrementer':
+ const nextIncrement =
+ DrawTool_Templater._getNextIncrement(
+ t.default,
+ t,
+ layer
+ )
+ v = nextIncrement.newValue
+ break
+ case 'date':
+ if (v === 'NOW')
+ v = moment
+ .utc(new Date().getTime())
+ .format(t.format || 'YYYY-MM-DDTHH:mm:ss')
+ else if (v === 'STARTTIME')
+ v = moment
+ .utc(TimeControl.getStartTime())
+ .format(t.format || 'YYYY-MM-DDTHH:mm:ss')
+ else if (v === 'ENDTIME')
+ v = moment
+ .utc(TimeControl.getEndTime())
+ .format(t.format || 'YYYY-MM-DDTHH:mm:ss')
+ break
+ default:
+ }
+ defaultProps[f] = v
+ }
+ })
+
+ return defaultProps
+ },
}
export default DrawTool_Templater
diff --git a/src/essence/Tools/Draw/config.json b/src/essence/Tools/Draw/config.json
index 1bfe5fa2..293c34cf 100644
--- a/src/essence/Tools/Draw/config.json
+++ b/src/essence/Tools/Draw/config.json
@@ -61,8 +61,13 @@
"default": "No"
},
{
- "type": "date",
+ "type": "incrementer",
"field": "g",
+ "default": "ID-#"
+ },
+ {
+ "type": "date",
+ "field": "h",
"format": "HH:mm:ss",
"default": "now"
}