From 967edde51d85d6fc377c135b4e79d437f1cf7508 Mon Sep 17 00:00:00 2001 From: Pierre-Gilles Leymarie Date: Mon, 19 Apr 2021 14:05:20 +0800 Subject: [PATCH 1/5] Add time condition in scenes --- front/src/config/i18n/en.json | 9 +- front/src/config/i18n/fr.json | 9 +- .../routes/scene/edit-scene/ActionCard.jsx | 13 +- .../scene/edit-scene/actions/CheckTime.jsx | 134 ++++++++++++++++++ .../actions/ChooseActionTypeCard.jsx | 3 +- server/lib/scene/scene.actions.js | 38 +++++ server/models/scene.js | 5 + .../lib/scene/scene.executeActions.test.js | 100 ++++++++++++- server/utils/constants.js | 1 + 9 files changed, 307 insertions(+), 5 deletions(-) create mode 100644 front/src/routes/scene/edit-scene/actions/CheckTime.jsx diff --git a/front/src/config/i18n/en.json b/front/src/config/i18n/en.json index d05a571da7..e137b17569 100644 --- a/front/src/config/i18n/en.json +++ b/front/src/config/i18n/en.json @@ -903,6 +903,12 @@ "orText": "OR", "orButton": "+ OR" }, + "checkTime": { + "description": "The scene will continue only if current time is between the selected limits, in the selected days. If a field is left empty, it'll not be taken into account.", + "beforeLabel": "Before", + "afterLabel": "After", + "daysOfTheWeekLabel": "Weekdays" + }, "userPresence": { "userLabel": "User", "houseLabel": "House", @@ -962,7 +968,8 @@ "stop": "Stop service" }, "condition": { - "only-continue-if": "Only continue if" + "only-continue-if": "Only continue if", + "check-time": "Time condition" }, "user": { "set-seen-at-home": "User seen at home", diff --git a/front/src/config/i18n/fr.json b/front/src/config/i18n/fr.json index 7948b6a045..521ba6fb2d 100644 --- a/front/src/config/i18n/fr.json +++ b/front/src/config/i18n/fr.json @@ -903,6 +903,12 @@ "orText": "OU", "orButton": "+ OU" }, + "checkTime": { + "description": "La scène continuera si l'heure actuelle est comprise entre les bornes spécifiées, aux jours spécifiés. Si une condition est vide, elle ne sera pas prise en compte.", + "beforeLabel": "Avant", + "afterLabel": "Après", + "daysOfTheWeekLabel": "Jour de la semaine" + }, "userPresence": { "userLabel": "Utilisateur", "houseLabel": "Maison", @@ -962,7 +968,8 @@ "stop": "Arrêter le service" }, "condition": { - "only-continue-if": "Continuer seulement si" + "only-continue-if": "Continuer seulement si", + "check-time": "Condition temporelle" }, "user": { "set-seen-at-home": "Utilisateur vu à la maison", diff --git a/front/src/routes/scene/edit-scene/ActionCard.jsx b/front/src/routes/scene/edit-scene/ActionCard.jsx index aac0d9b7b6..22434b1a8a 100644 --- a/front/src/routes/scene/edit-scene/ActionCard.jsx +++ b/front/src/routes/scene/edit-scene/ActionCard.jsx @@ -15,6 +15,7 @@ import TurnOnOffSwitchParams from './actions/TurnOnOffSwitchParams'; import UserPresence from './actions/UserPresence'; import HttpRequest from './actions/HttpRequest'; import CheckUserPresence from './actions/CheckUserPresence'; +import CheckTime from './actions/CheckTime'; const deleteActionFromColumn = (columnIndex, rowIndex, deleteAction) => () => { deleteAction(columnIndex, rowIndex); @@ -32,7 +33,8 @@ const ACTION_ICON = { [ACTIONS.USER.SET_SEEN_AT_HOME]: 'fe fe-home', [ACTIONS.USER.SET_OUT_OF_HOME]: 'fe fe-home', [ACTIONS.HTTP.REQUEST]: 'fe fe-link', - [ACTIONS.USER.CHECK_PRESENCE]: 'fe fe-home' + [ACTIONS.USER.CHECK_PRESENCE]: 'fe fe-home', + [ACTIONS.CONDITION.CHECK_TIME]: 'fe fe-watch' }; const ActionCard = ({ children, ...props }) => ( @@ -186,6 +188,15 @@ const ActionCard = ({ children, ...props }) => ( setVariables={props.setVariables} /> )} + {props.action.type === ACTIONS.CONDITION.CHECK_TIME && ( + + )} diff --git a/front/src/routes/scene/edit-scene/actions/CheckTime.jsx b/front/src/routes/scene/edit-scene/actions/CheckTime.jsx new file mode 100644 index 0000000000..32acb08c7a --- /dev/null +++ b/front/src/routes/scene/edit-scene/actions/CheckTime.jsx @@ -0,0 +1,134 @@ +import Select from 'react-select'; +import { Component } from 'preact'; +import DatePicker from 'react-datepicker'; +import { connect } from 'unistore/preact'; +import { format } from 'date-fns'; +import { Text, Localizer } from 'preact-i18n'; + +@connect('', {}) +class CheckTime extends Component { + handleBeforeTimeChange = time => { + const timeFormatted = time ? format(time, 'HH:mm') : undefined; + this.props.updateActionProperty(this.props.columnIndex, this.props.index, 'before', timeFormatted); + }; + handleBeforeAfterChange = time => { + const timeFormatted = time ? format(time, 'HH:mm') : undefined; + this.props.updateActionProperty(this.props.columnIndex, this.props.index, 'after', timeFormatted); + }; + handleDayOfTheWeekChange = options => { + const values = options ? options.map(option => option.value) : undefined; + this.props.updateActionProperty(this.props.columnIndex, this.props.index, 'days_of_the_week', values); + }; + + render(props, state) { + const { localeSet } = state; + const before = this.props.action.before + ? new Date().setHours(this.props.action.before.substr(0, 2), this.props.action.before.substr(3, 2)) + : null; + const after = this.props.action.after + ? new Date().setHours(this.props.action.after.substr(0, 2), this.props.action.after.substr(3, 2)) + : null; + const daysOfTheWeekOptions = [ + { + value: 'monday', + label: + }, + { + value: 'tuesday', + label: + }, + { + value: 'wednesday', + label: + }, + { + value: 'thursday', + label: + }, + { + value: 'friday', + label: + }, + { + value: 'saturday', + label: + }, + { + value: 'sunday', + label: + } + ]; + const selectedWeekDaysOptions = this.props.action.days_of_the_week + ? this.props.action.days_of_the_week.map(day => daysOfTheWeekOptions.find(option => option.value === day)) + : []; + return ( +
+

+ + + +

+
+
+
+
+ +
+ + } + showTimeSelect + showTimeSelectOnly + isClearable + timeIntervals={5} + timeCaption={} + dateFormat="HH:mm" + /> + +
+
+
+
+
+ +
+ + } + showTimeSelect + showTimeSelectOnly + isClearable + timeIntervals={5} + timeCaption={} + dateFormat="HH:mm" + /> + +
+
+
+
+
+ +
+