feat: G15Office job, widget settings and submissions admin, embed.js and the settings importer

- SyncG15Office files each submission as a G15Office task with its screenshot through a fetchguard client limited to the configured host; a River job with 3 attempts, PHP's messages on failure, nothing sent when unconfigured
- the replay of PHP's recorded G15Office exchange (classes/testdata) asserts the task JSON, headers and the screenshot part
- settings screen (cabana field types only), read-only submissions list, manage_settings permission and navigation
- embed.js served byte for byte at /plugins/golem15/feedback/assets/js/embed.js
- feedback:import-settings copies the WinterCMS settings row once
This commit is contained in:
Jakub Zych
2026-10-04 00:22:08 +02:00
parent 92e1b4e09c
commit af5d77c997
19 changed files with 2285 additions and 6 deletions

View File

@@ -14,10 +14,12 @@ import (
"net/http"
"time"
"git.golem15.com/golem15/sm-feedback-plugin/console"
"git.golem15.com/golem15/sm-feedback-plugin/models"
"git.golem15.com/golem15/sm-feedback-plugin/updates"
userclasses "git.golem15.com/golem15/sm-user-plugin/classes"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/bonfire"
"git.golem15.com/golem15/summercms/modules/pact"
"git.golem15.com/golem15/summercms/modules/party"
"git.golem15.com/golem15/summercms/modules/surf"
@@ -32,6 +34,7 @@ var (
_ pact.HasMigrations = (*Plugin)(nil)
_ pact.HasModels = (*Plugin)(nil)
_ pact.HasRoutes = (*Plugin)(nil)
_ pact.HasCommands = (*Plugin)(nil)
_ surf.BucketProvider = (*Plugin)(nil)
)
@@ -102,6 +105,11 @@ func (p *Plugin) Migrations() []*gormigrate.Migration { return updates.All() }
// Models is Submission, UserPreference and Settings.
func (p *Plugin) Models() []any { return models.All() }
// Commands is feedback:import-settings.
func (p *Plugin) Commands() []bonfire.Command {
return []bonfire.Command{console.ImportSettings(p.app)}
}
// Buckets are the widget routes' limits by client IP (behind the trusted
// proxies): 60 config reads and 10 submissions a minute.
func (p *Plugin) Buckets() map[string]surf.Bucket {