mirror of
https://github.com/documize/community.git
synced 2025-07-20 13:49:42 +02:00
Support for document draft-live publication workflows
This commit is contained in:
parent
bde0091a4a
commit
9235c183c5
14 changed files with 828 additions and 697 deletions
|
@ -52,9 +52,9 @@ Space view.
|
||||||
|
|
||||||
## Latest version
|
## Latest version
|
||||||
|
|
||||||
[Community edition: v1.62.0](https://github.com/documize/community/releases)
|
[Community edition: v1.63.0](https://github.com/documize/community/releases)
|
||||||
|
|
||||||
[Enterprise edition: v1.64.0](https://documize.com/downloads)
|
[Enterprise edition: v1.65.0](https://documize.com/downloads)
|
||||||
|
|
||||||
## OS support
|
## OS support
|
||||||
|
|
||||||
|
|
6
core/database/scripts/autobuild/db_00022.sql
Normal file
6
core/database/scripts/autobuild/db_00022.sql
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/* enterprise edition */
|
||||||
|
|
||||||
|
-- document lifecycle default option
|
||||||
|
ALTER TABLE label ADD COLUMN `lifecycle` INT NOT NULL DEFAULT 1 AFTER `type`;
|
||||||
|
|
||||||
|
-- deprecations
|
|
@ -19,11 +19,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/documize/community/model/workflow"
|
|
||||||
|
|
||||||
"github.com/documize/community/core/env"
|
|
||||||
|
|
||||||
api "github.com/documize/community/core/convapi"
|
api "github.com/documize/community/core/convapi"
|
||||||
|
"github.com/documize/community/core/env"
|
||||||
"github.com/documize/community/core/request"
|
"github.com/documize/community/core/request"
|
||||||
"github.com/documize/community/core/response"
|
"github.com/documize/community/core/response"
|
||||||
"github.com/documize/community/core/stringutil"
|
"github.com/documize/community/core/stringutil"
|
||||||
|
@ -37,6 +34,7 @@ import (
|
||||||
"github.com/documize/community/model/audit"
|
"github.com/documize/community/model/audit"
|
||||||
"github.com/documize/community/model/doc"
|
"github.com/documize/community/model/doc"
|
||||||
"github.com/documize/community/model/page"
|
"github.com/documize/community/model/page"
|
||||||
|
"github.com/documize/community/model/space"
|
||||||
uuid "github.com/nu7hatch/gouuid"
|
uuid "github.com/nu7hatch/gouuid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -144,7 +142,16 @@ func (h *Handler) convert(w http.ResponseWriter, r *http.Request, job, folderID
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nd, err := processDocument(ctx, h.Runtime, h.Store, h.Indexer, filename, job, folderID, fileResult)
|
// Fetch space where document resides.
|
||||||
|
sp, err := h.Store.Space.Get(ctx, folderID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Transaction.Rollback()
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nd, err := processDocument(ctx, h.Runtime, h.Store, h.Indexer, filename, job, sp, fileResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Transaction.Rollback()
|
ctx.Transaction.Rollback()
|
||||||
response.WriteServerError(w, method, err)
|
response.WriteServerError(w, method, err)
|
||||||
|
@ -158,16 +165,16 @@ func (h *Handler) convert(w http.ResponseWriter, r *http.Request, job, folderID
|
||||||
response.WriteJSON(w, nd)
|
response.WriteJSON(w, nd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func processDocument(ctx domain.RequestContext, r *env.Runtime, store *domain.Store, indexer indexer.Indexer, filename, job, folderID string, fileResult *api.DocumentConversionResponse) (newDocument doc.Document, err error) {
|
func processDocument(ctx domain.RequestContext, r *env.Runtime, store *domain.Store, indexer indexer.Indexer, filename, job string, sp space.Space, fileResult *api.DocumentConversionResponse) (newDocument doc.Document, err error) {
|
||||||
// Convert into database objects
|
// Convert into database objects
|
||||||
document := convertFileResult(filename, fileResult)
|
document := convertFileResult(filename, fileResult)
|
||||||
document.Job = job
|
document.Job = job
|
||||||
document.OrgID = ctx.OrgID
|
document.OrgID = ctx.OrgID
|
||||||
document.LabelID = folderID
|
document.LabelID = sp.RefID
|
||||||
document.UserID = ctx.UserID
|
document.UserID = ctx.UserID
|
||||||
documentID := uniqueid.Generate()
|
documentID := uniqueid.Generate()
|
||||||
document.RefID = documentID
|
document.RefID = documentID
|
||||||
document.Lifecycle = workflow.LifecycleLive
|
document.Lifecycle = sp.Lifecycle
|
||||||
|
|
||||||
err = store.Document.Add(ctx, document)
|
err = store.Document.Add(ctx, document)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -253,22 +253,34 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record document being marked as archived.
|
// Detect change in document status/lifecycle.
|
||||||
if d.Lifecycle != oldDoc.Lifecycle && d.Lifecycle == workflow.LifecycleArchived {
|
if d.Lifecycle != oldDoc.Lifecycle {
|
||||||
h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
// Record document being marked as archived.
|
||||||
LabelID: d.LabelID,
|
if d.Lifecycle == workflow.LifecycleArchived {
|
||||||
DocumentID: documentID,
|
h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
||||||
SourceType: activity.SourceTypeDocument,
|
LabelID: d.LabelID,
|
||||||
ActivityType: activity.TypeArchived})
|
DocumentID: documentID,
|
||||||
}
|
SourceType: activity.SourceTypeDocument,
|
||||||
|
ActivityType: activity.TypeArchived})
|
||||||
|
}
|
||||||
|
|
||||||
// Record document being marked as draft.
|
// Record document being marked as draft.
|
||||||
if d.Lifecycle != oldDoc.Lifecycle && d.Lifecycle == workflow.LifecycleDraft {
|
if d.Lifecycle == workflow.LifecycleDraft {
|
||||||
h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
||||||
LabelID: d.LabelID,
|
LabelID: d.LabelID,
|
||||||
DocumentID: documentID,
|
DocumentID: documentID,
|
||||||
SourceType: activity.SourceTypeDocument,
|
SourceType: activity.SourceTypeDocument,
|
||||||
ActivityType: activity.TypeDraft})
|
ActivityType: activity.TypeDraft})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record document being marked as live.
|
||||||
|
if d.Lifecycle == workflow.LifecycleLive {
|
||||||
|
h.Store.Activity.RecordUserActivity(ctx, activity.UserActivity{
|
||||||
|
LabelID: d.LabelID,
|
||||||
|
DocumentID: documentID,
|
||||||
|
SourceType: activity.SourceTypeDocument,
|
||||||
|
ActivityType: activity.TypePublished})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Transaction.Commit()
|
ctx.Transaction.Commit()
|
||||||
|
@ -318,7 +330,7 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// If approval workflow then only approvers can delete page
|
// If approval workflow then only approvers can delete page
|
||||||
if doc.Protection == workflow.ProtectionReview {
|
if doc.Protection == workflow.ProtectionReview {
|
||||||
approvers, err := permission.GetDocumentApprovers(ctx, *h.Store, doc.LabelID, doc.RefID)
|
approvers, err := permission.GetUsersWithDocumentPermission(ctx, *h.Store, doc.LabelID, doc.RefID, pm.DocumentApprove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.WriteForbiddenError(w)
|
response.WriteForbiddenError(w)
|
||||||
h.Runtime.Log.Error(method, err)
|
h.Runtime.Log.Error(method, err)
|
||||||
|
|
|
@ -1440,7 +1440,7 @@ func (h *Handler) workflowPermitsChange(doc dm.Document, ctx domain.RequestConte
|
||||||
|
|
||||||
// If approval workflow then only approvers can delete page
|
// If approval workflow then only approvers can delete page
|
||||||
if doc.Protection == workflow.ProtectionReview {
|
if doc.Protection == workflow.ProtectionReview {
|
||||||
approvers, err := permission.GetDocumentApprovers(ctx, *h.Store, doc.LabelID, doc.RefID)
|
approvers, err := permission.GetUsersWithDocumentPermission(ctx, *h.Store, doc.LabelID, doc.RefID, pm.DocumentApprove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.Runtime.Log.Error("workflowAllowsChange", err)
|
h.Runtime.Log.Error("workflowAllowsChange", err)
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
@ -227,8 +227,74 @@ func HasPermission(ctx domain.RequestContext, s domain.Store, spaceID string, ac
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDocumentApprovers returns list of users who can approve given document in given space
|
// // GetDocumentApprovers returns list of users who can approve given document in given space
|
||||||
func GetDocumentApprovers(ctx domain.RequestContext, s domain.Store, spaceID, documentID string) (users []u.User, err error) {
|
// func GetDocumentApprovers(ctx domain.RequestContext, s domain.Store, spaceID, documentID string) (users []u.User, err error) {
|
||||||
|
// users = []u.User{}
|
||||||
|
// prev := make(map[string]bool) // used to ensure we only process user once
|
||||||
|
|
||||||
|
// // Permissions can be assigned to both groups and individual users.
|
||||||
|
// // Pre-fetch users with group membership to help us work out
|
||||||
|
// // if user belongs to a group with permissions.
|
||||||
|
// groupMembers, err := s.Group.GetMembers(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// return users, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // space permissions
|
||||||
|
// sp, err := s.Permission.GetSpacePermissions(ctx, spaceID)
|
||||||
|
// if err != nil {
|
||||||
|
// return users, err
|
||||||
|
// }
|
||||||
|
// // document permissions
|
||||||
|
// dp, err := s.Permission.GetDocumentPermissions(ctx, documentID)
|
||||||
|
// if err != nil {
|
||||||
|
// return users, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // all permissions
|
||||||
|
// all := sp
|
||||||
|
// all = append(all, dp...)
|
||||||
|
|
||||||
|
// for _, p := range all {
|
||||||
|
// // only approvers
|
||||||
|
// if p.Action != pm.DocumentApprove {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if p.Who == pm.GroupPermission {
|
||||||
|
// // get group records for just this group
|
||||||
|
// groupRecords := group.FilterGroupRecords(groupMembers, p.WhoID)
|
||||||
|
|
||||||
|
// for i := range groupRecords {
|
||||||
|
// user, err := s.User.Get(ctx, groupRecords[i].UserID)
|
||||||
|
// if err != nil {
|
||||||
|
// return users, err
|
||||||
|
// }
|
||||||
|
// if _, isExisting := prev[user.RefID]; !isExisting {
|
||||||
|
// users = append(users, user)
|
||||||
|
// prev[user.RefID] = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if p.Who == pm.UserPermission {
|
||||||
|
// user, err := s.User.Get(ctx, p.WhoID)
|
||||||
|
// if err != nil {
|
||||||
|
// return users, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if _, isExisting := prev[user.RefID]; !isExisting {
|
||||||
|
// users = append(users, user)
|
||||||
|
// prev[user.RefID] = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return users, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GetUsersWithDocumentPermission returns list of users who have specified document permission in given space
|
||||||
|
func GetUsersWithDocumentPermission(ctx domain.RequestContext, s domain.Store, spaceID, documentID string, permissionRequired pm.Action) (users []u.User, err error) {
|
||||||
users = []u.User{}
|
users = []u.User{}
|
||||||
prev := make(map[string]bool) // used to ensure we only process user once
|
prev := make(map[string]bool) // used to ensure we only process user once
|
||||||
|
|
||||||
|
@ -257,7 +323,7 @@ func GetDocumentApprovers(ctx domain.RequestContext, s domain.Store, spaceID, do
|
||||||
|
|
||||||
for _, p := range all {
|
for _, p := range all {
|
||||||
// only approvers
|
// only approvers
|
||||||
if p.Action != pm.DocumentApprove {
|
if p.Action != permissionRequired {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ func (s Scope) Add(ctx domain.RequestContext, sp space.Space) (err error) {
|
||||||
sp.Created = time.Now().UTC()
|
sp.Created = time.Now().UTC()
|
||||||
sp.Revised = time.Now().UTC()
|
sp.Revised = time.Now().UTC()
|
||||||
|
|
||||||
_, err = ctx.Transaction.Exec("INSERT INTO label (refid, label, orgid, userid, type, likes, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
_, err = ctx.Transaction.Exec("INSERT INTO label (refid, label, orgid, userid, type, lifecycle, likes, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
sp.RefID, sp.Name, sp.OrgID, sp.UserID, sp.Type, sp.Likes, sp.Created, sp.Revised)
|
sp.RefID, sp.Name, sp.OrgID, sp.UserID, sp.Type, sp.Lifecycle, sp.Likes, sp.Created, sp.Revised)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "unable to execute insert for label")
|
err = errors.Wrap(err, "unable to execute insert for label")
|
||||||
|
@ -47,7 +47,7 @@ func (s Scope) Add(ctx domain.RequestContext, sp space.Space) (err error) {
|
||||||
|
|
||||||
// Get returns a space from the store.
|
// Get returns a space from the store.
|
||||||
func (s Scope) Get(ctx domain.RequestContext, id string) (sp space.Space, err error) {
|
func (s Scope) Get(ctx domain.RequestContext, id string) (sp space.Space, err error) {
|
||||||
err = s.Runtime.Db.Get(&sp, "SELECT id,refid,label as name,orgid,userid,type,likes,created,revised FROM label WHERE orgid=? and refid=?",
|
err = s.Runtime.Db.Get(&sp, "SELECT id,refid,label as name,orgid,userid,type,lifecycle,likes,created,revised FROM label WHERE orgid=? and refid=?",
|
||||||
ctx.OrgID, id)
|
ctx.OrgID, id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -59,7 +59,7 @@ func (s Scope) Get(ctx domain.RequestContext, id string) (sp space.Space, err er
|
||||||
|
|
||||||
// PublicSpaces returns spaces that anyone can see.
|
// PublicSpaces returns spaces that anyone can see.
|
||||||
func (s Scope) PublicSpaces(ctx domain.RequestContext, orgID string) (sp []space.Space, err error) {
|
func (s Scope) PublicSpaces(ctx domain.RequestContext, orgID string) (sp []space.Space, err error) {
|
||||||
qry := "SELECT id,refid,label as name,orgid,userid,type,likes,created,revised FROM label a where orgid=? AND type=1"
|
qry := "SELECT id,refid,label as name,orgid,userid,type,lifecycle,likes,created,revised FROM label a where orgid=? AND type=1"
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&sp, qry, orgID)
|
err = s.Runtime.Db.Select(&sp, qry, orgID)
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ func (s Scope) PublicSpaces(ctx domain.RequestContext, orgID string) (sp []space
|
||||||
// Also handles which spaces can be seen by anonymous users.
|
// Also handles which spaces can be seen by anonymous users.
|
||||||
func (s Scope) GetViewable(ctx domain.RequestContext) (sp []space.Space, err error) {
|
func (s Scope) GetViewable(ctx domain.RequestContext) (sp []space.Space, err error) {
|
||||||
q := `
|
q := `
|
||||||
SELECT id,refid,label as name,orgid,userid,type,likes,created,revised FROM label
|
SELECT id,refid,label as name,orgid,userid,type,lifecycle,likes,created,revised FROM label
|
||||||
WHERE orgid=?
|
WHERE orgid=?
|
||||||
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view' UNION ALL
|
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view' UNION ALL
|
||||||
|
@ -109,7 +109,7 @@ func (s Scope) GetViewable(ctx domain.RequestContext) (sp []space.Space, err err
|
||||||
// GetAll for admin users!
|
// GetAll for admin users!
|
||||||
func (s Scope) GetAll(ctx domain.RequestContext) (sp []space.Space, err error) {
|
func (s Scope) GetAll(ctx domain.RequestContext) (sp []space.Space, err error) {
|
||||||
qry := `
|
qry := `
|
||||||
SELECT id,refid,label as name,orgid,userid,type,likes,created,revised FROM label
|
SELECT id,refid,label as name,orgid,userid,type,lifecycle,likes,created,revised FROM label
|
||||||
WHERE orgid=?
|
WHERE orgid=?
|
||||||
ORDER BY name`
|
ORDER BY name`
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ func (s Scope) GetAll(ctx domain.RequestContext) (sp []space.Space, err error) {
|
||||||
func (s Scope) Update(ctx domain.RequestContext, sp space.Space) (err error) {
|
func (s Scope) Update(ctx domain.RequestContext, sp space.Space) (err error) {
|
||||||
sp.Revised = time.Now().UTC()
|
sp.Revised = time.Now().UTC()
|
||||||
|
|
||||||
_, err = ctx.Transaction.NamedExec("UPDATE label SET label=:name, type=:type, userid=:userid, likes=:likes, revised=:revised WHERE orgid=:orgid AND refid=:refid", &sp)
|
_, err = ctx.Transaction.NamedExec("UPDATE label SET label=:name, type=:type, lifecycle=:lifecycle, userid=:userid, likes=:likes, revised=:revised WHERE orgid=:orgid AND refid=:refid", &sp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, fmt.Sprintf("unable to execute update for label %s", sp.RefID))
|
err = errors.Wrap(err, fmt.Sprintf("unable to execute update for label %s", sp.RefID))
|
||||||
|
|
|
@ -294,6 +294,14 @@ func (h *Handler) Use(w http.ResponseWriter, r *http.Request) {
|
||||||
attachments, _ = h.Store.Attachment.GetAttachmentsWithData(ctx, templateID)
|
attachments, _ = h.Store.Attachment.GetAttachmentsWithData(ctx, templateID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch space where document resides.
|
||||||
|
sp, err := h.Store.Space.Get(ctx, folderID)
|
||||||
|
if err != nil {
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.WriteServerError(w, method, err)
|
response.WriteServerError(w, method, err)
|
||||||
|
@ -308,7 +316,7 @@ func (h *Handler) Use(w http.ResponseWriter, r *http.Request) {
|
||||||
d.LabelID = folderID
|
d.LabelID = folderID
|
||||||
d.UserID = ctx.UserID
|
d.UserID = ctx.UserID
|
||||||
d.Title = docTitle
|
d.Title = docTitle
|
||||||
d.Lifecycle = workflow.LifecycleLive
|
d.Lifecycle = sp.Lifecycle
|
||||||
|
|
||||||
err = h.Store.Document.Add(ctx, d)
|
err = h.Store.Document.Add(ctx, d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -41,7 +41,7 @@ func main() {
|
||||||
// product details
|
// product details
|
||||||
rt.Product = env.ProdInfo{}
|
rt.Product = env.ProdInfo{}
|
||||||
rt.Product.Major = "1"
|
rt.Product.Major = "1"
|
||||||
rt.Product.Minor = "62"
|
rt.Product.Minor = "63"
|
||||||
rt.Product.Patch = "0"
|
rt.Product.Patch = "0"
|
||||||
rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch)
|
rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch)
|
||||||
rt.Product.Edition = "Community"
|
rt.Product.Edition = "Community"
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "documize",
|
"name": "documize",
|
||||||
"version": "1.62.0",
|
"version": "1.63.0",
|
||||||
"description": "The Document IDE",
|
"description": "The Document IDE",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": "",
|
"repository": "",
|
||||||
|
|
|
@ -18,7 +18,6 @@ Convert test to support i.get() as per toc.js
|
||||||
// import { module, test } from 'qunit';
|
// import { module, test } from 'qunit';
|
||||||
// import { setupTest } from 'ember-qunit';
|
// import { setupTest } from 'ember-qunit';
|
||||||
// import toc from 'documize/utils/toc';
|
// import toc from 'documize/utils/toc';
|
||||||
// import models from 'documize/utils/model';
|
|
||||||
|
|
||||||
// module('Unit | Utility | TOC', function (hooks) {
|
// module('Unit | Utility | TOC', function (hooks) {
|
||||||
// setupTest(hooks);
|
// setupTest(hooks);
|
||||||
|
|
|
@ -112,6 +112,9 @@ const (
|
||||||
// TypeSearched records user performing document keyword search.
|
// TypeSearched records user performing document keyword search.
|
||||||
// Metadata field should contain search terms.
|
// Metadata field should contain search terms.
|
||||||
TypeSearched Type = 15
|
TypeSearched Type = 15
|
||||||
|
|
||||||
|
// TypePublished happens when a document is moved from Draft to Live.
|
||||||
|
TypePublished Type = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
// TypeName returns one-work descriptor for activity type
|
// TypeName returns one-work descriptor for activity type
|
||||||
|
@ -147,6 +150,8 @@ func TypeName(t Type) string {
|
||||||
return "Version"
|
return "Version"
|
||||||
case TypeSearched:
|
case TypeSearched:
|
||||||
return "Search"
|
return "Search"
|
||||||
|
case TypePublished:
|
||||||
|
return "Publish"
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -13,6 +13,7 @@ package space
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/documize/community/model"
|
"github.com/documize/community/model"
|
||||||
|
"github.com/documize/community/model/workflow"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Space defines a container for documents.
|
// Space defines a container for documents.
|
||||||
|
@ -22,6 +23,10 @@ type Space struct {
|
||||||
OrgID string `json:"orgId"`
|
OrgID string `json:"orgId"`
|
||||||
UserID string `json:"userId"`
|
UserID string `json:"userId"`
|
||||||
Type Scope `json:"folderType"`
|
Type Scope `json:"folderType"`
|
||||||
|
|
||||||
|
// Lifecycle stores the default value all new documents are given upon creation.
|
||||||
|
Lifecycle workflow.Lifecycle `json:"lifecycle"`
|
||||||
|
|
||||||
// Likes stores the question to ask the user such as 'Did this help you?'.
|
// Likes stores the question to ask the user such as 'Did this help you?'.
|
||||||
// An empty value tells us liking is not allowed.
|
// An empty value tells us liking is not allowed.
|
||||||
Likes string `json:"likes"`
|
Likes string `json:"likes"`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue