Skip to content

Commit

Permalink
Merge pull request #66 from Steve-Mcl/60-full-screen-list
Browse files Browse the repository at this point in the history
UX improvements
  • Loading branch information
Steve-Mcl authored Jul 26, 2023
2 parents b2e926a + d49c031 commit a5e7985
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 85 deletions.
162 changes: 146 additions & 16 deletions cronplus.html
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,31 @@
let map, mapPopup, selectedLocation, selectedLocationInput
const filesAdded = [] // list of files already added

function toggleFullscreen(selector, callback) {
callback = callback || function () {}
const el = document.querySelector(selector || "#node-cronplus-tab-static-schedules");
const $el = $(el)
if (!document.fullscreenElement) {
el.requestFullscreen().then(() => {
$el.addClass('cron-plus-fullscreen-element').removeClass('cron-plus-expanded-element')
callback()
}).catch((err) => {
if (callback) {
callback(err)
} else {
alert( `Unable to get fullscreen mode: ${err.message}`, );
}
});
} else {
$el.removeClass('cron-plus-fullscreen-element').removeClass('cron-plus-expanded-element')
try {
document.exitFullscreen();
} finally {
callback()
}
}
}

function checkLoadJsCssFile (filename, filetype, callback) {
if (filesAdded.indexOf(filename) === -1) {
loadJsCssFile(filename, filetype, function () {
Expand Down Expand Up @@ -644,7 +669,14 @@
}

function updateEditorLayout () {
onSchedulesExpandCompress()

if (RED._cron_plus_debug) console.log('cronplus-updateEditorLayout')
const scheduleList = $('#node-cronplus-tab-static-schedules')
const scheduleListFullScreen = scheduleList.css('position') === 'fixed' || document.fullscreenElement
if (scheduleListFullScreen) {
return // don't update layout if schedules are fullscreen
}
const dlg = $('#dialog-form')
let height = dlg.height() - 5
const expandRow = dlg.find('.form-row-auto-height')
Expand Down Expand Up @@ -1748,7 +1780,7 @@
const container = $('<li/>')
// const container = $('<li/>', { style: 'max-width: 600px' })

// control buttons
// row buttons
const controlsContainer = $('<span/>', { style: controlsContainerStyle }).appendTo(container)
const deleteButton = $('<a/>', { href: '#', class: 'editor-button editor-button-small', style: '' }).appendTo(controlsContainer)
$('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton)
Expand Down Expand Up @@ -1943,9 +1975,9 @@
offsetField.prop('title', 'Minutes Offset +/- 1439')

// init tooltips
initTooltip(offsetField, 'solar', { my: 'right top', at: 'right bottom+5', of: cell2Solar, collision: 'flipfit' })
initTooltip(locationField, 'solar', { my: 'right top', at: 'right bottom+5', of: cell2Solar, collision: 'flipfit' })
initTooltip(expressionField, 'cron', { my: 'right top', at: 'right bottom+5', of: cell2Cron, collision: 'flipfit' })
initTooltip(offsetField, 'solar', { my: 'middle top', at: 'middle bottom+5', of: cell2Solar, collision: 'flipfit' })
initTooltip(locationField, 'solar', { my: 'middle top', at: 'middle bottom+5', of: cell2Solar, collision: 'flipfit' })
initTooltip(expressionField, 'cron', { my: 'middle top', at: 'middle bottom+5', of: cell2Cron, collision: 'flipfit' })

// locationField.keyup(function () {
// const f = $(this)
Expand Down Expand Up @@ -1982,8 +2014,7 @@
})

deleteButton.click(function () {
container.css({ background: '#fee' })
container.fadeOut(300, function () {
container.fadeOut(200, function () {
$(this).remove()
})
})
Expand Down Expand Up @@ -2018,12 +2049,45 @@
$('#node-input-add-option').click(function () {
generateOption($('#node-input-option-container').children().length, {})
$('#node-input-option-container-div').scrollTop($('#node-input-option-container-div').get(0).scrollHeight)
// focus the input with class .node-input-option-name in the last li added
$('#node-input-option-container').children().last().find('.node-input-option-name').focus().select()
})

$('#node-input-show-dynamic').click(function () {
$('#cron-plus-dynamic-nodes-dialog').dialog('open')
})

removeEventListener("fullscreenchange", onSchedulesExpandCompress);
addEventListener("fullscreenchange", onSchedulesExpandCompress)

$('#cronplus-expand-schedules-button').click(function (evt) {
const selector = '#node-cronplus-tab-static-schedules'
if (evt) {
// prevent the default behaviour - we will handle it
evt.preventDefault()
evt.stopImmediatePropagation()
}

// if shift key or middle mouse button or already full screen then toggle full screen
if (evt.shiftKey || evt.button === 1 /* middle button */ || document.fullscreenElement) {
toggleFullscreen(selector, function (err) {
updateEditorLayout()
})
} else {
//CSS expansion/contraction
const el = $(selector)
const isSmall = el.css('position') !== 'fixed' && !document.fullscreenElement;
if (isSmall) {
// is small - make it big
el.addClass('cron-plus-expanded-element').removeClass('cron-plus-fullscreen-element')
} else {
// is big - make it small
el.removeClass('cron-plus-expanded-element').removeClass('cron-plus-fullscreen-element')
}
updateEditorLayout()
}
})

for (let i = 0; i < this.options.length; i++) {
const option = this.options[i]
try {
Expand Down Expand Up @@ -2052,9 +2116,11 @@
setTimeout(function () {
$('#node-cronplus-tab-static-schedules').css('max-width', '')
}, 200)

},
oneditsave: function () {
if (RED._cron_plus_debug) { console.log('oneditsave - cronplus') }
removeEventListener("fullscreenchange", onSchedulesExpandCompress);
const node = this
const options = $('#node-input-option-container').children()
delete node.persistDynamic // remove deprecated property
Expand Down Expand Up @@ -2096,6 +2162,12 @@
$('#node-input-timeZone').off()
$('#node-input-crontab').off()
},
oneditcancel: function() {
if (RED._cron_plus_debug) { console.log('oneditcancel - cronplus') }
removeEventListener("fullscreenchange", onSchedulesExpandCompress);
$('#node-input-timeZone').off()
$('#node-input-crontab').off()
},
button: {
visible: function () {
if (this.options && this.options.length === 1) {
Expand Down Expand Up @@ -2240,6 +2312,23 @@ <h1 class="red-ui-help-title">cron-plus</h1>
'width=800,height=600'
)
}

function onSchedulesExpandCompress () {
const selector = '#node-cronplus-tab-static-schedules'
const el = $(selector)
const $buttonExpandIcon = $('#cronplus-expand-schedules-button').find('i.fa')
const isBig = el.css('position') === 'fixed' || document.fullscreenElement;
if (isBig) {
// is big - set the icon to compress & hide certain elements
$buttonExpandIcon.removeClass('fa-expand').addClass('fa-compress')
$('#node-input-show-dynamic').addClass('cron-plus-vanish-element')
} else {
// is small - set the icon to expand & show elements
$buttonExpandIcon.removeClass('fa-compress').addClass('fa-expand')
$('#node-input-show-dynamic').removeClass('cron-plus-vanish-element')
}
}

</script>

<script type="text/html" data-template-name="cronplus">
Expand Down Expand Up @@ -2347,6 +2436,29 @@ <h1 class="red-ui-help-title">cron-plus</h1>
display: none !important;
visibility: hidden;
}
.cron-plus-fullscreen-element {
padding: 15px;
z-index: 99999;
background-color: var(--red-ui-form-background);
}
.cron-plus-expanded-element {
position: fixed;
z-index: 99999;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
visibility: visible;
height: unset !important;
width: unset !important;
padding: 15px;
margin: 0px;
background-color: var(--red-ui-form-background);
}
.cron-plus-vanish-element {
display: none !important;
visibility: hidden !important;
}
.cron-plus-map-dialog-content {
padding: 0px 0px 0px 0px;
}
Expand Down Expand Up @@ -2453,6 +2565,8 @@ <h4>Accepted formats...</h4>
<div id="cron-plus-expression-builder" >
</div>
</div>

<!-- For Rows -->
<div class="form-row cron-plus-form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name">Name</span></label>
<input type="text" id="node-input-name" style="width: calc(100% - 130px)" placeholder="Name">
Expand Down Expand Up @@ -2481,18 +2595,34 @@ <h4>Accepted formats...</h4>
<label for="node-input-storeName"><i class="fa fa-database"></i> Save State</label>
<select type="text" id="node-input-storeName" style="width: calc(100% - 130px);"></select>
</div>
<div id="node-cronplus-tab-static-schedules" class="form-row cron-plus-form-row form-row-auto-height" style="margin-bottom: 0px;width: 100%; min-height: 200px; max-width: min-content;">
<label for="node-input-option-container-div" style="vertical-align:top"><i class="fa fa-list-alt"></i> Schedules</label>
<div class="red-ui-editableList-border red-ui-editableList-container" id="node-input-option-container-div"
style="min-width: 300px; box-sizing: border-box; border-radius: 5px; padding: 5px; overflow-y:scroll;display: inline-block; width: 100%; height: calc(100% - 28px); min-height: 150px;">
<ol id="node-input-option-container" style=" list-style-type:none; margin: 0;"></ol>

<div id="node-cronplus-tab-static-schedules" class="form-row cron-plus-form-row form-row-auto-height"
style="width: 100%; min-height: 200px; display: flex; flex-flow: column nowrap; max-width: min-content">
<!-- Row 1 -->
<div style="display: flex; justify-content: space-between;">
<label for="node-input-option-container-div" style="vertical-align:top;flex-basis: 120px;">
<i class="fa fa-list-alt"></i>
Schedules
</label>
<div style="flex-grow: 1; column-gap: 2px; margin-bottom: 2px; margin-top: 0px; display: flex; padding: 0px 0px 0px 4px;">
<!-- Toolbar -->
<a href="#" accesskey="a" title="Add a new schedule [A]" class="editor-button editor-button-small" id="node-input-add-option">
<span><i class="fa fa-plus" style="margin-right: 2px;"></i> <u>a</u>dd</span>
</a>
<a href="#" accesskey="s" title="Show dynamic schedules [S]" class="editor-button editor-button-small" id="node-input-show-dynamic">
<span><i class="fa fa-table" style="margin-right: 2px;"></i> dynamic <u>s</u>chedules</span>
</a>
<a href="#" accesskey="x" class="editor-button editor-button-small" id="cronplus-expand-schedules-button" title="Hold the shift key for fullscreen [X]" style="margin-left: auto;">
<span class="expand-icon"><i class="fa fa-expand" style="margin-right: 2px;"></i> e<u>x</u>pand</span>
</a>
</div>
</div>
<!-- Row 2 (the list) -->
<div class="red-ui-editableList-border red-ui-editableList-container" id="node-input-option-container-div"
style="min-width: 300px;box-sizing: border-box;border-radius: 5px;padding: 5px;overflow-y:scroll;display: inline-block;height: calc(100% - -4px);min-height: 150px;">
<ol id="node-input-option-container" style=" list-style-type:none; margin: 0;" class="ui-sortable"></ol>
</div>
</div>
<div class="form-row cron-plus-form-row">
<a href="#" class="editor-button editor-button-small" id="node-input-add-option" style="margin-top: 4px;"><i class="fa fa-plus"></i> <span>add</span></a>
<a href="#" class="editor-button editor-button-small" id="node-input-show-dynamic" style="margin-top: 4px;"><i class="fa fa-table"></i> <span>view dynamic schedules</span></a>
</div>
</div>

</script>

Expand Down
138 changes: 69 additions & 69 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,70 +1,70 @@
{
"name": "node-red-contrib-cron-plus",
"version": "2.0.1",
"description": "A flexible scheduler (cron, solar events, fixed dates) node for Node-RED with full dynamic control and time zone support",
"main": "cronplus.js",
"scripts": {
"test": "mocha \"test/**/*_spec.js\"",
"publish": "npm publish"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Steve-Mcl/node-red-contrib-cron-plus.git"
},
"keywords": [
"node-red",
"scheduler",
"timer",
"cron",
"cronplus",
"cron plus",
"cron-plus",
"crontab",
"timer",
"suntime",
"sunrise",
"sunset"
],
"node-red": {
"version": ">=1.0.0",
"nodes": {
"cronplus": "cronplus.js"
}
},
"engines": {
"node": ">=8.0.0"
},
"author": {
"name": "Steve-Mcl"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus/issues"
},
"homepage": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus#readme",
"dependencies": {
"coord-parser": "^1.0.0",
"cronosjs": "^1.7.1",
"cronstrue": "^2.28.0",
"pretty-ms": "7.0.1",
"suncalc2": "^1.8.1"
},
"devDependencies": {
"eslint": "^8.45.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-standard": "^5.0.0",
"install": "^0.13.0",
"mocha": "^10.2.0",
"node-red-node-test-helper": "^0.3.2",
"npm": "^9.8.1",
"should": "^13.2.3"
},
"maintainers": [
{
"name": "Steve-Mcl",
"email": "[email protected]"
}
]
}
"name": "node-red-contrib-cron-plus",
"version": "2.1.0",
"description": "A flexible scheduler (cron, solar events, fixed dates) node for Node-RED with full dynamic control and time zone support",
"main": "cronplus.js",
"scripts": {
"test": "mocha \"test/**/*_spec.js\"",
"publish": "npm publish"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Steve-Mcl/node-red-contrib-cron-plus.git"
},
"keywords": [
"node-red",
"scheduler",
"timer",
"cron",
"cronplus",
"cron plus",
"cron-plus",
"crontab",
"timer",
"suntime",
"sunrise",
"sunset"
],
"node-red": {
"version": ">=1.0.0",
"nodes": {
"cronplus": "cronplus.js"
}
},
"engines": {
"node": ">=8.0.0"
},
"author": {
"name": "Steve-Mcl"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus/issues"
},
"homepage": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus#readme",
"dependencies": {
"coord-parser": "^1.0.0",
"cronosjs": "^1.7.1",
"cronstrue": "^2.28.0",
"pretty-ms": "7.0.1",
"suncalc2": "^1.8.1"
},
"devDependencies": {
"eslint": "^8.45.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-standard": "^5.0.0",
"install": "^0.13.0",
"mocha": "^10.2.0",
"node-red-node-test-helper": "^0.3.2",
"npm": "^9.8.1",
"should": "^13.2.3"
},
"maintainers": [
{
"name": "Steve-Mcl",
"email": "[email protected]"
}
]
}

0 comments on commit a5e7985

Please sign in to comment.