activity

package
v3.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2025 License: MIT Imports: 32 Imported by: 0

README

Activity

Usage

  • Firstly, you should create an activity instance in your project.

    ab := activity.New(db, currentUserFunc).
                  TablePrefix("cms_"). // if needed
                  AutoMigrate() // if needed
    
    • db (Required): The database where activity_logs is stored.
    • currentUserFunc (Required): You need to provide this method to get the creator.
  • Register activity into presets

    ab.Install(presetsBuilder)
    
  • Register normal model or a presets.ModelBuilder into activity

    ab.RegisterModel(normalModel) // It need you to record the activity log manually
    ab.RegisterModel(presetModel) // It will record the activity log automatically when you create, update or delete the model data via preset admin
    
  • Skip recording activity log for preset model if you don't want to record the activity log automatically

    ab.RegisterModel(presetModel).SkipCreate().SkipUpdate().SkipDelete()
    
  • Configure more options for the presets.ModelBuilder to record more custom information

    ab.RegisterModel(presetModel).AddKeys("ID", "Version") // will record value of the ID and Version field as the keyword of a model table
    ab.RegisterModel(presetModel).AddIgnoredFields("UpdateAt") // will ignore the UpdateAt field when recording activity log for update operation
    ab.RegisterModel(presetModel).AddTypeHanders(
      time.Time{},
      func(old, new any, prefixField string) []Diff {
      oldString := old.(time.Time).Format(time.RFC3339)
      newString := new.(time.Time).Format(time.RFC3339)
      if oldString != newString {
       return []Diff{
        {Field: prefixField, Old: oldString, New: newString},
       }
      }
      return []Diff{}
      }
      ) // you define your own type handler to record some custom type for update operation
    
  • Record log manually when you use a normal model or save the model data via db directly

    • When a struct type only have one activity.ModelBuilder, you can use activity to record the log directly.

        ab.OnEdit(ctx, old, new)
        ab.OnCreate(ctx, obj)
      
    • When a struct type have multiple activity.ModelBuilder, you need to get the corresponding activity.ModelBuilder and then use it to record the log.

        ab.MustGetModelBuilder(presetModel1).OnEdit(ctx, old, new)
        ab.MustGetModelBuilder(presetModel2).OnCreate(ctx, obj)
      
  • Add ListFieldNotes to Listing Builder

      mb.Listing("ID", "Title", "Body", activity.ListFieldNotes)
    
  • Add TimelineCompo to DetailingBuilder or EditingBuilder

    • Add to SidePanel
      dp.SidePanelFunc(func(obj any, ctx *web.EventContext) h.HTMLComponent {
        return ab.MustGetModelBuilder(mb).NewTimelineCompo(ctx, obj, "_side")
      })
    
    • Add to Field
      mb.Detailing("Title", "Body", activity.FieldTimeline)
    

Documentation

Index

Constants

View Source
const (
	ActionView     = "View"
	ActionEdit     = "Edit"
	ActionCreate   = "Create"
	ActionDelete   = "Delete"
	ActionNote     = "Note"
	ActionLastView = "LastView" // hidden and only for internal use
)
View Source
const (
	FieldTimeline       string = "__ActivityTimeline__"
	ListFieldNotes      string = "__ActivityNotes__"
	ListFieldLabelNotes string = "Notes"

	NopModelLabel = "-"
)
View Source
const (
	Create = 1 << iota
	Edit
	Delete
)
View Source
const (
	PermAll        = "activity:*"
	PermListNotes  = "activity:list_notes"
	PermAddNote    = "activity:add_note"
	PermEditNote   = "activity:edit_note"
	PermDeleteNote = "activity:delete_note"
)
View Source
const DefaultMaxCountShowInTimeline = 10
View Source
const I18nActionLabelPrefix = "ActivityAction"
View Source
const (
	I18nActivityKey i18n.ModuleKey = "I18nActivityKey"
)
View Source
const KeyHasUnreadNotes = "hasUnreadNotes"
View Source
const ModelKeysSeparator = ":"

Variables

View Source
var (

	// @snippet_begin(ActivityDefaultIgnoredFields)
	DefaultIgnoredFields = []string{"ID", "UpdatedAt", "DeletedAt", "CreatedAt"}

	// @snippet_begin(ActivityDefaultTypeHandles)
	DefaultTypeHandles = map[reflect.Type]TypeHandler{
		reflect.TypeOf(time.Time{}): func(old, new any, prefixField string) []Diff {
			var oldString, newString string
			if !old.(time.Time).IsZero() {
				oldString = old.(time.Time).Format(timeFormat)
			}
			if !new.(time.Time).IsZero() {
				newString = new.(time.Time).Format(timeFormat)
			}
			if oldString != newString {
				return []Diff{
					{Field: prefixField, Old: oldString, New: newString},
				}
			}
			return []Diff{}
		},
		reflect.TypeOf(media_library.MediaBox{}): func(old, new any, prefixField string) (diffs []Diff) {
			oldMediaBox := old.(media_library.MediaBox)
			newMediaBox := new.(media_library.MediaBox)

			if oldMediaBox.Url != newMediaBox.Url {
				diffs = append(diffs, Diff{Field: formatFieldByDot(prefixField, "Url"), Old: oldMediaBox.Url, New: newMediaBox.Url})
			}

			if oldMediaBox.Description != newMediaBox.Description {
				diffs = append(diffs, Diff{Field: formatFieldByDot(prefixField, "Description"), Old: oldMediaBox.Description, New: newMediaBox.Description})
			}

			if oldMediaBox.VideoLink != newMediaBox.VideoLink {
				diffs = append(diffs, Diff{Field: formatFieldByDot(prefixField, "VideoLink"), Old: oldMediaBox.VideoLink, New: newMediaBox.VideoLink})
			}

			return diffs
		},
	}
)
View Source
var Messages_en_US = &Messages{
	Activities:   "Activity",
	ActionAll:    "All",
	ActionView:   "View",
	ActionEdit:   "Edit",
	ActionCreate: "Create",
	ActionDelete: "Delete",
	ActionNote:   "Note",

	ModelUserID:    "Creator ID",
	ModelCreatedAt: "Create Time",
	ModelAction:    "Action",
	ModelUser:      "Creator",
	ModelKeys:      "Model Keys",
	ModelName:      "Model Name",
	ModelLabel:     "Menu Name",
	ModelLink:      "Link",
	ModelDiffs:     "Diffs",

	FilterAction:    "Action",
	FilterCreatedAt: "Create Time",
	FilterUser:      "Creator",
	FilterModel:     "Model Name",
	FilterModelKeys: "Model Keys",

	DiffDetail:  "Detail",
	DiffAdd:     "New",
	DiffDelete:  "Delete",
	DiffChanges: "Changes",
	DiffField:   "Field",
	DiffOld:     "Old",
	DiffNew:     "Now",
	DiffValue:   "Value",

	AddedANote:                    "Added a note :",
	LastEditedAtTemplate:          "(edited at {desc})",
	EditedNFieldsTemplate:         "Edited {n} fields",
	MoreInfo:                      "More Info",
	Created:                       "Created",
	Viewed:                        "Viewed",
	Deleted:                       "Deleted",
	PerformActionNoDetailTemplate: "Perform {action}",
	PerformActionTemplate:         "Perform {action} with {detail}",
	AddNote:                       "Add Note",
	UnknownUser:                   "Unknown",
	NoteCannotBeEmpty:             "Note cannot be empty",
	FailedToCreateNote:            "Failed to create note",
	SuccessfullyCreatedNote:       "Successfully created note",
	FailedToGetCurrentUser:        "Failed to get current user",
	FailedToGetNote:               "Failed to get note",
	YouAreNotTheNoteUser:          "You are not the creator of this note",
	FailedToUpdateNote:            "Failed to update note",
	SuccessfullyUpdatedNote:       "Successfully updated note",
	FailedToDeleteNote:            "Failed to delete note",
	SuccessfullyDeletedNote:       "Successfully deleted note",
	DeleteNoteDialogTitle:         "Delete Note",
	DeleteNoteDialogText:          "Are you sure you want to delete this note?",
	Cancel:                        "Cancel",
	Delete:                        "Delete",
	NoActivitiesYet:               "No activities yet",
	ViewAll:                       "View All",
	CannotShowMore:                "Reached the display limit, unable to load more.",

	HeaderNotes: "Notes",

	ActivityLogs: "Activity Logs",
	ActivityLog:  "Activity Log",

	FilterTabsHasUnreadNotes: "Has Unread Notes",
}
View Source
var Messages_ja_JP = &Messages{
	Activities:   "作業履歴",
	ActionAll:    "全て",
	ActionView:   "表示",
	ActionEdit:   "編集",
	ActionCreate: "作成する",
	ActionDelete: "削除",
	ActionNote:   "ノート",

	ModelUserID:    "作成者ID",
	ModelCreatedAt: "日時",
	ModelAction:    "アクション",
	ModelUser:      "作成者",
	ModelKeys:      "キー",
	ModelName:      "モデル名",
	ModelLabel:     "メニュー名",
	ModelLink:      "リンク",
	ModelDiffs:     "差分",

	FilterAction:    "アクション",
	FilterCreatedAt: "作成日時",
	FilterUser:      "作成者",
	FilterModel:     "モデル名",
	FilterModelKeys: "キー",

	DiffDetail:  "詳細",
	DiffAdd:     "追加",
	DiffDelete:  "削除",
	DiffChanges: "変更",
	DiffField:   "フィールド",
	DiffOld:     "以前",
	DiffNew:     "現在",
	DiffValue:   "値",

	AddedANote:                    "ノートを追加しました:",
	LastEditedAtTemplate:          "{desc} に編集",
	EditedNFieldsTemplate:         "{n}つのフィールドを編集しました",
	MoreInfo:                      "詳細情報",
	Created:                       "作成する",
	Viewed:                        "表示",
	Deleted:                       "削除",
	PerformActionNoDetailTemplate: "{action} を実行",
	PerformActionTemplate:         "{action} を実行し、{detail} を使用",
	AddNote:                       "ノートを追加",
	UnknownUser:                   "不明",
	NoteCannotBeEmpty:             "ノートは必須です",
	FailedToCreateNote:            "ノートの作成に失敗しました",
	SuccessfullyCreatedNote:       "ノートの作成に成功しました",
	FailedToGetCurrentUser:        "現在のユーザーの取得に失敗しました",
	FailedToGetNote:               "ノートの取得に失敗しました",
	YouAreNotTheNoteUser:          "このノートの作成者ではありません",
	FailedToUpdateNote:            "ノートの更新に失敗しました",
	SuccessfullyUpdatedNote:       "ノートの更新に成功しました",
	FailedToDeleteNote:            "ノートの削除に失敗しました",
	SuccessfullyDeletedNote:       "ノートの削除に成功しました",
	DeleteNoteDialogTitle:         "ノートを削除",
	DeleteNoteDialogText:          "このノートを削除してもよろしいですか?",
	Cancel:                        "キャンセル",
	Delete:                        "削除",
	NoActivitiesYet:               "まだアクティビティはありません",
	ViewAll:                       "全て表示",
	CannotShowMore:                "表示上限に達しました。これ以上読み込むことができません。",

	HeaderNotes: "ノート",

	ActivityLogs: "作業履歴",
	ActivityLog:  "作業履歴",

	FilterTabsHasUnreadNotes: "未読ノート",
}
View Source
var Messages_zh_CN = &Messages{
	Activities:   "活动",
	ActionAll:    "全部",
	ActionView:   "查看",
	ActionEdit:   "编辑",
	ActionCreate: "创建",
	ActionDelete: "删除",
	ActionNote:   "备注",

	ModelUserID:    "操作者ID",
	ModelCreatedAt: "日期时间",
	ModelAction:    "操作",
	ModelUser:      "操作者",
	ModelKeys:      "主键",
	ModelName:      "对象",
	ModelLabel:     "菜单名",
	ModelLink:      "链接",
	ModelDiffs:     "差异",

	FilterAction:    "操作类型",
	FilterCreatedAt: "操作时间",
	FilterUser:      "操作者",
	FilterModel:     "对象",
	FilterModelKeys: "主键",

	DiffDetail:  "详情",
	DiffAdd:     "新加",
	DiffDelete:  "删除",
	DiffChanges: "修改",
	DiffField:   "字段",
	DiffOld:     "之前的值",
	DiffNew:     "当前的值",
	DiffValue:   "值",

	AddedANote:                    "添加了一个备注:",
	LastEditedAtTemplate:          "编辑于 {desc}",
	EditedNFieldsTemplate:         "编辑了 {n} 个字段",
	MoreInfo:                      "更多信息",
	Created:                       "创建",
	Viewed:                        "查看",
	Deleted:                       "删除",
	PerformActionNoDetailTemplate: "执行 {action}",
	PerformActionTemplate:         "执行 {action} 操作,详情为 {detail}",
	AddNote:                       "添加备注",
	UnknownUser:                   "未知",
	NoteCannotBeEmpty:             "备注不能为空",
	FailedToCreateNote:            "创建备注失败",
	SuccessfullyCreatedNote:       "成功创建备注",
	FailedToGetCurrentUser:        "获取当前用户失败",
	FailedToGetNote:               "获取备注失败",
	YouAreNotTheNoteUser:          "您不是备注的创建者",
	FailedToUpdateNote:            "更新备注失败",
	SuccessfullyUpdatedNote:       "成功更新备注",
	FailedToDeleteNote:            "删除备注失败",
	SuccessfullyDeletedNote:       "成功删除备注",
	DeleteNoteDialogTitle:         "删除备注",
	DeleteNoteDialogText:          "确定要删除此备注吗?",
	Cancel:                        "取消",
	Delete:                        "删除",
	NoActivitiesYet:               "暂无活动",
	ViewAll:                       "查看全部",
	CannotShowMore:                "已达到显示上限,无法加载更多。",

	HeaderNotes: "备注",

	ActivityLogs: "操作日志",
	ActivityLog:  "操作日志",

	FilterTabsHasUnreadNotes: "未读备注",
}

Functions

func AutoMigrate

func AutoMigrate(db *gorm.DB, tablePrefix string) error

func ContextWithDB

func ContextWithDB(ctx context.Context, db *gorm.DB) context.Context

func ContextWithScope

func ContextWithScope(ctx context.Context, scope string) context.Context

func DiffComponent

func DiffComponent(diffstr string, req *http.Request) h.HTMLComponent

func FetchOld

func FetchOld(db *gorm.DB, ref any) (any, error)

func FetchOldWithSlug

func FetchOldWithSlug(db *gorm.DB, ref any, slug string) (any, error)

func FirstUpperWord

func FirstUpperWord(name string) string

func GetHasUnreadNotesHref

func GetHasUnreadNotesHref(listingHref string) string

func KeysValue

func KeysValue(v any, keys []string, sep string) string

func NotifiLastViewedAtUpdated

func NotifiLastViewedAtUpdated(modelName string) string

func ParseModelName

func ParseModelName(v any) string

func ParsePrimaryKeys

func ParsePrimaryKeys(v any, useBindName bool) []string

func ParseSchema

func ParseSchema(v any) (*schema.Schema, error)

func ParseSchemaWithDB

func ParseSchemaWithDB(db *gorm.DB, v any) (*schema.Schema, error)

func ScopeWithOwner

func ScopeWithOwner(owner string) string

func ScopeWithTablePrefix

func ScopeWithTablePrefix(tablePrefix string) func(db *gorm.DB) *gorm.DB

ScopeWithTablePrefix set table prefix 1. Only scenarios where a Model is provided are supported 2. Previously Table(...) will be overwritten

Types

type ActivityLog

type ActivityLog struct {
	gorm.Model

	UserID string `gorm:"index;not null;"`
	User   User   `gorm:"-"`

	Action     string `gorm:"index;not null;"`
	Hidden     bool   `gorm:"index;default:false;not null;"`
	ModelName  string `gorm:"index;not null;"`
	ModelKeys  string `gorm:"index;not null;"`
	ModelLabel string `gorm:"not null;"` // IMPROVE: need named resource sign
	ModelLink  string `gorm:"not null;"`
	Detail     string `gorm:"not null;"`
	Scope      string `gorm:"index;"`
}

func (*ActivityLog) AfterMigrate

func (v *ActivityLog) AfterMigrate(tx *gorm.DB, tablePrefix string) error

type ActivityUser

type ActivityUser struct {
	ID        string `gorm:"primarykey"`
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt gorm.DeletedAt `gorm:"index"`
	Name      string         `gorm:"index;not null"`
	Avatar    string         `gorm:"not null"`
}

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

@snippet_begin(ActivityBuilder)

func New

func New(db *gorm.DB, currentUserFunc func(ctx context.Context) (*User, error)) *Builder

func (*Builder) AutoMigrate

func (b *Builder) AutoMigrate() (r *Builder)

func (*Builder) FindLogsForTimelineFunc

func (ab *Builder) FindLogsForTimelineFunc(v func(ctx context.Context, db *gorm.DB, modelName, modelKeys string) (logs []*ActivityLog, hasMore bool, err error)) *Builder

func (*Builder) FindUsersFunc

func (ab *Builder) FindUsersFunc(v func(ctx context.Context, ids []string) (map[string]*User, error)) *Builder

func (*Builder) GetLogModelBuilder

func (ab *Builder) GetLogModelBuilder(pb *presets.Builder) *presets.ModelBuilder

func (*Builder) GetModelBuilder

func (ab *Builder) GetModelBuilder(v any) (*ModelBuilder, bool)

func (*Builder) GetModelBuilders

func (ab *Builder) GetModelBuilders() []*ModelBuilder

func (*Builder) GetNotesCounts

func (ab *Builder) GetNotesCounts(ctx context.Context, modelName string, modelKeyses []string, conditions ...presets.SQLCondition) ([]*NoteCount, error)

func (*Builder) Install

func (ab *Builder) Install(b *presets.Builder) error

func (*Builder) Log

func (ab *Builder) Log(ctx context.Context, action string, v any, detail any) (*ActivityLog, error)

func (*Builder) MarkAllNotesAsRead

func (ab *Builder) MarkAllNotesAsRead(ctx context.Context) error

func (*Builder) MaxCountShowInTimeline

func (ab *Builder) MaxCountShowInTimeline(v int) *Builder

func (*Builder) ModelInstall

func (b *Builder) ModelInstall(pb *presets.Builder, m *presets.ModelBuilder) error

func (*Builder) MustGetModelBuilder

func (ab *Builder) MustGetModelBuilder(v any) *ModelBuilder

func (*Builder) Note

func (ab *Builder) Note(ctx context.Context, v any, note *Note) (*ActivityLog, error)

func (*Builder) OnCreate

func (ab *Builder) OnCreate(ctx context.Context, v any) (*ActivityLog, error)

func (*Builder) OnDelete

func (ab *Builder) OnDelete(ctx context.Context, v any) (*ActivityLog, error)

func (*Builder) OnEdit

func (ab *Builder) OnEdit(ctx context.Context, old, new any) (*ActivityLog, error)

func (*Builder) OnView

func (ab *Builder) OnView(ctx context.Context, v any) (*ActivityLog, error)

func (*Builder) PermPolicy

func (ab *Builder) PermPolicy(v *perm.PolicyBuilder) *Builder

func (*Builder) RegisterModel

func (ab *Builder) RegisterModel(m any) (amb *ModelBuilder)

func (*Builder) RegisterModels

func (ab *Builder) RegisterModels(models ...any) *Builder

func (*Builder) SkipResPermCheck

func (ab *Builder) SkipResPermCheck(v bool) *Builder

func (*Builder) TablePrefix

func (ab *Builder) TablePrefix(prefix string) *Builder

func (*Builder) WrapLogModelInstall

func (ab *Builder) WrapLogModelInstall(w func(presets.ModelInstallFunc) presets.ModelInstallFunc) *Builder

type CreateNoteRequest

type CreateNoteRequest struct {
	Note string `json:"note"`
}

type DeleteNoteRequest

type DeleteNoteRequest struct {
	LogID uint `json:"log_id"`
}

type Diff

type Diff struct {
	Field string
	Old   string
	New   string
}

type DiffBuilder

type DiffBuilder struct {
	// contains filtered or unexported fields
}

func NewDiffBuilder

func NewDiffBuilder(mb *ModelBuilder) *DiffBuilder

func (*DiffBuilder) Diff

func (db *DiffBuilder) Diff(old, new any) ([]Diff, error)

type Messages

type Messages struct {
	Activities   string
	ActionAll    string
	ActionView   string
	ActionEdit   string
	ActionCreate string
	ActionDelete string
	ActionNote   string

	ModelUserID    string
	ModelCreatedAt string
	ModelAction    string
	ModelUser      string
	ModelKeys      string
	ModelName      string
	ModelLabel     string
	ModelLink      string
	ModelDiffs     string

	FilterAction    string
	FilterCreatedAt string
	FilterUser      string
	FilterModel     string
	FilterModelKeys string

	DiffDetail  string
	DiffAdd     string
	DiffDelete  string
	DiffChanges string
	DiffField   string
	DiffOld     string
	DiffNew     string
	DiffValue   string

	AddedANote                    string
	LastEditedAtTemplate          string
	EditedNFieldsTemplate         string
	MoreInfo                      string
	Created                       string
	Viewed                        string
	Deleted                       string
	PerformActionNoDetailTemplate string
	PerformActionTemplate         string
	AddNote                       string
	UnknownUser                   string
	NoteCannotBeEmpty             string
	FailedToCreateNote            string
	SuccessfullyCreatedNote       string
	FailedToGetCurrentUser        string
	FailedToGetNote               string
	YouAreNotTheNoteUser          string
	FailedToUpdateNote            string
	SuccessfullyUpdatedNote       string
	FailedToDeleteNote            string
	SuccessfullyDeletedNote       string
	DeleteNoteDialogTitle         string
	DeleteNoteDialogText          string
	Cancel                        string
	Delete                        string
	NoActivitiesYet               string
	ViewAll                       string
	CannotShowMore                string

	HeaderNotes string

	ActivityLogs string
	ActivityLog  string

	FilterTabsHasUnreadNotes string
}

func (*Messages) EditedNFields

func (msgr *Messages) EditedNFields(n int) string

func (*Messages) LastEditedAt

func (msgr *Messages) LastEditedAt(desc string) string

func (*Messages) PerformAction

func (msgr *Messages) PerformAction(action string, detail string) string

type ModelBuilder

type ModelBuilder struct {
	// contains filtered or unexported fields
}

@snippet_begin(ActivityModelBuilder)

func (*ModelBuilder) AddIgnoredFields

func (mb *ModelBuilder) AddIgnoredFields(fields ...string) *ModelBuilder

func (*ModelBuilder) AddKeys

func (mb *ModelBuilder) AddKeys(keys ...string) *ModelBuilder

func (*ModelBuilder) AddTypeHanders

func (mb *ModelBuilder) AddTypeHanders(v any, f TypeHandler) *ModelBuilder

func (*ModelBuilder) BeforeCreate

func (mb *ModelBuilder) BeforeCreate(f func(ctx context.Context, log *ActivityLog) error) *ModelBuilder

func (*ModelBuilder) Diff

func (mb *ModelBuilder) Diff(old, new any) ([]Diff, error)

func (*ModelBuilder) IgnoredFields

func (mb *ModelBuilder) IgnoredFields(fields ...string) *ModelBuilder

func (*ModelBuilder) Keys

func (mb *ModelBuilder) Keys(keys ...string) *ModelBuilder

func (*ModelBuilder) LabelFunc

func (mb *ModelBuilder) LabelFunc(f func() string) *ModelBuilder

func (*ModelBuilder) LinkFunc

func (mb *ModelBuilder) LinkFunc(f func(any) string) *ModelBuilder

func (*ModelBuilder) Log

func (mb *ModelBuilder) Log(ctx context.Context, action string, obj any, detail any) (*ActivityLog, error)

func (*ModelBuilder) NewHasUnreadNotesFilterItem

func (amb *ModelBuilder) NewHasUnreadNotesFilterItem(ctx context.Context, columnPrefix string) (*vx.FilterItem, error)

func (*ModelBuilder) NewHasUnreadNotesFilterTab

func (amb *ModelBuilder) NewHasUnreadNotesFilterTab(ctx context.Context) (*presets.FilterTab, error)

func (*ModelBuilder) NewTimelineCompo

func (amb *ModelBuilder) NewTimelineCompo(evCtx *web.EventContext, obj any, idSuffix string) h.HTMLComponent

func (*ModelBuilder) Note

func (mb *ModelBuilder) Note(ctx context.Context, v any, note *Note) (*ActivityLog, error)

func (*ModelBuilder) OnCreate

func (mb *ModelBuilder) OnCreate(ctx context.Context, v any) (*ActivityLog, error)

func (*ModelBuilder) OnDelete

func (mb *ModelBuilder) OnDelete(ctx context.Context, v any) (*ActivityLog, error)

func (*ModelBuilder) OnEdit

func (mb *ModelBuilder) OnEdit(ctx context.Context, old any, new any) (*ActivityLog, error)

func (*ModelBuilder) OnView

func (mb *ModelBuilder) OnView(ctx context.Context, v any) (*ActivityLog, error)

func (*ModelBuilder) ParseModelKeys

func (mb *ModelBuilder) ParseModelKeys(v any) string

func (*ModelBuilder) SQLConditionHasUnreadNotes

func (amb *ModelBuilder) SQLConditionHasUnreadNotes(ctx context.Context, columnPrefix string) (string, error)

SQLConditionHasUnreadNotes returns a SQL condition that can be used in a WHERE clause to filter records that have unread notes. Note that this method requires the applied db to be amb.ab.db, not any other db

func (*ModelBuilder) SkipCreate

func (mb *ModelBuilder) SkipCreate() *ModelBuilder

func (*ModelBuilder) SkipDelete

func (mb *ModelBuilder) SkipDelete() *ModelBuilder

func (*ModelBuilder) SkipEdit

func (mb *ModelBuilder) SkipEdit() *ModelBuilder

func (*ModelBuilder) WrapperSaveFunc

func (amb *ModelBuilder) WrapperSaveFunc(in presets.SaveFunc) presets.SaveFunc

type Note

type Note struct {
	Note         string    `json:"note"`
	LastEditedAt time.Time `json:"last_edited_at"`
}

type NoteCount

type NoteCount struct {
	ModelName        string
	ModelKeys        string
	ModelLabel       string
	UnreadNotesCount int64
	TotalNotesCount  int64
}

type PayloadLastViewedAtUpdated

type PayloadLastViewedAtUpdated struct {
	Log *ActivityLog `json:"log"`
}

type StructField

type StructField struct {
	reflect.StructField
	BindNames  []string
	Attachment any
}

func CollectStructFields

func CollectStructFields(v any, bindNames []string, preprocess func(f *StructField) (valid bool)) []*StructField

type TimelineCompo

type TimelineCompo struct {
	ID        string `json:"id"`
	ModelName string `json:"model_name"`
	ModelKeys string `json:"model_keys"`
	ModelLink string `json:"model_link"`
	// contains filtered or unexported fields
}

func (*TimelineCompo) CompoID

func (c *TimelineCompo) CompoID() string

func (*TimelineCompo) CreateNote

func (c *TimelineCompo) CreateNote(ctx context.Context, req CreateNoteRequest) (r web.EventResponse, _ error)

func (*TimelineCompo) DeleteNote

func (c *TimelineCompo) DeleteNote(ctx context.Context, req DeleteNoteRequest) (r web.EventResponse, _ error)

func (*TimelineCompo) MarshalHTML

func (c *TimelineCompo) MarshalHTML(ctx context.Context) ([]byte, error)

func (*TimelineCompo) MustGetEventContext

func (c *TimelineCompo) MustGetEventContext(ctx context.Context) (*web.EventContext, *Messages)

func (*TimelineCompo) UpdateNote

func (c *TimelineCompo) UpdateNote(ctx context.Context, req UpdateNoteRequest) (r web.EventResponse, _ error)

func (*TimelineCompo) VarCurrentActive

func (c *TimelineCompo) VarCurrentActive() string

type TypeHandler

type TypeHandler func(old, new any, prefixField string) []Diff

@snippet_begin(ActivityTypeHandle)

type UpdateNoteRequest

type UpdateNoteRequest struct {
	LogID uint   `json:"log_id"`
	Note  string `json:"note"`
}

type User

type User struct {
	ID     string
	Name   string
	Avatar string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL