Skip to content
Snippets Groups Projects
action.go 9.45 KiB
package extension

import (
	"git.perx.ru/perxis/perxis-go/pkg/references"
	pb "git.perx.ru/perxis/perxis-go/proto/extensions"
	"github.com/mitchellh/mapstructure"
)

type (
	ActionKind     = pb.Action_Kind
	ActionTarget   = pb.Target
	ActionView     = pb.Action_View
	ResponseState  = pb.ActionResponse_State
	ResponseFormat = pb.ActionResponse_Format

	ActionRequest struct {
		Extension    string
		Action       string
		SpaceID      string
		EnvID        string
		CollectionID string
		ItemID       string
		ItemIDs      []string
		Fields       []string
		Metadata     map[string]string
		Refs         []*references.Reference
		Params       *references.Reference
	}

	ActionResponse struct {
		State    ResponseState
		Target   ActionTarget
		Format   ResponseFormat
		Msg      string
		Title    string
		Image    string
		Error    string
		Next     []*Action
		Metadata map[string]string
		Refs     []*references.Reference
	}
)

const (
	ActionKindDefault     = pb.Action_DEFAULT
	ActionKindSpace       = pb.Action_SPACE
	ActionKindEnvironment = pb.Action_ENVIRONMENT
	ActionKindCollection  = pb.Action_COLLECTION
	ActionKindItem        = pb.Action_ITEM
	ActionKindItems       = pb.Action_ITEMS
	ActionKindRevision    = pb.Action_REVISION
	ActionKindCreate      = pb.Action_CREATE

	ActionTargetDefault      = pb.Target_DEFAULT
	ActionTargetModal        = pb.Target_MODAL
	ActionTargetWide         = pb.Target_WIDE
	ActionTargetMain         = pb.Target_MAIN
	ActionTargetDrawer       = pb.Target_DRAWER
	ActionTargetNotification = pb.Target_NOTIFICATION
	ActionTargetBlank        = pb.Target_BLANK
	ActionTargetNone         = pb.Target_NONE

	ActionViewDefault        = pb.Action_DEFAULT_VIEW
	ActionViewHidden         = pb.Action_HIDDEN_VIEW
	ActionViewMainMenu       = pb.Action_MAIN_MENU_VIEW
	ActionViewMainMenuBottom = pb.Action_MAIN_MENU_BOTTOM_VIEW

	ResponseDone               = pb.ActionResponse_DONE
	ResponseError              = pb.ActionResponse_ERROR
	ResponsePending            = pb.ActionResponse_PENDING
	ResponseInProgress         = pb.ActionResponse_IN_PROGRESS
	ResponseParametersRequired = pb.ActionResponse_PARAMETERS_REQUIRED

	ResponseFormatPlain    = pb.ActionResponse_PLAIN
	ResponseFormatHtml     = pb.ActionResponse_HTML
	ResponseFormatMarkdown = pb.ActionResponse_MARKDOWN
)

var (
	ActionKindName      = pb.Action_Kind_name
	ActionKindValue     = pb.Action_Kind_value
	ActionTargetName    = pb.Target_name
	ActionTargetValue   = pb.Target_value
	ActionViewName      = pb.Action_View_name
	ActionViewValue     = pb.Action_View_value
	ResponseStateName   = pb.ActionResponse_State_name
	ResponseStateValue  = pb.ActionResponse_State_value
	ResponseFormatName  = pb.ActionResponse_Format_name
	ResponseFormatValue = pb.ActionResponse_Format_value
)

type Action struct {
	Extension        string                  `mapstructure:"extension,omitempty"`   // Расширение
	Action           string                  `mapstructure:"action,omitempty"`      // Идентификатор действия
	Target           ActionTarget            `mapstructure:"target,omitempty"`      // Отображение результата действия
	Parent           string                  `mapstructure:"parent,omitempty"`      // Идентификатор родительского действия (для отображения в меню)
	Name             string                  `mapstructure:"name,omitempty"`        // Название действия для отображения в интерфейсе (пункт меню, кнопка).
	Description      string                  `mapstructure:"description,omitempty"` // Описание действия для отображения в интерфейсе
	Icon             string                  `mapstructure:"icon,omitempty"`        // Название иконки для отображения действия в интерфейсе
	Image            *references.Reference   `mapstructure:"image,omitempty"`       // Изображение для отображения в действия в интерфейсе
	Groups           []string                `mapstructure:"groups,omitempty"`      // Группы отображения действия в интерфейсе
	Kind             ActionKind              `mapstructure:"kind,omitempty"`        // Указывает на что направлено действие
	Classes          []string                `mapstructure:"classes,omitempty"`     // Классы данных к которым применимо действие (название коллекций или специальных групп в рамках которых данное действие применимо)
	Refs             []*references.Reference `mapstructure:"refs,omitempty"`        // Ссылки на записи используемые для выполнения действия (назначение ссылок зависит от действия и расширения)
	ParamsCollection string                  `mapstructure:"params_collection,omitempty"`
	Request          *ActionRequest          `mapstructure:"request,omitempty"`           // Параметры запроса (используется в случае `ActionResponse.next`)
	NavigationAction bool                    `mapstructure:"navigation_action,omitempty"` // Флаг указывающий, что действие должно переносить пользователя в другую часть интерфейса, а не отправлять запрос на сервер
	NavigationRoute  string                  `mapstructure:"navigation_route,omitempty"`
	Autorun          bool                    `mapstructure:"autorun,omitempty"` // Параметр указывающий, что действие выполняется автоматически
	Confirm          bool                    `mapstructure:"confirm,omitempty"` // Параметр указывающий, что действие требует подтверждения пользователя
}

func ActionToMap(action *Action) map[string]interface{} {
	res := make(map[string]interface{})
	_ = mapstructure.Decode(action, &res)
	res["kind"] = int64(action.Kind.Number())
	res["target"] = int64(action.Target.Number())
	return res
}

func ActionFromMap(d map[string]interface{}) (*Action, error) {
	var action Action
	err := mapstructure.Decode(d, &action)
	return &action, err
}

func ActionRequestToPB(req *ActionRequest) *pb.ActionRequest {
	if req == nil {
		return nil
	}
	return &pb.ActionRequest{
		Extension:    req.Extension,
		Action:       req.Action,
		SpaceId:      req.SpaceID,
		EnvId:        req.EnvID,
		CollectionId: req.CollectionID,
		ItemId:       req.ItemID,
		ItemIds:      req.ItemIDs,
		Fields:       req.Fields,
		Metadata:     req.Metadata,
		Refs:         references.ReferenceListToPB(req.Refs),
		Params:       references.ReferenceToPB(req.Params),
	}
}

func ActionRequestFromPB(req *pb.ActionRequest) *ActionRequest {
	if req == nil {
		return nil
	}
	return &ActionRequest{
		Extension:    req.Extension,
		Action:       req.Action,
		SpaceID:      req.SpaceId,
		EnvID:        req.EnvId,
		CollectionID: req.CollectionId,
		ItemID:       req.ItemId,
		ItemIDs:      req.ItemIds,
		Fields:       req.Fields,
		Metadata:     req.Metadata,
		Refs:         references.ReferenceListFromPB(req.Refs),
		Params:       references.ReferenceFromPB(req.Params),
	}
}
func ActionResponseToPB(out *ActionResponse) *pb.ActionResponse {
	if out == nil {
		return nil
	}

	var next []*pb.Action
	for _, a := range out.Next {
		next = append(next, ActionToPB(a))
	}

	return &pb.ActionResponse{
		State:    out.State,
		Msg:      out.Msg,
		Error:    out.Error,
		Next:     next,
		Metadata: out.Metadata,
		Refs:     references.ReferenceListToPB(out.Refs),
	}
}

func ActionResponseFromPB(out *pb.ActionResponse) *ActionResponse {
	if out == nil {
		return nil
	}

	var next []*Action
	for _, a := range out.Next {
		next = append(next, ActionFromPB(a))
	}

	return &ActionResponse{
		State:    out.State,
		Msg:      out.Msg,
		Error:    out.Error,
		Next:     next,
		Metadata: out.Metadata,
		Refs:     references.ReferenceListFromPB(out.Refs),
	}
}

func ActionFromPB(a *pb.Action) *Action {
	if a == nil {
		return nil
	}
	return &Action{
		Extension:        a.Extension,
		Action:           a.Action,
		Target:           a.Target,
		Parent:           a.Parent,
		Name:             a.Name,
		Description:      a.Description,
		Icon:             a.Icon,
		Image:            references.ReferenceFromPB(a.Image),
		Groups:           a.Groups,
		Kind:             a.Kind,
		Classes:          a.Classes,
		Refs:             references.ReferenceListFromPB(a.Refs),
		ParamsCollection: a.ParamsCollection,
		Request:          ActionRequestFromPB(a.Request),
		NavigationAction: a.NavigationAction,
		NavigationRoute:  a.NavigationRoute,
		Autorun:          a.Autorun,
		Confirm:          a.Confirm,
	}
}

func ActionToPB(a *Action) *pb.Action {
	if a == nil {
		return nil
	}
	return &pb.Action{
		Extension:        a.Extension,
		Action:           a.Action,
		Name:             a.Name,
		Description:      a.Description,
		Icon:             a.Icon,
		Image:            references.ReferenceToPB(a.Image),
		Groups:           a.Groups,
		Kind:             a.Kind,
		Classes:          a.Classes,
		Refs:             references.ReferenceListToPB(a.Refs),
		ParamsCollection: a.ParamsCollection,
		Request:          ActionRequestToPB(a.Request),
		NavigationAction: a.NavigationAction,
		NavigationRoute:  a.NavigationRoute,
	}
}