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

Allow group name change #795

Merged
merged 4 commits into from
Jul 15, 2024
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
27 changes: 26 additions & 1 deletion lib/db/api.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2019,2023 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
* Copyright © 2019-2024 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
**/

var r = require('rethinkdb')
Expand Down Expand Up @@ -826,6 +826,31 @@ dbapi.updateDefaultUserGroupsQuotas = function(email, duration, number, repetiti
}}}, {returnChanges: true}))
}

dbapi.updateDeviceGroupName = function(serial, group) {
return db.run(r.table('devices').get(serial).update({group: {
name:
r.branch(
r.expr(apiutil.isOriginGroup(group.class)).eq(false)
, r.branch(
r.expr(group.isActive).eq(true)
, group.name
, r.row('group')('name')
)
, r.branch(
r.row('group')('origin').eq(r.row('group')('id'))
, group.name
, r.row('group')('name')
)
)
, originName:
r.branch(
r.expr(apiutil.isOriginGroup(group.class)).eq(true)
, group.name
, r.row('group')('originName')
)
}}))
}

dbapi.updateDeviceCurrentGroupFromOrigin = function(serial) {
return db.run(r.table('devices').get(serial)).then(function(device) {
return db.run(r.table('groups').get(device.group.origin)).then(function(group) {
Expand Down
34 changes: 32 additions & 2 deletions lib/units/api/controllers/groups.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2019 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
* Copyright © 2019-2024 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
**/

const _ = require('lodash')
Expand Down Expand Up @@ -782,6 +782,35 @@ function updateGroup(req, res) {
const stop = new Date(req.body.stopTime || group.dates[0].stop)
let state, isActive

if (group.state !== apiutil.PENDING) {
// only name can be updated
state = typeof req.body.state === 'undefined' ? group.state : req.body.state

if (start.toISOString() !== group.dates[0].start.toISOString() ||
stop.toISOString() !== group.dates[0].stop.toISOString() ||
state !== group.state ||
_class !== group.class ||
repetitions !== group.repetitions) {
return apiutil.respond(res, 403, 'Forbidden (only name can be updated)')
}

if (name === group.name) {
return apiutil.respond(res, 200, 'Unchanged (group)', {group: {}})
}

return dbapi.updateGroup(group.id, {
name: name
})
.then(function(updatedGroup) {
if (updatedGroup) {
apiutil.respond(res, 200, 'Updated (group)', {group: apiutil.publishGroup(updatedGroup)})
}
else {
throw new Error(`Group not found: ${group.id}`)
}
})
}

if (apiutil.isOriginGroup(_class)) {
state = apiutil.READY
isActive = true
Expand All @@ -808,7 +837,8 @@ function updateGroup(req, res) {
repetitions === group.repetitions) {
return apiutil.respond(res, 200, 'Unchanged (group)', {group: {}})
}
const duration = group.devices.length * (stop - start) * (repetitions + 1)
const duration = apiutil.isOriginGroup(_class) ?
0 : group.devices.length * (stop - start) * (repetitions + 1)
const dates = apiutil.computeGroupDates({start: start, stop: stop}, _class, repetitions)

if (start < group.dates[0].start ||
Expand Down
9 changes: 5 additions & 4 deletions lib/units/groups-engine/watchers/devices.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2019 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
* Copyright © 2019-2024 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
**/

const wirerouter = require('../../../wire/router')
Expand Down Expand Up @@ -66,7 +66,6 @@ module.exports = function(push, pushdev, channelRouter) {

delete device.channel
delete device.owner
delete device.group.id
delete device.group.lifeTime
return device
}
Expand Down Expand Up @@ -117,7 +116,7 @@ module.exports = function(push, pushdev, channelRouter) {
, 'model'
, 'operator'
, 'manufacturer'
, {group: ['id', 'origin', 'originName', 'lifeTime']}
, {group: ['id', 'name', 'origin', 'originName', 'lifeTime', 'owner']}
, {provider: ['name']}
, {network: ['type', 'subtype']}
, {display: ['height', 'width']}
Expand Down Expand Up @@ -154,7 +153,9 @@ module.exports = function(push, pushdev, channelRouter) {
data.new_val.network.type !== data.old_val.network.type ||
data.new_val.network.subtype !== data.old_val.network.subtype
) ||
data.new_val.provider.name !== data.old_val.provider.name) {
data.new_val.provider.name !== data.old_val.provider.name ||
data.new_val.group.name !== data.old_val.group.name ||
data.new_val.group.originName !== data.old_val.group.originName) {
sendDeviceChange(data.new_val, data.old_val, 'updated')
}

Expand Down
15 changes: 13 additions & 2 deletions lib/units/groups-engine/watchers/groups.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2019 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
* Copyright © 2019-2024 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
**/

const wirerouter = require('../../../wire/router')
Expand Down Expand Up @@ -104,6 +104,12 @@ module.exports = function(push, pushdev, channelRouter) {
})
}

function doUpdateDevicesGroupName(group) {
return Promise.map(group.devices, function(serial) {
return dbapi.updateDeviceGroupName(serial, group)
})
}

function doUpdateDevicesCurrentGroup(group, devices) {
return Promise.map(devices, function(serial) {
return dbapi.updateDeviceCurrentGroup(serial, group)
Expand Down Expand Up @@ -235,7 +241,7 @@ module.exports = function(push, pushdev, channelRouter) {
.then(function(cursor) {
cursor.each(function(err, data) {
let users, devices, isBecomeActive, isBecomeUnactive, isActive
, isAddedUser, isAddedDevice, isUpdatedDeviceOriginGroup, isChangedDates
, isAddedUser, isAddedDevice, isUpdatedDeviceOriginGroup, isChangedDates, isChangedName

if (err) {
throw err
Expand Down Expand Up @@ -281,6 +287,7 @@ module.exports = function(push, pushdev, channelRouter) {
isBecomeActive = isBecomeUnactive = false
isAddedUser = isAddedDevice = false
isUpdatedDeviceOriginGroup = false
isChangedName = false
}
else {
users = _.xor(data.new_val.users, data.old_val.users)
Expand All @@ -300,6 +307,7 @@ module.exports = function(push, pushdev, channelRouter) {
data.new_val.ticket !== null &&
(data.old_val.ticket === null ||
data.new_val.ticket.signature !== data.old_val.ticket.signature)
isChangedName = data.old_val.name !== data.new_val.name

if (!isUpdatedDeviceOriginGroup) {
sendGroupChange(
Expand Down Expand Up @@ -337,6 +345,9 @@ module.exports = function(push, pushdev, channelRouter) {
else if (users.length) {
return treatGroupUsersChange(data.old_val, users, isActive, isAddedUser)
}
else if (isChangedName) {
return doUpdateDevicesGroupName(data.new_val)
}
return true
})
})
Expand Down
11 changes: 10 additions & 1 deletion lib/units/websocket/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright © 2019 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
* Copyright © 2019-2024 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
**/

var http = require('http')
Expand Down Expand Up @@ -133,6 +133,15 @@ module.exports = function(options) {
disconnectSocket(true)
})
.on(wire.DeviceChangeMessage, function(channel, message) {
if (user.groups.subscribed.indexOf(message.device.group.id) > -1) {
socket.emit('device.change', {
important: true
, data: {
serial: message.device.serial
, group: message.device.group
}
})
}
if (user.groups.subscribed.indexOf(message.device.group.origin) > -1 ||
user.groups.subscribed.indexOf(message.oldOriginGroupId) > -1) {
socket.emit('user.settings.devices.' + message.action, message)
Expand Down
9 changes: 6 additions & 3 deletions lib/wire/wire.proto
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright © 2019 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
// Copyright © 2019-2024 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
//

// Message wrapper
Expand Down Expand Up @@ -160,8 +160,11 @@ message DeviceProviderField {
}

message DeviceGroupField {
optional string origin = 1;
optional string originName = 2;
optional string id = 1;
optional string name = 2;
optional string origin = 3;
optional string originName = 4;
optional GroupOwnerField owner = 5;
}

message DeviceField {
Expand Down
2 changes: 1 addition & 1 deletion res/app/settings/groups/groups-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ module.exports = function GroupsCtrl(
getAvailableGroupDevices(group)
}
}
if (isChangedSchedule && group.state !== 'pending') {
if (isChangedSchedule) {
$scope.initTemporarySchedule(group)
}
if (doGetDevices) {
Expand Down
13 changes: 6 additions & 7 deletions res/app/settings/groups/groups.pug
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
Copyright © 2019 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
Copyright © 2019-2024 code initially contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
//

.widget-container.fluid-height.stf-groups(ng-controller='GroupsCtrl')
Expand Down Expand Up @@ -84,15 +84,15 @@
.group-line.group-actions
i.fa.fa-object-group.fa-2x.fa-fw.group-list-icon
.group-list-details.selectable
form.form-inline(name='nameForm' ng-if="group.state === 'pending' && showName")
form.form-inline(name='nameForm' ng-if="showName")
input.form-control.input-sm(
size='35' type='text' placeholder="Name"
ng-model='groupsEnv[group.id].tmpName'
ng-pattern="nameRegex"
uib-tooltip="{{'Regex syntax' | translate}}: {{::nameRegexStr}}"
tooltip-placement='top'
tooltip-popup-delay='500'
tooltip-enable="group.state === 'pending' && nameForm.$invalid"
tooltip-enable="nameForm.$invalid"
required)

button.btn.btn-sm.btn-primary.btn-check-name(
Expand All @@ -103,7 +103,7 @@

.group-list-name(
ng-bind-template='{{group.name}}'
ng-if="group.state !== 'pending' || !showName")
ng-if="!showName")

.group-list-id
span(translate) Identifier
Expand Down Expand Up @@ -134,10 +134,9 @@

button.btn.btn-xs.pull-right(
type='button'
ng-show="group.state === 'pending'"
ng-click='initTemporaryName(group); showName = !showName'
ng-class='{"btn-primary-outline": !showName && group.state === "pending",\
"btn-primary": showName && group.state === "pending"}')
ng-class='{"btn-primary-outline": !showName,\
"btn-primary": showName}')
i.fa.fa-tag
span(translate) Name

Expand Down