diff --git a/conference.go b/conference.go index 3c22619..ed75b62 100644 --- a/conference.go +++ b/conference.go @@ -40,15 +40,18 @@ func Conferences(ctxt ui.AmContext) (string, any) { ctxt.VarMap().Set("commName", comm.Name) ctxt.VarMap().Set("commAlias", comm.Alias) ctxt.SetFrameTitle("Conference Listing: " + comm.Name) - clist, err := database.AmGetCommunityConferences(ctxt.Ctx(), comm.Id, - comm.TestPermission("Community.ShowHiddenObjects", ctxt.EffectiveLevel())) + clist, err := database.AmListConferences(ctxt.Ctx(), comm.Id, comm.TestPermission("Community.ShowHiddenObjects", ctxt.EffectiveLevel())) if err != nil { return "error", err } ctxt.VarMap().Set("conferences", clist) if len(clist) > 0 { newflag := make([]bool, len(clist)) - for i, conf := range clist { + for i, c := range clist { + conf, err := c.Conf(ctxt.Ctx()) + if err != nil { + return "error", err + } msgCount, err := conf.UnreadMessages(ctxt.Ctx(), ctxt.CurrentUser()) if err != nil { return "error", err diff --git a/conferenceadmin.go b/conferenceadmin.go index cdf6e87..6910be6 100644 --- a/conferenceadmin.go +++ b/conferenceadmin.go @@ -789,3 +789,43 @@ func CreateConference(ctxt ui.AmContext) (string, any) { log.Infof("Created conference '%s'", conf.Name) return "redirect", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, alias) } + +/* ManageConferenceList displays the list for managing conferences. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Command string dictating what to be rendered. + * Data as a parameter for the command string. + */ +func ManageConferenceList(ctxt ui.AmContext) (string, any) { + comm := ctxt.CurrentCommunity() + if !comm.TestPermission("Community.Create", ctxt.EffectiveLevel()) { + return "error", ENOPERM + } + + clist, err := database.AmListConferences(ctxt.Ctx(), comm.Id, true) + if err != nil { + return "error", err + } + + ntopics := make([]int, len(clist)) + nposts := make([]int, len(clist)) + for i, c := range clist { + conf, err := c.Conf(ctxt.Ctx()) + if err != nil { + return "error", err + } + ntopics[i], nposts[i], err = conf.Stats(ctxt.Ctx()) + if err != nil { + return "error", err + } + } + ctxt.VarMap().Set("confs", clist) + ctxt.VarMap().Set("ntopics", ntopics) + ctxt.VarMap().Set("nposts", nposts) + ctxt.VarMap().Set("commName", comm.Name) + ctxt.VarMap().Set("baseUrl", fmt.Sprintf("/comm/%s/manage_conf", comm.Alias)) + ctxt.VarMap().Set("returnUrl", fmt.Sprintf("/comm/%s/conf", comm.Alias)) + ctxt.SetFrameTitle("Manage Conference List") + return "framed", "manage_conflist.jet" +} diff --git a/database/conference.go b/database/conference.go index 15eeafa..be3ce60 100644 --- a/database/conference.go +++ b/database/conference.go @@ -70,6 +70,23 @@ type ConferenceProperties struct { Data *string `db:"data"` // property data } +// ConferenceSummary represents summary information about a conference. +type ConferenceSummary struct { + ConfId int32 // conference ID + Name string // conference name + Alias string // an alias for the conference + LastUpdate *time.Time // last update date/time + Hosts []string // usernames of the hosts + Description string // description string + Sequence int16 // sequence number in the list + Hidden bool // hidden in list? +} + +// Conf gets the conference from the summary. +func (cs *ConferenceSummary) Conf(ctx context.Context) (*Conference, error) { + return AmGetConference(ctx, cs.ConfId) +} + // Default spacing between sequence numbers in commtoconf table. const COMMTOCONF_SEQ_SPACING = 10 @@ -786,6 +803,15 @@ func (c *Conference) GetActiveUserEMailAddrs(ctx context.Context, userSelect, da return rc, nil } +// Stats retrieves the number of topics and posts in this conference. +func (c *Conference) Stats(ctx context.Context) (int, int, error) { + row := amdb.QueryRowContext(ctx, "SELECT COUNT(*), SUM(top_message + 1) FROM topics WHERE confid = ?", c.ConfId) + ntopic := 0 + npost := 0 + err := row.Scan(&ntopic, &npost) + return ntopic, npost, err +} + /* AmGetConference returns a conference given its ID. * Parameters: * ctx - Standard Go context value. @@ -864,37 +890,44 @@ func AmGetConferenceByAliasInCommunity(ctx context.Context, cid int32, alias str return nil, err } -/* AmGetCommunityConferences returns all conferences for a given community. +/* AmListConferences returns all conferences for a given community. * Parameters: * ctx - Standard Go context value. * cid - Community ID to get conferences for. * showHidden - true to show hidden conferences. * Returns: - * Array containing the COnference pointers, or nil. + * Array containing the ConferenceSummary pointers, or nil. * Stanbard Go error status. */ -func AmGetCommunityConferences(ctx context.Context, cid int32, showHidden bool) ([]*Conference, error) { +func AmListConferences(ctx context.Context, cid int32, showHidden bool) ([]*ConferenceSummary, error) { q := "" if !showHidden { q = " AND x.hide_list = 0" } - rs, err := amdb.QueryContext(ctx, `SELECT x.confid FROM commtoconf x, confs c WHERE x.confid = c.confid - AND x.commid = ?`+q+" ORDER BY x.sequence, c.name", cid) + rs, err := amdb.QueryContext(ctx, `SELECT x.confid, c.name, c.lastupdate, c.descr, x.sequence, x.hide_list FROM commtoconf x, confs c + WHERE x.confid = c.confid AND x.commid = ?`+q+" ORDER BY x.sequence, c.name", cid) if err != nil { return nil, err } - rc := make([]*Conference, 0, 6) + rc := make([]*ConferenceSummary, 0) for rs.Next() { - var confid int32 - if err = rs.Scan(&confid); err == nil { - conf, err := AmGetConference(ctx, confid) - if err == nil { - rc = append(rc, conf) - } else { - log.Errorf("AmGetCommunityConferences conference error: %v", err) - } + var cs ConferenceSummary + if err = rs.Scan(&(cs.ConfId), &(cs.Name), &(cs.LastUpdate), &(cs.Description), &(cs.Sequence), &(cs.Hidden)); err == nil { + rc = append(rc, &cs) } else { - log.Errorf("AmGetCommunityConferences scan error: %v", err) + return nil, err + } + } + for i := range rc { + row := amdb.QueryRowContext(ctx, "SELECT alias FROM confalias WHERE confid = ?", rc[i].ConfId) + err = row.Scan(&(rc[i].Alias)) + if err != nil { + return nil, err + } + err = amdb.SelectContext(ctx, &(rc[i].Hosts), `SELECT u.username FROM confmember m, users u WHERE u.uid = m.uid AND m.confid = ? + AND m.granted_lvl = ? ORDER BY u.username`, rc[i].ConfId, AmRole("Conference.Host").Level()) + if err != nil { + return nil, err } } return rc, nil diff --git a/main.go b/main.go index 4a71490..e503e8c 100644 --- a/main.go +++ b/main.go @@ -117,6 +117,7 @@ func setupEcho() *echo.Echo { // conference group commGroup.GET("/create_conf", ui.AmWrap(CreateConferenceForm)) commGroup.POST("/create_conf", ui.AmWrap(CreateConference)) + commGroup.GET("/manage_conf", ui.AmWrap(ManageConferenceList)) commGroup.GET("/conf", ui.AmWrap(Conferences), ui.ValidateConference) confGroup := commGroup.Group("/conf/:confid", ui.ValidateConference, ui.SetConference) confGroup.GET("", ui.AmWrap(Topics)) diff --git a/ui/views/conflist.jet b/ui/views/conflist.jet index 7f5669f..afe4042 100644 --- a/ui/views/conflist.jet +++ b/ui/views/conflist.jet @@ -23,7 +23,7 @@ 🟣
| + | Conference Name | +Topics | +Posts | +|||
|---|---|---|---|---|---|---|
| + {{ if c.Hidden }} + + ⚫ + + {{ else }} + + 🟢 + + {{ end }} + | ++ {{ if i < (len(confs) - 1) }} + ⬇️ + {{ else }} + + {{ end }} + | ++ {{ if i > 0 }} + ⬆️ + {{ else }} + + {{ end }} + | ++ ❌ + | +
+ {{ c.Name }}
+ |
+
+ {{ ntopics[i] }}
+ |
+
+ {{ nposts[i] }}
+ |
+