Esempio n. 1
0
func (publish *Publish) registerWorkerJob() {
	if w := publish.WorkerScheduler; w != nil {
		if w.Admin == nil {
			fmt.Println("Need to add worker to admin first before set worker")
			return
		}

		qorWorkerArgumentResource := w.Admin.NewResource(&QorWorkerArgument{})
		qorWorkerArgumentResource.Meta(&admin.Meta{Name: "IDs", Type: "publish_job_argument", Valuer: func(record interface{}, context *qor.Context) interface{} {
			var values = map[*admin.Resource][][]string{}

			if workerArgument, ok := record.(*QorWorkerArgument); ok {
				for _, id := range workerArgument.IDs {
					if keys := strings.Split(id, "__"); len(keys) >= 2 {
						name, id := keys[0], keys[1:]
						recordRes := w.Admin.GetResource(name)
						values[recordRes] = append(values[recordRes], id)
					}
				}
			}

			return values
		}})

		w.RegisterJob(&worker.Job{
			Name:       "Publish",
			Group:      "Publish",
			Permission: roles.Deny(roles.Read, roles.Anyone),
			Handler: func(argument interface{}, job worker.QorJobInterface) error {
				if argu, ok := argument.(*QorWorkerArgument); ok {
					records := publish.searchWithPublishIDs(publish.DraftDB(), w.Admin, argu.IDs)
					publish.Logger(&workerJobLogger{job: job}).Publish(records...)
				}
				return nil
			},
			Resource: qorWorkerArgumentResource,
		})

		w.RegisterJob(&worker.Job{
			Name:       "Discard",
			Group:      "Publish",
			Permission: roles.Deny(roles.Read, roles.Anyone),
			Handler: func(argument interface{}, job worker.QorJobInterface) error {
				if argu, ok := argument.(*QorWorkerArgument); ok {
					records := publish.searchWithPublishIDs(publish.DraftDB(), w.Admin, argu.IDs)
					publish.Logger(&workerJobLogger{job: job}).Discard(records...)
				}
				return nil
			},
			Resource: qorWorkerArgumentResource,
		})
	}
}
Esempio n. 2
0
// ConfigureQorResource used to configure transition for qor admin
func (stageChangeLog *StateChangeLog) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		if res.Config.Permission == nil {
			res.Config.Permission = roles.Deny(roles.Update, roles.Anyone).Deny(roles.Create, roles.Anyone)
		} else {
			res.Config.Permission = res.Config.Permission.Deny(roles.Update, roles.Anyone).Deny(roles.Create, roles.Anyone)
		}
	}
}
Esempio n. 3
0
// ConfigureQorResource used to configure transition for qor admin
func (transition *Transition) ConfigureQorResource(res resource.Resourcer) {
	if res, ok := res.(*admin.Resource); ok {
		if res.GetMeta("State") == nil {
			res.Meta(&admin.Meta{Name: "State", Permission: roles.Deny(roles.Update, roles.Anyone).Deny(roles.Create, roles.Anyone)})
		}

		res.IndexAttrs(res.IndexAttrs(), "-StateChangeLogs")
		res.ShowAttrs(res.ShowAttrs(), "-StateChangeLogs", false)
		res.NewAttrs(res.NewAttrs(), "-StateChangeLogs")
		res.EditAttrs(res.EditAttrs(), "-StateChangeLogs")
	}
}
Esempio n. 4
0
func SetupAdmin() *admin.Admin {

	// Setup Database for QOR Admin
	sorting.RegisterCallbacks(config.DB)
	validations.RegisterCallbacks(config.DB)
	media_library.RegisterCallbacks(config.DB)

	result := admin.New(&qor.Config{DB: config.DB})

	result.SetSiteName(config.QOR.SiteName)
	result.SetAuth(config.Auth)
	//result.RegisterViewPath("/home/drew/GoWork/src/github.com/8legd/hugocms/vendor/github.com/qor/admin/views")

	// Add Asset Manager, for rich editor
	assetManager := result.AddResource(&media_library.AssetManager{}, &admin.Config{Invisible: true})

	columnImage := result.NewResource(&models.PageContentColumnImage{}, &admin.Config{Invisible: true})
	columnImage.Meta(&admin.Meta{
		Name: "Alignment",
		Type: "select_one",
		Collection: func(o interface{}, context *qor.Context) [][]string {
			var result [][]string
			result = append(result, []string{"media-left media-top", "left top"})
			result = append(result, []string{"media-left media-middle", "left middle"})
			result = append(result, []string{"media-left media-bottom", "left bottom"})
			result = append(result, []string{"media-right media-top", "right top"})
			result = append(result, []string{"media-right media-middle", "right middle"})
			result = append(result, []string{"media-right media-bottom", "right bottom"})
			return result
		},
	})
	columnImage.NewAttrs("-ContentColumns")
	columnImage.EditAttrs("-ContentColumns")

	columns := result.NewResource(&models.PageContentColumn{}, &admin.Config{Invisible: true})
	columns.Meta(&admin.Meta{
		Name: "ColumnWidth",
		Type: "select_one",
		Collection: func(o interface{}, context *qor.Context) [][]string {
			var result [][]string
			result = append(result, []string{"col-md-6", "50% on desktop, 100% on mobile"})
			result = append(result, []string{"col-md-12", "100% on desktop, 100% on mobile"})
			return result
		},
	})
	columns.Meta(&admin.Meta{Name: "ColumnText", Type: "rich_editor", Resource: assetManager})
	staticContentSection := &admin.Section{
		Title: "Static Content",
		Rows: [][]string{
			{"ColumnText"},
			{"ColumnImage"},
		}}
	columns.Meta(&admin.Meta{Name: "ColumnImage", Resource: columnImage})
	dynmamicContentSection := &admin.Section{
		Title: "Dynamic Content",
		Rows: [][]string{
			{"Video", "Slideshow"},
		}}
	columns.NewAttrs("-Page", "ColumnWidth", "ColumnHeading", staticContentSection, dynmamicContentSection, "ColumnLink")
	columns.EditAttrs("-Page", "ColumnWidth", "ColumnHeading", staticContentSection, dynmamicContentSection, "ColumnLink")

	links := result.NewResource(&models.PageLink{}, &admin.Config{Invisible: true})
	links.Meta(&admin.Meta{Name: "LinkText", Type: "rich_editor", Resource: assetManager})
	links.NewAttrs("-Page")
	links.EditAttrs("-Page")

	pages = result.AddResource(&models.Page{}, &admin.Config{Name: "Pages"})
	pages.IndexAttrs("Path", "Name")

	pages.Meta(&admin.Meta{Name: "ContentColumns", Resource: columns})

	pages.Meta(&admin.Meta{Name: "Links", Resource: links})

	pages.Meta(&admin.Meta{Name: "Path", Type: "select_one", Collection: config.QOR.Paths})

	// define scopes for pages
	for _, path := range config.QOR.Paths {
		path := path // The anonymous function below captures the variable `path` not its value
		// So because the range variable is re-assigned a value on each iteration, if we just used it,
		// the actual value being used would just end up being the same (last value of iteration).
		// By redeclaring `path` within the range block's scope a new variable is in effect created for each iteration
		// and that specific variable is used in the anonymous function instead
		// Another solution would be to pass the range variable into a function as a parameter which then returns the
		// original function you wanted creating a `closure` around the passed in parameter (you often  come accross this in JavaScript)
		pages.Scope(&admin.Scope{
			Name:  path,
			Group: "Path",
			Handle: func(db *gorm.DB, context *qor.Context) *gorm.DB {
				return db.Where(models.Page{Path: path})
			},
		})
	}

	pageSection := &admin.Section{
		Title: "Page Setup",
		Rows: [][]string{
			{"Name"},
			{"Path", "MenuWeight"},
			{"Links"},
		}}
	pages.NewAttrs(pageSection, "SEO", "ContentColumns")
	pages.EditAttrs(pageSection, "SEO", "ContentColumns")

	pages.AddValidator(func(record interface{}, metaValues *resource.MetaValues, context *qor.Context) error {
		if meta := metaValues.Get("Name"); meta != nil {
			if name := utils.ToString(meta.Value); strings.TrimSpace(name) == "" {
				return validations.NewError(record, "Name", "Name can not be blank")
			}
		}
		if meta := metaValues.Get("Path"); meta != nil {
			if name := utils.ToString(meta.Value); strings.TrimSpace(name) == "" {
				return validations.NewError(record, "Path", "Path can not be blank")
			}
		}

		// TODO make SEO required

		// if we have content check it is valid
		if meta := metaValues.Get("ContentColumns"); meta != nil {
			if metas := meta.MetaValues.Values; len(metas) > 0 {
				for _, v := range metas {

					// All image content need alt text and alignment
					if v.Name == "ImageContent" {
						if fields := v.MetaValues.Values; len(fields) > 0 {
							img := false
							imgAlt := false
							imgAlign := false
							for _, f := range fields {
								if f.Name == "Image" && f.Value != nil {
									if v, ok := f.Value.([]*multipart.FileHeader); ok {
										if len(v) > 0 {
											img = true
										}
									}
								}
								if f.Name == "Alt" && f.Value != nil {
									if v, ok := f.Value.([]string); ok {
										if len(v) > 0 && v[0] != "" {
											imgAlt = true
										}
									}
								}
								if f.Name == "Alignment" && f.Value != nil {
									if v, ok := f.Value.([]string); ok {
										if len(v) > 0 && v[0] != "" {
											imgAlign = true
										}
									}
								}
							}
							if img && (!imgAlt || !imgAlign) {
								return validations.NewError(record, "ContentColumns", "All Image Content requires Alt Text and Alignment")
							}
						}

					}

				}
			}

		}
		return nil
	})

	slideshows = result.AddResource(&models.Slideshow{}, &admin.Config{Name: "Slideshow"})
	slideshows.IndexAttrs("Name")

	videos = result.AddResource(&models.Video{}, &admin.Config{Name: "Videos"})
	videos.IndexAttrs("Name")

	// Add Settings

	contact := result.NewResource(&models.SettingsContactDetails{}, &admin.Config{Invisible: true})
	contact.Meta(&admin.Meta{Name: "OpeningHoursDesktop", Type: "rich_editor", Resource: assetManager})

	callToAction := result.NewResource(&models.SettingsCallToAction{}, &admin.Config{Invisible: true})
	callToAction.Meta(&admin.Meta{Name: "ActionText", Type: "rich_editor", Resource: assetManager})

	settings = result.AddResource(&models.Settings{}, &admin.Config{Singleton: true})
	settings.Meta(&admin.Meta{Name: "ContactDetails", Resource: contact})
	settings.Meta(&admin.Meta{Name: "CallToAction", Resource: callToAction})
	settings.Meta(&admin.Meta{Name: "Footer", Type: "rich_editor", Resource: assetManager})

	releases = result.AddResource(&models.Release{}, &admin.Config{
		Name:       "Releases",
		Permission: roles.Deny(roles.Delete, roles.Anyone),
	})

	releases.IndexAttrs("ID", "Date", "Comment")
	releases.NewAttrs("Comment")
	releases.EditAttrs("")
	releases.ShowAttrs("ID", "Date", "Comment", "Log")

	// Add Translations
	result.AddResource(config.I18n, &admin.Config{})

	return result
}