123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- package views
- import (
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "github.com/qor5/admin/presets"
- "github.com/qor5/admin/presets/actions"
- "github.com/qor5/admin/publish"
- "github.com/qor5/admin/utils"
- . "github.com/qor5/ui/vuetify"
- "github.com/qor5/web"
- "github.com/qor5/x/i18n"
- "github.com/sunfmin/reflectutils"
- h "github.com/theplant/htmlgo"
- "gorm.io/gorm"
- )
- func sidePanel(db *gorm.DB, mb *presets.ModelBuilder) presets.ComponentFunc {
- return func(ctx *web.EventContext) h.HTMLComponent {
- var (
- msgr = i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages)
- activeClass = "primary white--text"
- selected = ctx.R.FormValue("selected")
- selectVersionsEvent = web.Plaid().EventFunc(selectVersionsEvent).Query(presets.ParamID, ctx.R.FormValue(presets.ParamID)).Query("selected", web.Var("$event")).Go()
- selectItems = []map[string]string{
- {"text": msgr.AllVersions, "value": "all-versions"},
- {"text": msgr.NamedVersions, "value": "named-versions"},
- }
- )
- table, currentVersion, err := versionListTable(db, mb, msgr, ctx)
- if err != nil || table == nil {
- return nil
- }
- if selected == "" {
- selected = "all-versions"
- }
- var onlineVersionComp h.HTMLComponent
- if currentVersion != nil {
- onlineVersionComp = VSimpleTable(h.Tbody(h.Tr(h.Td(h.Text(currentVersion.VersionName)), h.Td(h.Text(currentVersion.Status))).Class(activeClass)))
- }
- return h.Div(
- VCard(
- VCardTitle(h.Text(msgr.OnlineVersion)),
- onlineVersionComp,
- ),
- h.Br(),
- VCard(
- VCardTitle(
- h.Text(msgr.VersionsList),
- ).Attr("style", "padding-bottom: 0px;"),
- VCardText(
- VSelect().
- Items(selectItems).
- Value(selected).
- On("change", selectVersionsEvent),
- ).Attr("style", "padding-bottom: 0px;"),
- web.Portal(
- table,
- ).Name("versions-list"),
- ),
- )
- }
- }
- func findVersionItems(db *gorm.DB, mb *presets.ModelBuilder, ctx *web.EventContext, paramId string) (list interface{}, err error) {
- list = mb.NewModelSlice()
- primaryKeys, err := utils.GetPrimaryKeys(mb.NewModel(), db)
- if err != nil {
- return
- }
- err = utils.PrimarySluggerWhere(db.Session(&gorm.Session{NewDB: true}).Select(strings.Join(primaryKeys, ",")), mb.NewModel(), paramId, "version").
- Order("version DESC").
- Find(list).
- Error
- return list, err
- }
- type versionListTableItem struct {
- ID string
- Version string
- VersionName string
- Status string
- ItemClass string
- ParamID string
- }
- func versionListTable(db *gorm.DB, mb *presets.ModelBuilder, msgr *Messages, ctx *web.EventContext) (table h.HTMLComponent, currentVersion *versionListTableItem, err error) {
- var obj = mb.NewModel()
- slugger := obj.(presets.SlugDecoder)
- paramID := ctx.R.FormValue(presets.ParamID)
- if paramID == "" {
- return nil, nil, nil
- }
- cs := slugger.PrimaryColumnValuesBySlug(paramID)
- id, currentVersionName := cs["id"], cs["version"]
- if id == "" || currentVersionName == "" {
- return nil, nil, fmt.Errorf("invalid version id: %s", paramID)
- }
- var (
- versions []*versionListTableItem
- namedVersions []*versionListTableItem
- activeClass = "vx-list-item--active primary--text"
- selected = ctx.R.FormValue("selected")
- page = ctx.R.FormValue("page")
- currentPage = 1
- )
- if page != "" {
- if p, err := strconv.Atoi(page); err == nil {
- currentPage = p
- }
- }
- var results = mb.NewModelSlice()
- primaryKeys, err := utils.GetPrimaryKeys(mb.NewModel(), db)
- if err != nil {
- return
- }
- err = utils.PrimarySluggerWhere(db.Session(&gorm.Session{NewDB: true}).Select(strings.Join(append(primaryKeys, "version_name", "status"), ",")), mb.NewModel(), paramID, "version").
- Order("version DESC").
- Find(results).Error
- if err != nil {
- panic(err)
- }
- vO := reflect.ValueOf(results).Elem()
- for i := 0; i < vO.Len(); i++ {
- v := vO.Index(i).Interface()
- version := &versionListTableItem{}
- ID, _ := reflectutils.Get(v, "ID")
- version.ID = fmt.Sprintf("%v", ID)
- version.Version = v.(publish.VersionInterface).GetVersion()
- version.VersionName = v.(publish.VersionInterface).GetVersionName()
- version.Status = v.(publish.StatusInterface).GetStatus()
- if version.Status == publish.StatusOnline {
- currentVersion = version
- }
- version.Status = GetStatusText(version.Status, msgr)
- if version.Version == currentVersionName {
- version.ItemClass = activeClass
- }
- if version.VersionName == "" {
- version.VersionName = version.Version
- }
- if version.VersionName != version.Version {
- namedVersions = append(namedVersions, version)
- }
- version.ParamID = v.(presets.SlugEncoder).PrimarySlug()
- versions = append(versions, version)
- }
- if selected == "named-versions" {
- versions = namedVersions
- }
- var (
- swithVersionEvent = web.Plaid().EventFunc(switchVersionEvent).Query(presets.ParamID, web.Var(`$event.ParamID`)).Query("selected", selected).Query("page", web.Var("locals.versionPage")).Go()
- deleteVersionEvent = web.Plaid().EventFunc(actions.DeleteConfirmation).Query(presets.ParamID, web.Var(`props.item.ParamID`)).
- Query(presets.ParamAfterDeleteEvent, afterDeleteVersionEvent).
- Query("current_selected_id", ctx.R.FormValue(presets.ParamID)).
- Query("selected", selected).
- Query("page", web.Var("locals.versionPage")).
- Go() + ";event.stopPropagation();"
- renameVersionEvent = web.Plaid().EventFunc(renameVersionEvent).Query(presets.ParamID, web.Var(`props.item.ParamID`)).Query("name", web.Var("props.item.VersionName")).Go()
- )
- table = web.Scope(
- VDataTable(
- web.Slot(
- VEditDialog(
- VIcon("edit").Small(true).Class("mr-2").Attr(":class", "props.item.ItemClass"),
- VIcon("delete").Small(true).Class("mr-2").Attr("@click", deleteVersionEvent).Attr(":class", "props.item.ItemClass"),
- web.Slot(
- VTextField().Attr("v-model", "props.item.VersionName").Label(msgr.RenameVersion),
- ).Name("input"),
- ).Bind("return-value.sync", "props.item.VersionName").On("save", renameVersionEvent).Large(true).Transition("slide-x-reverse-transition"),
- ).Name("item.Actions").Scope("props"),
- ).
- Items(versions).
- Headers(
- []map[string]interface{}{
- {"text": "VersionName", "value": "VersionName"},
- {"text": "Status", "value": "Status"},
- {"text": "Actions", "value": "Actions"},
- }).
- HideDefaultHeader(true).
- HideDefaultFooter(len(versions) <= 10).
- On("click:row", swithVersionEvent).
- On("pagination", "locals.versionPage = $event.page").
- ItemClass("ItemClass").
- FooterProps(
- map[string]interface{}{
- "items-per-page-options": []int{5, 10, 20},
- "show-first-last-page": true,
- "items-per-page-text": "",
- "page-text": "",
- },
- ).
- Page(currentPage),
- ).Init(fmt.Sprintf(`{versionPage: %d}`, currentPage)).
- VSlot("{ locals }")
- return table, currentVersion, nil
- }
- func switchVersionAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder) web.EventFunc {
- return func(ctx *web.EventContext) (r web.EventResponse, err error) {
- paramId := ctx.R.FormValue(presets.ParamID)
- eb := mb.Editing()
- obj := mb.NewModel()
- obj, err = eb.Fetcher(obj, paramId, ctx)
- eb.UpdateOverlayContent(ctx, &r, obj, "", err)
- if ctx.Queries().Get("no_msg") == "true" {
- return
- }
- msgr := i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages)
- presets.ShowMessage(&r, msgr.SwitchedToNewVersion, "")
- return
- }
- }
- func saveNewVersionAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder) web.EventFunc {
- return func(ctx *web.EventContext) (r web.EventResponse, err error) {
- var toObj = mb.NewModel()
- slugger := toObj.(presets.SlugDecoder)
- currentVersionName := slugger.PrimaryColumnValuesBySlug(ctx.R.FormValue(presets.ParamID))["version"]
- paramID := ctx.R.FormValue(presets.ParamID)
- me := mb.Editing()
- vErr := me.RunSetterFunc(ctx, false, toObj)
- if vErr.HaveErrors() {
- me.UpdateOverlayContent(ctx, &r, toObj, "", &vErr)
- return
- }
- var fromObj = mb.NewModel()
- utils.PrimarySluggerWhere(db, mb.NewModel(), paramID).First(fromObj)
- if err = utils.SetPrimaryKeys(fromObj, toObj, db, paramID); err != nil {
- return
- }
- if err = reflectutils.Set(toObj, "Version.ParentVersion", currentVersionName); err != nil {
- return
- }
- if me.Validator != nil {
- if vErr := me.Validator(toObj, ctx); vErr.HaveErrors() {
- me.UpdateOverlayContent(ctx, &r, toObj, "", &vErr)
- return
- }
- }
- if err = me.Saver(toObj, paramID, ctx); err != nil {
- me.UpdateOverlayContent(ctx, &r, toObj, "", err)
- return
- }
- msgr := i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages)
- presets.ShowMessage(&r, msgr.SuccessfullyCreated, "")
- if ctx.R.URL.Query().Get(presets.ParamInDialog) == "true" {
- web.AppendVarsScripts(&r,
- "vars.presetsDialog = false",
- web.Plaid().
- URL(ctx.R.RequestURI).
- EventFunc(actions.UpdateListingDialog).
- StringQuery(ctx.R.URL.Query().Get(presets.ParamListingQueries)).
- Go(),
- )
- } else {
- r.Reload = true
- }
- return
- }
- }
- func duplicateVersionAction(db *gorm.DB, mb *presets.ModelBuilder, publisher *publish.Builder) web.EventFunc {
- return func(ctx *web.EventContext) (r web.EventResponse, err error) {
- var toObj = mb.NewModel()
- slugger := toObj.(presets.SlugDecoder)
- currentVersionName := slugger.PrimaryColumnValuesBySlug(ctx.R.FormValue(presets.ParamID))["version"]
- paramID := ctx.R.FormValue(presets.ParamID)
- me := mb.Editing()
- vErr := me.RunSetterFunc(ctx, false, toObj)
- if vErr.HaveErrors() {
- presets.ShowMessage(&r, vErr.Error(), "error")
- return
- }
- var fromObj = mb.NewModel()
- utils.PrimarySluggerWhere(db, mb.NewModel(), paramID).First(fromObj)
- if err = utils.SetPrimaryKeys(fromObj, toObj, db, paramID); err != nil {
- presets.ShowMessage(&r, err.Error(), "error")
- return
- }
- if err = reflectutils.Set(toObj, "Version.ParentVersion", currentVersionName); err != nil {
- presets.ShowMessage(&r, err.Error(), "error")
- return
- }
- if me.Validator != nil {
- if vErr := me.Validator(toObj, ctx); vErr.HaveErrors() {
- presets.ShowMessage(&r, vErr.Error(), "error")
- return
- }
- }
- if err = me.Saver(toObj, paramID, ctx); err != nil {
- presets.ShowMessage(&r, err.Error(), "error")
- return
- }
- msgr := i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages)
- presets.ShowMessage(&r, msgr.SuccessfullyCreated, "")
- se := toObj.(presets.SlugEncoder)
- newQueries := ctx.Queries()
- newQueries.Del(presets.ParamID)
- r.PushState = web.Location(newQueries).URL(mb.Info().DetailingHref(se.PrimarySlug()))
- return
- }
- }
- func searcher(db *gorm.DB, mb *presets.ModelBuilder) presets.SearchFunc {
- return func(obj interface{}, params *presets.SearchParams, ctx *web.EventContext) (r interface{}, totalCount int, err error) {
- ilike := "ILIKE"
- if db.Dialector.Name() == "sqlite" {
- ilike = "LIKE"
- }
- wh := db.Model(obj)
- if len(params.KeywordColumns) > 0 && len(params.Keyword) > 0 {
- var segs []string
- var args []interface{}
- for _, c := range params.KeywordColumns {
- segs = append(segs, fmt.Sprintf("%s %s ?", c, ilike))
- args = append(args, fmt.Sprintf("%%%s%%", params.Keyword))
- }
- wh = wh.Where(strings.Join(segs, " OR "), args...)
- }
- for _, cond := range params.SQLConditions {
- wh = wh.Where(strings.Replace(cond.Query, " ILIKE ", " "+ilike+" ", -1), cond.Args...)
- }
- stmt := &gorm.Statement{DB: db}
- stmt.Parse(mb.NewModel())
- tn := stmt.Schema.Table
- var pks []string
- condition := ""
- var c int64
- for _, f := range stmt.Schema.Fields {
- if f.Name == "DeletedAt" {
- condition = "WHERE deleted_at IS NULL"
- }
- }
- for _, f := range stmt.Schema.PrimaryFields {
- if f.Name != "Version" {
- pks = append(pks, f.DBName)
- }
- }
- pkc := strings.Join(pks, ",")
- sql := fmt.Sprintf("(%v,version) IN (SELECT %v, MAX(version) FROM %v %v GROUP BY %v)", pkc, pkc, tn, condition, pkc)
- if err = wh.Where(sql).Count(&c).Error; err != nil {
- return
- }
- totalCount = int(c)
- if params.PerPage > 0 {
- wh = wh.Limit(int(params.PerPage))
- page := params.Page
- if page == 0 {
- page = 1
- }
- offset := (page - 1) * params.PerPage
- wh = wh.Offset(int(offset))
- }
- orderBy := params.OrderBy
- if len(orderBy) > 0 {
- wh = wh.Order(orderBy)
- }
- if err = wh.Find(obj).Error; err != nil {
- return
- }
- r = reflect.ValueOf(obj).Elem().Interface()
- return
- }
- }
- func versionActionsFunc(m *presets.ModelBuilder) presets.ObjectComponentFunc {
- return func(obj interface{}, ctx *web.EventContext) h.HTMLComponent {
- gmsgr := presets.MustGetMessages(ctx.R)
- var buttonLabel = gmsgr.Create
- m.RightDrawerWidth("800")
- var disableUpdateBtn bool
- var isCreateBtn = true
- if ctx.R.FormValue(presets.ParamID) != "" {
- isCreateBtn = false
- buttonLabel = gmsgr.Update
- m.RightDrawerWidth("1200")
- disableUpdateBtn = m.Info().Verifier().Do(presets.PermUpdate).ObjectOn(obj).WithReq(ctx.R).IsAllowed() != nil
- }
- msgr := i18n.MustGetModuleMessages(ctx.R, I18nPublishKey, Messages_en_US).(*Messages)
- updateBtn := VBtn(buttonLabel).
- Color("primary").
- Attr("@click", web.Plaid().
- EventFunc(actions.Update).
- Queries(ctx.Queries()).
- Query(presets.ParamID, ctx.R.FormValue(presets.ParamID)).
- URL(m.Info().ListingHref()).
- Go(),
- )
- if disableUpdateBtn {
- updateBtn = updateBtn.Disabled(disableUpdateBtn)
- } else {
- updateBtn = updateBtn.Attr(":disabled", "isFetching").Attr(":loading", "isFetching")
- }
- if isCreateBtn {
- return h.Components(
- VSpacer(),
- updateBtn,
- )
- }
- saveNewVersionBtn := VBtn(msgr.SaveAsNewVersion).
- Color("secondary").
- Attr("@click", web.Plaid().
- EventFunc(SaveNewVersionEvent).
- Queries(ctx.Queries()).
- Query(presets.ParamID, ctx.R.FormValue(presets.ParamID)).
- URL(m.Info().ListingHref()).
- Go(),
- )
- if disableUpdateBtn {
- saveNewVersionBtn = saveNewVersionBtn.Disabled(disableUpdateBtn)
- } else {
- saveNewVersionBtn = saveNewVersionBtn.Attr(":disabled", "isFetching").Attr(":loading", "isFetching")
- }
- return h.Components(
- VSpacer(),
- saveNewVersionBtn,
- updateBtn,
- )
- }
- }
|