Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#356 DrawTool Templating - Incrementer field #357

Merged
merged 1 commit into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions docs/pages/Tools/Draw/Draw.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,21 @@ 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
}
],
"example_2": [
{
"type": "checkbox",
"field": "h",
"field": "i",
"default": false
}
]
Expand Down
5 changes: 3 additions & 2 deletions src/essence/Ancillary/Coordinates.js
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
14 changes: 14 additions & 0 deletions src/essence/Tools/Draw/DrawTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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.',
Expand Down
5 changes: 4 additions & 1 deletion src/essence/Tools/Draw/DrawTool_Editing.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions src/essence/Tools/Draw/DrawTool_Templater.css
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,6 @@
.drawToolTemplaterLiBody_dropdown_default input[type='number'] {
width: 90px !important;
}
.drawToolTemplaterLiBody_incrementer_default {
width: 100%;
}
184 changes: 182 additions & 2 deletions src/essence/Tools/Draw/DrawTool_Templater.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -92,6 +93,15 @@ const DrawTool_Templater = {
`<input id='drawToolFileModalTemplateDate_${idx}' placeholder='${t.format || 'YYYY-MM-DDTHH:mm:ss'}' autocomplete='off'></input>`,
`</li>`
].join('\n')
case 'incrementer':
return [
`<li id='drawToolTemplater_${idx}' class='drawToolTemplater${t.type}'>`,
`<div title='${t.field}'>${t.field}:</div>`,
`<input type='text' placeholder="${t.default != null ? ` value='${t.default}'` : ''}" autocomplete="off"
${t.default != null ? ` value='${t.default}'` : ''}
/>`,
`</li>`
].join('\n')
default:
return null
}
Expand Down Expand Up @@ -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':
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -697,6 +799,17 @@ const DrawTool_Templater = {
"</div>"
]
break
case 'incrementer':
// prettier-ignore
typeMarkup = [
`<div class='drawToolTemplaterLiBody_${type}'>`,
`<div class='drawToolTemplaterLiBody_${type}_default'>`,
`<div>Value with a single '#' to place an incrementing number: </div>`,
`<input id='drawToolTemplaterLiFieldInput_${idx}_default' placeholder='ID-#' type='text' value='${opts.default != null ? opts.default : ''}'></input>`,
"</div>",
"</div>"
]
break
default:
break
}
Expand Down Expand Up @@ -788,6 +901,7 @@ const DrawTool_Templater = {
).val()

const items = []
const invalids = {}
$(`#${containerId} #drawToolTemplaterDesignContent > li`).each(
function () {
const item = {}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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 == '') {
Expand Down Expand Up @@ -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 },
Expand All @@ -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
},
Expand Down Expand Up @@ -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
7 changes: 6 additions & 1 deletion src/essence/Tools/Draw/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,13 @@
"default": "No"
},
{
"type": "date",
"type": "incrementer",
"field": "g",
"default": "ID-#"
},
{
"type": "date",
"field": "h",
"format": "HH:mm:ss",
"default": "now"
}
Expand Down