Skip to content

Commit

Permalink
Multiple UI fixes + implement umzug so that DB is migrated in Gladys …
Browse files Browse the repository at this point in the history
…directly (GladysAssistant#711)

* fix GladysAssistant#664 remove reboot button

* fix GladysAssistant#657 - no page on get device

* Fix GladysAssistant#669: edit room name

* Fix GladysAssistant#661: no value for motion on dashboard

* Fix GladysAssistant#679: execute DB migrations on startup

* fix GladysAssistant#656: dashboard rooms by houses

* Map - Fit zoom to markers

* Prettier on Map.jsx

* prettier

* Prettier --'

* Remove pagination everywhere on get device request

* Don't send to_update property to room update route

* House & Room name should be between 1 & 40 characters

* Edit house: Add more validation errors in UI

* Fix linting

* remove front flag

* Fix margin problems with room names

* Run tests in a RAM db

* Fix codecov.yml

* Fix Maps: markerArray should not be a global variable

* Eslint should check .jsx files

* Update README

* Change Maps markerArray lifecycle

Co-authored-by: atrovato <1839717+atrovato@users.noreply.github.com>
Co-authored-by: Vincent KULAK <vkulak62@gmail.com>
  • Loading branch information
3 people authored Mar 21, 2020
1 parent cabc83a commit f74b837
Show file tree
Hide file tree
Showing 35 changed files with 271 additions and 217 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This is just a simple scenario, possibilities with Gladys are just endless. Don'

Right now we are migrating from Gladys 3 to Gladys 4, a new release rewrote from scratch. If you want to install Gladys 3, visit [our website](https://gladysassistant.com).

To install Gladys 4 Alpha, read the following instructions.
To install Gladys 4 Beta, read the following instructions.

We use Docker to deploy Gladys 4, so it's easy to install it on any system.

Expand All @@ -69,7 +69,7 @@ It's only thanks to donation from the community that my open-source work is sust

To support the project, you can:

- Support monthly, 9.99€/month with the [Gladys Community Package](https://gladysassistant.com/gladys-community-package).
- Support monthly, 9.99€/month with [Gladys Plus](https://gladysassistant.com/pricing).
- Donate with Bitcoin: 3KQiX1FtbdXLXPH9UfLSyuzRMDRGY52EiA

## Links
Expand All @@ -82,4 +82,4 @@ To support the project, you can:

## Copyright & License

Copyright (c) 2013-2019 Gladys Assistant - Released under the [Apache 2.0 License](https://github.com/gladysassistant/Gladys/blob/master/LICENSE).
Copyright (c) 2013-2020 Gladys Assistant - Released under the [Apache 2.0 License](https://github.com/gladysassistant/Gladys/blob/master/LICENSE).
6 changes: 2 additions & 4 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ coverage:
project:
server:
target: 90%
flags: server
flags:
- server

flags:
server:
paths:
- server
front:
paths:
- front
2 changes: 1 addition & 1 deletion front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"build": "cross-env NODE_ENV=production preact build --template src/template.html --no-prerender",
"serve": "npm run build && preact serve",
"dev": "preact watch -p 1444 --template src/template.html",
"eslint": "eslint src --ext .json --ext .js",
"eslint": "eslint src --ext .json --ext .js --ext .jsx",
"prettier-check": "prettier --check '**/*.js' '**/*.jsx' '**/*.json'",
"prettier": "prettier --write '**/*.js' '**/*.jsx' '**/*.json'",
"test": "jest --coverage"
Expand Down
17 changes: 0 additions & 17 deletions front/src/actions/dashboard/edit-boxes/editDevicesInRoom.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
import { RequestStatus } from '../../../utils/consts';
import createBoxActions from '../boxActions';

function createActions(store) {
const boxActions = createBoxActions(store);

const actions = {
async getRooms(state) {
store.setState({
DashboardEditDeviceInRoomStatus: RequestStatus.Getting
});
try {
const rooms = await state.httpClient.get('/api/v1/room');
store.setState({
rooms,
DashboardEditDeviceInRoomStatus: RequestStatus.Success
});
} catch (e) {
store.setState({
DashboardEditDeviceInRoomStatus: RequestStatus.Error
});
}
},
updateBoxRoom(state, x, y, room) {
boxActions.updateBoxConfig(state, x, y, {
room
Expand Down
17 changes: 0 additions & 17 deletions front/src/actions/dashboard/edit-boxes/editTemperatureInRoom.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
import { RequestStatus } from '../../../utils/consts';
import createBoxActions from '../boxActions';

function createActions(store) {
const boxActions = createBoxActions(store);

const actions = {
async getRooms(state) {
store.setState({
DashboardEditTemperatureInRoomStatus: RequestStatus.Getting
});
try {
const rooms = await state.httpClient.get('/api/v1/room');
store.setState({
rooms,
DashboardEditTemperatureInRoomStatus: RequestStatus.Success
});
} catch (e) {
store.setState({
DashboardEditTemperatureInRoomStatus: RequestStatus.Error
});
}
},
updateBoxRoom(state, x, y, room) {
boxActions.updateBoxConfig(state, x, y, {
room
Expand Down
33 changes: 30 additions & 3 deletions front/src/actions/house.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,25 @@ function createActions(store) {
});
store.setState(newState);
},
editRoom(state, houseIndex, roomIndex, property, value) {
const newState = update(state, {
houses: {
[houseIndex]: {
rooms: {
[roomIndex]: {
[property]: {
$set: value
},
to_update: {
$set: true
}
}
}
}
}
});
store.setState(newState);
},
addHouse(state) {
const newState = update(state, {
houses: {
Expand Down Expand Up @@ -154,10 +173,12 @@ function createActions(store) {

const promises = house.rooms.map(async room => {
if (room.to_delete) {
return state.httpClient.delete(`/api/v1/room/${room.selector}`, room);
return state.httpClient.delete(`/api/v1/room/${room.selector}`);
}
if (!room.id) {
return state.httpClient.post(`/api/v1/house/${houseCreatedOrUpdated.selector}/room`, room);
} else if (room.to_update) {
return state.httpClient.patch(`/api/v1/room/${room.selector}`, { name: room.name });
}
return room;
});
Expand Down Expand Up @@ -193,8 +214,8 @@ function createActions(store) {
store.setState(newState);
} catch (e) {
const status = get(e, 'response.status');
const errorValue = get(e, 'response.data.error.value');
if (status === 409 && errorValue === 'room') {
const url = get(e, 'response.config.url');
if (status === 409 && url.endsWith('/room')) {
store.setState({
houseUpdateStatus: {
[house.id]: RequestStatus.RoomConflictError
Expand All @@ -206,6 +227,12 @@ function createActions(store) {
[house.id]: RequestStatus.ConflictError
}
});
} else if (status === 422 && url.includes('/room/')) {
store.setState({
houseUpdateStatus: {
[house.id]: RequestStatus.RoomValidationError
}
});
} else if (status === 422) {
store.setState({
houseUpdateStatus: {
Expand Down
47 changes: 18 additions & 29 deletions front/src/components/boxs/device-in-room/EditDeviceInRoom.jsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
import { Component } from 'preact';
import { connect } from 'unistore/preact';
import actions from '../../../actions/dashboard/edit-boxes/editDevicesInRoom';
import BaseEditBox from '../baseEditBox';

const updateBoxRoom = (updateBoxRoomFunc, x, y) => e => {
updateBoxRoomFunc(x, y, e.target.value);
};
import BaseEditBox from '../baseEditBox';
import RoomSelector from '../../house/RoomSelector';

const EditDevicesInRoom = ({ children, ...props }) => (
<BaseEditBox {...props} titleKey="dashboard.boxTitle.devices-in-room">
<div class="form-group">
<label>Select the room you want to display here:</label>
<select onChange={updateBoxRoom(props.updateBoxRoom, props.x, props.y)} class="form-control">
<option value="">-------</option>
{props.rooms &&
props.rooms.map(room => (
<option selected={room.selector === props.box.room} value={room.selector}>
{room.name}
</option>
))}
</select>
</div>
</BaseEditBox>
);
import actions from '../../../actions/dashboard/edit-boxes/editDevicesInRoom';

@connect('rooms', actions)
class EditDeviceInRoomComponent extends Component {
componentDidMount() {
this.props.getRooms();
}
@connect('', actions)
class EditDeviceInRoom extends Component {
updateBoxRoom = room => {
this.props.updateBoxRoom(this.props.x, this.props.y, room.selector);
};

render(props, {}) {
return <EditDevicesInRoom {...props} />;
render(props) {
return (
<BaseEditBox {...props} titleKey="dashboard.boxTitle.devices-in-room">
<div class="form-group">
<label>Select the room you want to display here:</label>
<RoomSelector selectedRoom={props.box.room} updateRoomSelection={this.updateBoxRoom} />
</div>
</BaseEditBox>
);
}
}

export default EditDeviceInRoomComponent;
export default EditDeviceInRoom;
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ const SensorDeviceType = ({ children, ...props }) => (
)}
{props.deviceFeature.category === DEVICE_FEATURE_CATEGORIES.MOTION_SENSOR && (
<td class="text-right">
{dayjs(props.deviceFeature.last_value_changed)
.locale(props.user.language)
.fromNow()}
{!props.deviceFeature.last_value_changed && <Text id="dashboard.boxes.devicesInRoom.noValue" />}
{props.deviceFeature.last_value_changed &&
dayjs(props.deviceFeature.last_value_changed)
.locale(props.user.language)
.fromNow()}
</td>
)}
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { Text } from 'preact-i18n';
import actions from '../../../actions/dashboard/edit-boxes/editTemperatureInRoom';
import BaseEditBox from '../baseEditBox';

const updateBoxRoom = (updateBoxRoomFunc, x, y) => e => {
updateBoxRoomFunc(x, y, e.target.value);
import RoomSelector from '../../house/RoomSelector';

const updateBoxRoom = (updateBoxRoomFunc, x, y) => room => {
updateBoxRoomFunc(x, y, room.selector);
};

const EditRoomTemperatureBox = ({ children, ...props }) => (
Expand All @@ -14,25 +16,16 @@ const EditRoomTemperatureBox = ({ children, ...props }) => (
<label>
<Text id="dashboard.boxes.temperatureInRoom.editRoomLabel" />
</label>
<select onChange={updateBoxRoom(props.updateBoxRoom, props.x, props.y)} class="form-control">
<option value="">-------</option>
{props.rooms &&
props.rooms.map(room => (
<option selected={room.selector === props.box.room} value={room.selector}>
{room.name}
</option>
))}
</select>
<RoomSelector
selectedRoom={props.box.room}
updateRoomSelection={updateBoxRoom(props.updateBoxRoom, props.x, props.y)}
/>
</div>
</BaseEditBox>
);

@connect('rooms', actions)
@connect('', actions)
class EditRoomTemperatureBoxComponent extends Component {
componentDidMount() {
this.props.getRooms();
}

render(props, {}) {
return <EditRoomTemperatureBox {...props} />;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Text } from 'preact-i18n';
import cx from 'classnames';

const documentationURL = 'https://documentation.gladysassistant.com';

const DeviceConfigurationLink = ({ children, documentKey, user, linkClass }) => (
<a
target="_blank"
rel="noopener noreferrer"
href={`${documentationURL}/${user.language}/configuration#${documentKey}`}
class={cx({
[linkClass]: linkClass
Expand Down
41 changes: 13 additions & 28 deletions front/src/components/house/EditHouse.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import cx from 'classnames';
import get from 'get-value';
import { RequestStatus } from '../../utils/consts';
import Map from './Map';

const removeRoomLocal = (index, removeRoom) => () => {
removeRoom(index);
};
import EditRoom from './EditRoom';

const EditHouse = ({ children, ...props }) => (
<div
Expand All @@ -26,11 +23,6 @@ const EditHouse = ({ children, ...props }) => (
<Text id="signup.configureHouse.conflictError" />
</div>
)}
{props.houseUpdateStatus === RequestStatus.RoomConflictError && (
<div class="alert alert-danger">
<Text id="signup.configureHouse.roomConflictError" />
</div>
)}
{props.houseUpdateStatus === RequestStatus.NetworkError && (
<div class="alert alert-danger">
<Text id="signup.httpErrors.networkError" />
Expand Down Expand Up @@ -70,26 +62,19 @@ const EditHouse = ({ children, ...props }) => (
<label class="form-label">
<Text id="signup.configureHouse.roomsLabel" />
</label>
<div
class="tags"
style={{
marginBottom: '10px'
}}
>
{props.houseUpdateStatus === RequestStatus.RoomConflictError && (
<div class="alert alert-danger">
<Text id="signup.configureHouse.roomConflictError" />
</div>
)}
{props.houseUpdateStatus === RequestStatus.RoomValidationError && (
<div class="alert alert-danger">
<Text id="signup.configureHouse.validationErrorRoom" />
</div>
)}
<div class="row mb-2">
{props.house.rooms &&
props.house.rooms.map((room, index) => {
if (room.to_delete === true) {
return null;
}
return (
<span class="tag">
{room.name}
<a onClick={removeRoomLocal(index, props.removeRoom)} class="tag-addon">
<i class="fe fe-x" />
</a>
</span>
);
})}
props.house.rooms.map((room, index) => <EditRoom {...props} room={room} index={index} />)}
</div>
<div class="input-group">
<Localizer>
Expand Down
4 changes: 4 additions & 0 deletions front/src/components/house/EditHouseComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class EditHouseComponent extends Component {
removeRoom = roomIndex => {
this.props.removeRoom(this.props.houseIndex, roomIndex);
};
editRoom = (roomIndex, property, value) => {
this.props.editRoom(this.props.houseIndex, roomIndex, property, value);
};
saveHouse = async () => {
this.setState({
loading: true
Expand Down Expand Up @@ -72,6 +75,7 @@ class EditHouseComponent extends Component {
newRoomName={newRoomName}
addRoom={this.addRoom}
removeRoom={this.removeRoom}
editRoom={this.editRoom}
saveHouse={this.saveHouse}
onKeyPressRoomInput={this.onKeyPressRoomInput}
wantToDeleteHouse={wantToDeleteHouse}
Expand Down
Loading

0 comments on commit f74b837

Please sign in to comment.