diff --git a/multipanels.go b/multipanels.go index 4a93eb2..93c5bd7 100644 --- a/multipanels.go +++ b/multipanels.go @@ -15,6 +15,9 @@ type MultiPanel struct { SelectMenu bool `json:"select_menu"` SelectMenuPlaceholder *string `json:"select_menu_placeholder"` Embed *CustomEmbedWithFields `json:"embed"` + UsesComponentsV2 bool `json:"uses_components_v2"` + Components *string `json:"components"` + Name *string `json:"name"` } type MultiPanelTable struct { @@ -40,13 +43,16 @@ CREATE TABLE IF NOT EXISTS multi_panels( PRIMARY KEY("id") ); CREATE INDEX IF NOT EXISTS multi_panels_guild_id ON multi_panels("guild_id"); -CREATE INDEX IF NOT EXISTS multi_panels_message_id ON multi_panels("message_id");` +CREATE INDEX IF NOT EXISTS multi_panels_message_id ON multi_panels("message_id"); +ALTER TABLE multi_panels ADD COLUMN IF NOT EXISTS "uses_components_v2" bool NOT NULL DEFAULT false; +ALTER TABLE multi_panels ADD COLUMN IF NOT EXISTS "components" JSONB DEFAULT NULL; +ALTER TABLE multi_panels ADD COLUMN IF NOT EXISTS "name" text DEFAULT NULL;` } func (p *MultiPanelTable) Get(ctx context.Context, id int) (MultiPanel, bool, error) { query := ` SELECT - "id", "message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed" + "id", "message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed", "uses_components_v2", "components", "name" FROM multi_panels WHERE @@ -56,7 +62,7 @@ WHERE var panel MultiPanel var embedRaw *string err := p.QueryRow(ctx, query, id).Scan( - &panel.Id, &panel.MessageId, &panel.ChannelId, &panel.GuildId, &panel.SelectMenu, &panel.SelectMenuPlaceholder, &embedRaw, + &panel.Id, &panel.MessageId, &panel.ChannelId, &panel.GuildId, &panel.SelectMenu, &panel.SelectMenuPlaceholder, &embedRaw, &panel.UsesComponentsV2, &panel.Components, &panel.Name, ) if err != nil { @@ -79,7 +85,7 @@ WHERE func (p *MultiPanelTable) GetByMessageId(ctx context.Context, messageId uint64) (MultiPanel, bool, error) { query := ` SELECT - "id", "message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed" + "id", "message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed", "uses_components_v2", "components", "name" FROM multi_panels WHERE @@ -89,7 +95,7 @@ WHERE var panel MultiPanel var embedRaw *string err := p.QueryRow(ctx, query, messageId).Scan( - &panel.Id, &panel.MessageId, &panel.ChannelId, &panel.GuildId, &panel.SelectMenu, &panel.SelectMenuPlaceholder, &embedRaw, + &panel.Id, &panel.MessageId, &panel.ChannelId, &panel.GuildId, &panel.SelectMenu, &panel.SelectMenuPlaceholder, &embedRaw, &panel.UsesComponentsV2, &panel.Components, &panel.Name, ) if err != nil { @@ -111,9 +117,10 @@ WHERE func (p *MultiPanelTable) GetByGuild(ctx context.Context, guildId uint64) ([]MultiPanel, error) { query := ` -SELECT "id", "message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed" +SELECT "id", "message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed", "uses_components_v2", "components", "name" FROM multi_panels -WHERE "guild_id" = $1; +WHERE "guild_id" = $1 +ORDER BY "id" ASC; ` rows, err := p.Query(ctx, query, guildId) @@ -127,7 +134,7 @@ WHERE "guild_id" = $1; var panel MultiPanel var embedRaw *string err := rows.Scan( - &panel.Id, &panel.MessageId, &panel.ChannelId, &panel.GuildId, &panel.SelectMenu, &panel.SelectMenuPlaceholder, &embedRaw, + &panel.Id, &panel.MessageId, &panel.ChannelId, &panel.GuildId, &panel.SelectMenu, &panel.SelectMenuPlaceholder, &embedRaw, &panel.UsesComponentsV2, &panel.Components, &panel.Name, ) if err != nil { @@ -149,9 +156,9 @@ WHERE "guild_id" = $1; func (p *MultiPanelTable) Create(ctx context.Context, panel MultiPanel) (int, error) { query := ` INSERT INTO - multi_panels("message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed") + multi_panels("message_id", "channel_id", "guild_id", "select_menu", "select_menu_placeholder", "embed", "uses_components_v2", "components", "name") VALUES - ($1, $2, $3, $4, $5, $6) + ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id" ; @@ -169,7 +176,7 @@ RETURNING var multiPanelId int if err := p.QueryRow(ctx, query, - panel.MessageId, panel.ChannelId, panel.GuildId, panel.SelectMenu, panel.SelectMenuPlaceholder, embedRaw, + panel.MessageId, panel.ChannelId, panel.GuildId, panel.SelectMenu, panel.SelectMenuPlaceholder, embedRaw, panel.UsesComponentsV2, panel.Components, panel.Name, ).Scan(&multiPanelId); err != nil { return 0, err } @@ -206,6 +213,19 @@ UPDATE multi_panels return } +// Kept out of Update so callers that don't set these fields can't clear them. +func (p *MultiPanelTable) UpdateComponentsV2(ctx context.Context, multiPanelId int, usesComponentsV2 bool, components *string) error { + query := `UPDATE multi_panels SET "uses_components_v2" = $2, "components" = $3 WHERE "id" = $1;` + _, err := p.Exec(ctx, query, multiPanelId, usesComponentsV2, components) + return err +} + +func (p *MultiPanelTable) SetName(ctx context.Context, multiPanelId int, name *string) error { + query := `UPDATE multi_panels SET "name" = $2 WHERE "id" = $1;` + _, err := p.Exec(ctx, query, multiPanelId, name) + return err +} + func (p *MultiPanelTable) UpdateMessageId(ctx context.Context, multiPanelId int, messageId uint64) (err error) { query := ` UPDATE multi_panels diff --git a/multipaneltargets.go b/multipaneltargets.go index 572ae44..bc97541 100644 --- a/multipaneltargets.go +++ b/multipaneltargets.go @@ -88,6 +88,11 @@ SELECT panels.feedback_enabled, panels.support_can_view, panels.support_can_type, + panels.message_uses_components_v2, + panels.message_components, + panels.welcome_message_uses_components_v2, + panels.welcome_message_components, + panels.name, multi_panel_targets.custom_label, multi_panel_targets.description, multi_panel_targets.custom_emoji_name, @@ -136,11 +141,15 @@ SELECT multi_panels.guild_id, multi_panels.select_menu, multi_panels.select_menu_placeholder, - multi_panels.embed + multi_panels.embed, + multi_panels.uses_components_v2, + multi_panels.components, + multi_panels.name FROM multi_panel_targets INNER JOIN multi_panels ON multi_panels.id = multi_panel_targets.multi_panel_id -WHERE multi_panel_targets.panel_id = $1; +WHERE multi_panel_targets.panel_id = $1 +ORDER BY multi_panels.id ASC; ` rows, err := p.Query(ctx, query, panelId) @@ -161,6 +170,9 @@ WHERE multi_panel_targets.panel_id = $1; &multiPanel.SelectMenu, &multiPanel.SelectMenuPlaceholder, &embedRaw, + &multiPanel.UsesComponentsV2, + &multiPanel.Components, + &multiPanel.Name, ) if err != nil { diff --git a/panels.go b/panels.go index e6b6117..e08f355 100644 --- a/panels.go +++ b/panels.go @@ -50,6 +50,11 @@ type Panel struct { FeedbackEnabled bool `json:"feedback_enabled"` SupportCanView bool `json:"support_can_view"` SupportCanType bool `json:"support_can_type"` + MessageUsesComponentsV2 bool `json:"message_uses_components_v2"` + MessageComponents *string `json:"message_components"` + WelcomeMessageUsesComponentsV2 bool `json:"welcome_message_uses_components_v2"` + WelcomeMessageComponents *string `json:"welcome_message_components"` + Name *string `json:"name"` } type PanelWithWelcomeMessage struct { @@ -123,7 +128,12 @@ CREATE INDEX IF NOT EXISTS panels_guild_id ON panels("guild_id"); CREATE INDEX IF NOT EXISTS panels_message_id ON panels("message_id"); CREATE INDEX IF NOT EXISTS panels_form_id ON panels("form_id"); CREATE INDEX IF NOT EXISTS panels_guild_id_form_id ON panels("guild_id", "form_id"); -CREATE INDEX IF NOT EXISTS panels_custom_id ON panels("custom_id");` +CREATE INDEX IF NOT EXISTS panels_custom_id ON panels("custom_id"); +ALTER TABLE panels ADD COLUMN IF NOT EXISTS "message_uses_components_v2" bool NOT NULL DEFAULT false; +ALTER TABLE panels ADD COLUMN IF NOT EXISTS "message_components" JSONB DEFAULT NULL; +ALTER TABLE panels ADD COLUMN IF NOT EXISTS "welcome_message_uses_components_v2" bool NOT NULL DEFAULT false; +ALTER TABLE panels ADD COLUMN IF NOT EXISTS "welcome_message_components" JSONB DEFAULT NULL; +ALTER TABLE panels ADD COLUMN IF NOT EXISTS "name" text DEFAULT NULL;` } func (p *PanelTable) Get(ctx context.Context, messageId uint64) (panel Panel, e error) { @@ -170,7 +180,12 @@ SELECT close_confirmation, feedback_enabled, support_can_view, - support_can_type + support_can_type, + message_uses_components_v2, + message_components, + welcome_message_uses_components_v2, + welcome_message_components, + name FROM panels WHERE "message_id" = $1; ` @@ -227,7 +242,12 @@ SELECT close_confirmation, feedback_enabled, support_can_view, - support_can_type + support_can_type, + message_uses_components_v2, + message_components, + welcome_message_uses_components_v2, + welcome_message_components, + name FROM panels WHERE "panel_id" = $1; ` @@ -285,6 +305,11 @@ SELECT panels.feedback_enabled, panels.support_can_view, panels.support_can_type, + panels.message_uses_components_v2, + panels.message_components, + panels.welcome_message_uses_components_v2, + panels.welcome_message_components, + panels.name, embeds.id, embeds.guild_id, embeds.title, @@ -403,7 +428,12 @@ SELECT close_confirmation, feedback_enabled, support_can_view, - support_can_type + support_can_type, + message_uses_components_v2, + message_components, + welcome_message_uses_components_v2, + welcome_message_components, + name FROM panels WHERE "guild_id" = $1 AND "custom_id" = $2; ` @@ -463,7 +493,12 @@ SELECT close_confirmation, feedback_enabled, support_can_view, - support_can_type + support_can_type, + message_uses_components_v2, + message_components, + welcome_message_uses_components_v2, + welcome_message_components, + name FROM panels WHERE "guild_id" = $1 AND "form_id" = $2; ` @@ -523,7 +558,12 @@ SELECT panels.close_confirmation, panels.feedback_enabled, panels.support_can_view, - panels.support_can_type + panels.support_can_type, + panels.message_uses_components_v2, + panels.message_components, + panels.welcome_message_uses_components_v2, + panels.welcome_message_components, + panels.name FROM panels INNER JOIN forms ON forms.form_id = panels.form_id @@ -585,7 +625,12 @@ SELECT close_confirmation, feedback_enabled, support_can_view, - support_can_type + support_can_type, + message_uses_components_v2, + message_components, + welcome_message_uses_components_v2, + welcome_message_components, + name FROM panels WHERE "guild_id" = $1 ORDER BY "panel_id" ASC;` @@ -608,6 +653,79 @@ ORDER BY "panel_id" ASC;` return } +// For hot paths that never read the component trees, which are left nil. +func (p *PanelTable) GetByGuildWithoutComponents(ctx context.Context, guildId uint64) (panels []Panel, e error) { + query := ` +SELECT + panel_id, + message_id, + channel_id, + guild_id, + title, + content, + colour, + target_category, + emoji_name, + emoji_id, + emoji_animated, + welcome_message, + default_team, + custom_id, + image_url, + thumbnail_url, + button_style, + button_label, + form_id, + naming_scheme, + force_disabled, + disabled, + exit_survey_form_id, + pending_category, + mention_behaviour, + transcript_channel_id, + use_threads, + ticket_notification_channel, + cooldown_seconds, + ticket_limit, + hide_close_button, + hide_close_with_reason_button, + hide_claim_button, + show_in_open_command, + store_transcripts, + overflow_enabled, + overflow_category_id, + users_can_close, + close_confirmation, + feedback_enabled, + support_can_view, + support_can_type, + message_uses_components_v2, + NULL::text, + welcome_message_uses_components_v2, + NULL::text, + name +FROM panels +WHERE "guild_id" = $1 +ORDER BY "panel_id" ASC;` + + rows, err := p.Query(ctx, query, guildId) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var panel Panel + if err := rows.Scan(panel.fieldPtrs()...); err != nil { + return nil, err + } + + panels = append(panels, panel) + } + + return +} + func (p *PanelTable) GetByGuildWithWelcomeMessage(ctx context.Context, guildId uint64) (panels []PanelWithWelcomeMessage, e error) { query := ` SELECT @@ -653,6 +771,11 @@ SELECT panels.feedback_enabled, panels.support_can_view, panels.support_can_type, + panels.message_uses_components_v2, + panels.message_components, + panels.welcome_message_uses_components_v2, + panels.welcome_message_components, + panels.name, embeds.id, embeds.guild_id, embeds.title, @@ -788,9 +911,14 @@ INSERT INTO panels( "close_confirmation", "feedback_enabled", "support_can_view", - "support_can_type" + "support_can_type", + "message_uses_components_v2", + "message_components", + "welcome_message_uses_components_v2", + "welcome_message_components", + "name" ) -VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40, $41) +VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40, $41, $42, $43, $44, $45, $46) ON CONFLICT("message_id") DO NOTHING RETURNING "panel_id";` @@ -836,6 +964,11 @@ RETURNING "panel_id";` panel.FeedbackEnabled, panel.SupportCanView, panel.SupportCanType, + panel.MessageUsesComponentsV2, + panel.MessageComponents, + panel.WelcomeMessageUsesComponentsV2, + panel.WelcomeMessageComponents, + panel.Name, ).Scan(&panelId) return @@ -950,6 +1083,19 @@ UPDATE panels return err } +// Kept out of UpdateWithTx so callers that don't set these fields can't clear them. +func (p *PanelTable) UpdateComponentsV2WithTx(ctx context.Context, tx pgx.Tx, panel Panel) error { + query := `UPDATE panels SET "message_uses_components_v2" = $2, "message_components" = $3, "welcome_message_uses_components_v2" = $4, "welcome_message_components" = $5 WHERE "panel_id" = $1;` + _, err := tx.Exec(ctx, query, panel.PanelId, panel.MessageUsesComponentsV2, panel.MessageComponents, panel.WelcomeMessageUsesComponentsV2, panel.WelcomeMessageComponents) + return err +} + +func (p *PanelTable) SetNameWithTx(ctx context.Context, tx pgx.Tx, panelId int, name *string) error { + query := `UPDATE panels SET "name" = $2 WHERE "panel_id" = $1;` + _, err := tx.Exec(ctx, query, panelId, name) + return err +} + func (p *PanelTable) SetOverflow(ctx context.Context, panelId int, enabled bool, categoryId *uint64) (err error) { query := `UPDATE panels SET "overflow_enabled" = $2, "overflow_category_id" = $3 WHERE "panel_id" = $1;` _, err = p.Exec(ctx, query, panelId, enabled, categoryId) @@ -1077,5 +1223,10 @@ func (p *Panel) fieldPtrs() []interface{} { &p.FeedbackEnabled, &p.SupportCanView, &p.SupportCanType, + &p.MessageUsesComponentsV2, + &p.MessageComponents, + &p.WelcomeMessageUsesComponentsV2, + &p.WelcomeMessageComponents, + &p.Name, } } diff --git a/tickets.go b/tickets.go index ba258d7..27b6662 100644 --- a/tickets.go +++ b/tickets.go @@ -1548,12 +1548,12 @@ func secondsToDuration(secs *float64) *time.Duration { func (t *TicketTable) GetTicketCountByPanel(ctx context.Context, guildId uint64, nDays int, filter *PanelFilter) ([]PanelTicketCount, error) { query := ` -SELECT t.panel_id, COALESCE(p.title, 'No Panel'), COUNT(*) +SELECT t.panel_id, COALESCE(NULLIF(p.name, ''), p.title, 'No Panel'), COUNT(*) FROM tickets t LEFT JOIN panels p ON t.panel_id = p.panel_id WHERE t.guild_id = $1 AND t.open_time > CURRENT_DATE - ($2 - 1) * INTERVAL '1 day'` + PanelPredicate("t", 3, 4) + ` -GROUP BY t.panel_id, p.title +GROUP BY t.panel_id, p.name, p.title ORDER BY COUNT(*) DESC;` arr, unassigned, err := filter.Args()