797d6bc04a
* initial commit * turn on featureflag * additional fixes * update for using FullCalendar * update to allow both calendars * fix dnd, remove log messages * fix lint, unit tests * dates should use themselves for timezone offset * fix for tests * remove react-big-calendar * remove react-big-calendar * fix for handling feature flags changing * clean up * remove unit test * update tests * fix tests * lint fixes * add creating event, fixes * linter fixes * clean up * add unit tests * fixes * update snapshots * update test * update snapshot * disable test for now, timezone changes labels * remove test to get to build * remove snapshot * feedback updates * use getConfig instead * linter fix * more linter * revert changes * some fixes for issues * fix for displaying new calendar * fix for displaying new calendar * add properties to cards * add properties to cards * read only implementation * i18-extract * implement unit tests * implement unit tests * fix test * remove log statements * remove feature flag from config * updated icons * Updating icons for calendar mvp * Revert "Updating icons for calendar mvp" This reverts commite16e715e8a
. * Revert "updated icons" This reverts commit120b7b0b96
. * update for code reviews * fix linter * more feedback updates * fix some styling * fix lint errors * Updating css * Updating calendar css * update for lint errors Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>
94 lines
3.4 KiB
Go
94 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"reflect"
|
|
)
|
|
|
|
// configuration captures the plugin's external configuration as exposed in the Mattermost server
|
|
// configuration, as well as values computed from the configuration. Any public fields will be
|
|
// deserialized from the Mattermost server configuration in OnConfigurationChange.
|
|
//
|
|
// As plugins are inherently concurrent (hooks being called asynchronously), and the plugin
|
|
// configuration can change at any time, access to the configuration must be synchronized. The
|
|
// strategy used in this plugin is to guard a pointer to the configuration, and clone the entire
|
|
// struct whenever it changes. You may replace this with whatever strategy you choose.
|
|
//
|
|
// If you add non-reference types to your configuration struct, be sure to rewrite Clone as a deep
|
|
// copy appropriate for your types.
|
|
type configuration struct {
|
|
EnablePublicSharedBoards bool
|
|
}
|
|
|
|
// Clone shallow copies the configuration. Your implementation may require a deep copy if
|
|
// your configuration has reference types.
|
|
func (c *configuration) Clone() *configuration {
|
|
var clone = *c
|
|
return &clone
|
|
}
|
|
|
|
// getConfiguration retrieves the active configuration under lock, making it safe to use
|
|
// concurrently. The active configuration may change underneath the client of this method, but
|
|
// the struct returned by this API call is considered immutable.
|
|
func (p *Plugin) getConfiguration() *configuration {
|
|
p.configurationLock.RLock()
|
|
defer p.configurationLock.RUnlock()
|
|
|
|
if p.configuration == nil {
|
|
return &configuration{}
|
|
}
|
|
|
|
return p.configuration
|
|
}
|
|
|
|
// setConfiguration replaces the active configuration under lock.
|
|
//
|
|
// Do not call setConfiguration while holding the configurationLock, as sync.Mutex is not
|
|
// reentrant. In particular, avoid using the plugin API entirely, as this may in turn trigger a
|
|
// hook back into the plugin. If that hook attempts to acquire this lock, a deadlock may occur.
|
|
//
|
|
// This method panics if setConfiguration is called with the existing configuration. This almost
|
|
// certainly means that the configuration was modified without being cloned and may result in
|
|
// an unsafe access.
|
|
func (p *Plugin) setConfiguration(configuration *configuration) {
|
|
p.configurationLock.Lock()
|
|
defer p.configurationLock.Unlock()
|
|
|
|
if configuration != nil && p.configuration == configuration {
|
|
// Ignore assignment if the configuration struct is empty. Go will optimize the
|
|
// allocation for same to point at the same memory address, breaking the check
|
|
// above.
|
|
if reflect.ValueOf(*configuration).NumField() == 0 {
|
|
return
|
|
}
|
|
|
|
panic("setConfiguration called with the existing configuration")
|
|
}
|
|
|
|
p.configuration = configuration
|
|
}
|
|
|
|
// OnConfigurationChange is invoked when configuration changes may have been made.
|
|
func (p *Plugin) OnConfigurationChange() error { //nolint
|
|
// Have we been setup by OnActivate?
|
|
if p.wsPluginAdapter == nil {
|
|
return nil
|
|
}
|
|
mmconfig := p.API.GetConfig()
|
|
|
|
// handle plugin configuration settings
|
|
enableShareBoards := false
|
|
if mmconfig.PluginSettings.Plugins[pluginName][sharedBoardsName] == true {
|
|
enableShareBoards = true
|
|
}
|
|
configuration := &configuration{
|
|
EnablePublicSharedBoards: enableShareBoards,
|
|
}
|
|
p.setConfiguration(configuration)
|
|
p.server.Config().EnablePublicSharedBoards = enableShareBoards
|
|
|
|
// handle feature flags
|
|
p.server.Config().FeatureFlags = parseFeatureFlags(mmconfig.FeatureFlags.ToMap())
|
|
p.server.UpdateAppConfig()
|
|
p.wsPluginAdapter.BroadcastConfigChange(*p.server.App().GetClientConfig())
|
|
return nil
|
|
}
|