modpol/modpol_core/modules/change_modules.lua
Nathan Schneider 2028f1ee85 Refactored policy structure
Previously, all modules in an org were fully copied into that
org. Now, the only copy of the modules is at modpol.modules, and orgs
have a policy table at [org].policies, which overrides the config
table in any given module.
2022-02-09 22:14:26 -07:00

119 lines
3.6 KiB
Lua

--- change_modules
-- Depends on consent
-- @module change_modules
local change_modules = {
name = "Change modules (consent)",
slug = "change_modules",
desc = "Add or remove modules from the org with member consent",
hide = false;
}
change_modules.data = {
result = nil,
modules_before = {},
modules_after = {},
summary = "",
}
change_modules.config = {
}
--- Initiate change in modules.
-- Either adds or removes module depending on user input
-- @function change_modules:initiate
-- @param result Callback if this module is embedded in other modules
function change_modules:initiate(result)
self.data.result = result
self.data.add_modules = {}
self.data.remove_modules = {}
local modules_before = {}
local modules_after = {}
-- generate self.config.modules table
for k, module in pairs(modpol.modules) do
if not modpol.modules[module.slug].hide then
local in_org = false
if self.org.policies[module.slug] then
in_org = true
end
table.insert(
modules_before,
{module.name.." ["..module.slug.."]", in_org})
end
end
-- send query to user
modpol.interactions.checkbox_query(
self.initiator,
"Check the modules to activate in this org:",
modules_before,
function(input)
-- identify changes
modules_after = input
for i,v in ipairs(modules_after) do
if v[2] ~= modules_before[i][2] then
if v[2] then
table.insert(self.data.add_modules, v[1])
else
table.insert(self.data.remove_modules, v[1])
end
end
end
-- abort if no changes
if #self.data.add_modules == 0
and #self.data.remove_modules == 0 then
modpol.interactions.message(
self.initiator, "No module changes proposed")
modpol.interactions.org_dashboard(
self.initiator, self.org.id)
self.org:delete_process(self.id)
return
end
-- proceed with consent
local query = "Accept module changes in org "..
self.org.name.."?"
self.data.summary = ""
if #self.data.add_modules > 0 then
self.data.summary = self.data.summary.."\nAdd: "..
table.concat(self.data.add_modules,", ")
elseif #self.data.remove_modules > 0 then
self.data.summary = "\nRemove: "..
table.concat(self.data.remove_modules,", ")
end
self:call_module(
"consent",
self.initiator,
{
prompt = query..self.data.summary,
votes_required = #self.org.members
},
function()
self:implement_change()
end)
modpol.interactions.org_dashboard(
self.initiator, self.org.id)
end)
end
function change_modules:implement_change()
for i,v in ipairs(self.data.add_modules) do
local slug = string.match(v,"%[(.+)%]")
self.org.policies[slug] = {}
table.sort(self.org.policies)
end
for i,v in ipairs(self.data.remove_modules) do
local slug = string.match(v,"%[(.+)%]")
self.org.policies[slug] = nil
table.sort(self.org.policies)
end
-- announce and shut down
modpol.interactions.message_org(
self.initiator,
self.org.id,
"Module changes applied to org "..self.org.name..":"..
self.data.summary)
if self.data.result then self.data.result() end
self.org:delete_process(self.id)
end
modpol.modules.change_modules = change_modules