mirror of
https://github.com/documize/community.git
synced 2025-07-18 20:59:43 +02:00
Provider foundation for doc lifecycle and versions
This commit is contained in:
parent
4e32bffebe
commit
958f4d30b9
19 changed files with 918 additions and 782 deletions
|
@ -25,7 +25,7 @@ Anyone who wants a single place for any kind of document.
|
|||
Anyone who wants to loop in external participants complete security.
|
||||
|
||||
Anyone who wishes documentation and knowledge capture worked like agile software development.
|
||||
|
||||
|
||||
## What's different about Documize?
|
||||
|
||||
Sane organization through personal, team and public spaces.
|
||||
|
@ -52,7 +52,7 @@ Space view.
|
|||
|
||||
## Latest version
|
||||
|
||||
Community edition: v1.58.0
|
||||
Community edition: v1.59.0
|
||||
|
||||
## OS support
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (er
|
|||
}
|
||||
|
||||
// assign permissions to space
|
||||
perms := []string{"view", "manage", "own", "doc-add", "doc-edit", "doc-delete", "doc-move", "doc-copy", "doc-template", "doc-approve"}
|
||||
perms := []string{"view", "manage", "own", "doc-add", "doc-edit", "doc-delete", "doc-move", "doc-copy", "doc-template", "doc-approve", "doc-version", "doc-lifecycle"}
|
||||
for _, p := range perms {
|
||||
sql = fmt.Sprintf("insert into permission (orgid, who, whoid, action, scope, location, refid) values (\"%s\", 'user', \"%s\", \"%s\", 'object', 'space', \"%s\")", orgID, userID, p, labelID)
|
||||
_, err = runSQL(rt, sql)
|
||||
|
|
22
core/database/scripts/autobuild/db_00019.sql
Normal file
22
core/database/scripts/autobuild/db_00019.sql
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* enterprise edition */
|
||||
|
||||
-- document lifecycle and versions
|
||||
ALTER TABLE document ADD COLUMN `lifecycle` INT NOT NULL DEFAULT 1 AFTER `approval`;
|
||||
ALTER TABLE document ADD COLUMN `versioned` INT NOT NULL DEFAULT 0 AFTER `lifecycle`;
|
||||
ALTER TABLE document ADD COLUMN `versionid` VARCHAR(100) DEFAULT '' NOT NULL AFTER `versioned`;
|
||||
ALTER TABLE document ADD COLUMN `versionorder` INT NOT NULL DEFAULT 0 AFTER `versionid`;
|
||||
ALTER TABLE document ADD COLUMN `groupid` CHAR(16) NOT NULL COLLATE utf8_bin AFTER `versionorder`;
|
||||
|
||||
-- grant doc-lifecycle permission
|
||||
INSERT INTO permission(orgid, who, whoid, action, scope, location, refid, created)
|
||||
SELECT orgid, who, whoid, 'doc-lifecycle' AS action, scope, location, refid, created
|
||||
FROM permission
|
||||
WHERE action = 'doc-edit' OR action = 'doc-approve';
|
||||
|
||||
-- grant doc-versions permission
|
||||
INSERT INTO permission(orgid, who, whoid, action, scope, location, refid, created)
|
||||
SELECT orgid, who, whoid, 'doc-version' AS action, scope, location, refid, created
|
||||
FROM permission
|
||||
WHERE action = 'doc-edit' OR action = 'doc-approve';
|
||||
|
||||
-- deprecations
|
|
@ -30,6 +30,7 @@ import (
|
|||
indexer "github.com/documize/community/domain/search"
|
||||
"github.com/documize/community/model/attachment"
|
||||
"github.com/documize/community/model/audit"
|
||||
"github.com/documize/community/model/workflow"
|
||||
uuid "github.com/nu7hatch/gouuid"
|
||||
)
|
||||
|
||||
|
@ -161,7 +162,12 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
a, _ := h.Store.Attachment.GetAttachments(ctx, documentID)
|
||||
d, _ := h.Store.Document.Get(ctx, documentID)
|
||||
go h.Indexer.IndexDocument(ctx, d, a)
|
||||
|
||||
if d.Lifecycle == workflow.LifecycleLive {
|
||||
go h.Indexer.IndexDocument(ctx, d, a)
|
||||
} else {
|
||||
go h.Indexer.DeleteDocument(ctx, d.RefID)
|
||||
}
|
||||
|
||||
response.WriteEmpty(w)
|
||||
}
|
||||
|
@ -236,7 +242,12 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
all, _ := h.Store.Attachment.GetAttachments(ctx, documentID)
|
||||
d, _ := h.Store.Document.Get(ctx, documentID)
|
||||
go h.Indexer.IndexDocument(ctx, d, all)
|
||||
|
||||
if d.Lifecycle == workflow.LifecycleLive {
|
||||
go h.Indexer.IndexDocument(ctx, d, all)
|
||||
} else {
|
||||
go h.Indexer.DeleteDocument(ctx, d.RefID)
|
||||
}
|
||||
|
||||
response.WriteEmpty(w)
|
||||
}
|
||||
|
|
|
@ -249,7 +249,12 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
|
|||
h.Store.Audit.Record(ctx, audit.EventTypeDocumentUpdate)
|
||||
|
||||
a, _ := h.Store.Attachment.GetAttachments(ctx, documentID)
|
||||
go h.Indexer.IndexDocument(ctx, d, a)
|
||||
|
||||
if d.Lifecycle == workflow.LifecycleLive {
|
||||
go h.Indexer.IndexDocument(ctx, d, a)
|
||||
} else {
|
||||
go h.Indexer.DeleteDocument(ctx, d.RefID)
|
||||
}
|
||||
|
||||
response.WriteEmpty(w)
|
||||
}
|
||||
|
|
|
@ -29,13 +29,16 @@ type Scope struct {
|
|||
}
|
||||
|
||||
// Add inserts the given document record into the document table and audits that it has been done.
|
||||
func (s Scope) Add(ctx domain.RequestContext, document doc.Document) (err error) {
|
||||
document.OrgID = ctx.OrgID
|
||||
document.Created = time.Now().UTC()
|
||||
document.Revised = document.Created // put same time in both fields
|
||||
func (s Scope) Add(ctx domain.RequestContext, d doc.Document) (err error) {
|
||||
d.OrgID = ctx.OrgID
|
||||
d.Created = time.Now().UTC()
|
||||
d.Revised = d.Created // put same time in both fields
|
||||
|
||||
_, err = ctx.Transaction.Exec("INSERT INTO document (refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
document.RefID, document.OrgID, document.LabelID, document.UserID, document.Job, document.Location, document.Title, document.Excerpt, document.Slug, document.Tags, document.Template, document.Protection, document.Approval, document.Created, document.Revised)
|
||||
_, err = ctx.Transaction.Exec(`
|
||||
INSERT INTO document (refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, lifecycle, versioned, versionid, versionorder, groupid, created, revised)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
d.RefID, d.OrgID, d.LabelID, d.UserID, d.Job, d.Location, d.Title, d.Excerpt, d.Slug, d.Tags,
|
||||
d.Template, d.Protection, d.Approval, d.Lifecycle, d.Versioned, d.VersionID, d.VersionOrder, d.GroupID, d.Created, d.Revised)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "execuet insert document")
|
||||
|
@ -46,7 +49,11 @@ func (s Scope) Add(ctx domain.RequestContext, document doc.Document) (err error)
|
|||
|
||||
// Get fetches the document record with the given id fromt the document table and audits that it has been got.
|
||||
func (s Scope) Get(ctx domain.RequestContext, id string) (document doc.Document, err error) {
|
||||
err = s.Runtime.Db.Get(&document, "SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, created, revised FROM document WHERE orgid=? and refid=?",
|
||||
err = s.Runtime.Db.Get(&document, `
|
||||
SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template,
|
||||
protection, approval, lifecycle, versioned, versionid, versionorder, groupid, created, revised
|
||||
FROM document
|
||||
WHERE orgid=? and refid=?`,
|
||||
ctx.OrgID, id)
|
||||
|
||||
if err != nil {
|
||||
|
@ -106,21 +113,23 @@ func (s Scope) GetAll() (ctx domain.RequestContext, documents []doc.Document, er
|
|||
// by category permissions -- caller must filter as required.
|
||||
func (s Scope) GetBySpace(ctx domain.RequestContext, spaceID string) (documents []doc.Document, err error) {
|
||||
err = s.Runtime.Db.Select(&documents, `
|
||||
SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, created, revised
|
||||
SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template,
|
||||
protection, approval, lifecycle, versioned, versionid, versionorder, groupid, created, revised
|
||||
FROM document
|
||||
WHERE orgid=? AND template=0 AND labelid IN (
|
||||
SELECT refid FROM label WHERE orgid=? AND refid IN
|
||||
SELECT refid FROM label WHERE orgid=? AND refid IN
|
||||
(SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid=? AND refid IN (
|
||||
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view'
|
||||
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view'
|
||||
UNION ALL
|
||||
SELECT p.refid from permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=?
|
||||
SELECT p.refid from permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=?
|
||||
AND p.who='role' AND p.location='space' AND p.refid=? AND p.action='view' AND (r.userid=? OR r.userid='0')
|
||||
))
|
||||
)
|
||||
ORDER BY title`, ctx.OrgID, ctx.OrgID, ctx.OrgID, spaceID, ctx.OrgID, ctx.UserID, ctx.OrgID, spaceID, ctx.UserID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
if err == sql.ErrNoRows || len(documents) == 0 {
|
||||
err = nil
|
||||
documents = []doc.Document{}
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "select documents by space")
|
||||
|
@ -132,18 +141,25 @@ func (s Scope) GetBySpace(ctx domain.RequestContext, spaceID string) (documents
|
|||
// Templates returns a slice containing the documents available as templates to the client's organisation, in title order.
|
||||
func (s Scope) Templates(ctx domain.RequestContext) (documents []doc.Document, err error) {
|
||||
err = s.Runtime.Db.Select(&documents,
|
||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, created, revised FROM document WHERE orgid=? AND template=1
|
||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template,
|
||||
protection, approval, lifecycle, versioned, versionid, versionorder, groupid, created, revised
|
||||
FROM document
|
||||
WHERE orgid=? AND template=1 AND lifecycle=1
|
||||
AND labelid IN
|
||||
(
|
||||
SELECT refid FROM label WHERE orgid=?
|
||||
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'
|
||||
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view'
|
||||
UNION ALL
|
||||
SELECT p.refid from permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' AND p.location='space' AND p.action='view' AND (r.userid=? OR r.userid='0')
|
||||
))
|
||||
)
|
||||
ORDER BY title`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||
|
||||
if err == sql.ErrNoRows || len(documents) == 0 {
|
||||
err = nil
|
||||
documents = []doc.Document{}
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "select document templates")
|
||||
}
|
||||
|
@ -154,12 +170,15 @@ func (s Scope) Templates(ctx domain.RequestContext) (documents []doc.Document, e
|
|||
// TemplatesBySpace returns a slice containing the documents available as templates for given space.
|
||||
func (s Scope) TemplatesBySpace(ctx domain.RequestContext, spaceID string) (documents []doc.Document, err error) {
|
||||
err = s.Runtime.Db.Select(&documents,
|
||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, created, revised FROM document WHERE orgid=? AND labelid=? AND template=1
|
||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template,
|
||||
protection, approval, lifecycle, versioned, versionid, versionorder, groupid, created, revised
|
||||
FROM document
|
||||
WHERE orgid=? AND labelid=? AND template=1 ANd lifecycle=1
|
||||
AND labelid IN
|
||||
(
|
||||
SELECT refid FROM label WHERE orgid=?
|
||||
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'
|
||||
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view'
|
||||
UNION ALL
|
||||
SELECT p.refid from permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' AND p.location='space' AND p.action='view' AND (r.userid=? OR r.userid='0')
|
||||
))
|
||||
|
@ -170,7 +189,6 @@ func (s Scope) TemplatesBySpace(ctx domain.RequestContext, spaceID string) (docu
|
|||
err = nil
|
||||
documents = []doc.Document{}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "select space document templates")
|
||||
}
|
||||
|
@ -184,9 +202,14 @@ func (s Scope) PublicDocuments(ctx domain.RequestContext, orgID string) (documen
|
|||
`SELECT d.refid as documentid, d.title as document, d.revised as revised, l.refid as folderid, l.label as folder
|
||||
FROM document d LEFT JOIN label l ON l.refid=d.labelid
|
||||
WHERE d.orgid=?
|
||||
AND l.type=1
|
||||
AND d.template=0`, orgID)
|
||||
AND l.type=1
|
||||
AND d.lifecycle=1
|
||||
AND d.template=0`, orgID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
documents = []doc.SitemapDocument{}
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("execute GetPublicDocuments for org %s%s", orgID))
|
||||
}
|
||||
|
@ -197,12 +220,15 @@ func (s Scope) PublicDocuments(ctx domain.RequestContext, orgID string) (documen
|
|||
// DocumentList returns a slice containing the documents available as templates to the client's organisation, in title order.
|
||||
func (s Scope) DocumentList(ctx domain.RequestContext) (documents []doc.Document, err error) {
|
||||
err = s.Runtime.Db.Select(&documents,
|
||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, protection, approval, created, revised FROM document WHERE orgid=? AND template=0
|
||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template,
|
||||
protection, approval, lifecycle, versioned, versionid, versionorder, groupid, created, revised
|
||||
FROM document
|
||||
WHERE orgid=? AND template=0 AND lifecycle=1
|
||||
AND labelid IN
|
||||
(
|
||||
SELECT refid FROM label WHERE orgid=?
|
||||
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'
|
||||
SELECT refid from permission WHERE orgid=? AND who='user' AND (whoid=? OR whoid='0') AND location='space' AND action='view'
|
||||
UNION ALL
|
||||
SELECT p.refid from permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' AND p.location='space' AND p.action='view' AND (r.userid=? OR r.userid='0')
|
||||
))
|
||||
|
@ -213,7 +239,6 @@ func (s Scope) DocumentList(ctx domain.RequestContext) (documents []doc.Document
|
|||
err = nil
|
||||
documents = []doc.Document{}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "select documents list")
|
||||
}
|
||||
|
@ -225,7 +250,12 @@ func (s Scope) DocumentList(ctx domain.RequestContext) (documents []doc.Document
|
|||
func (s Scope) Update(ctx domain.RequestContext, document doc.Document) (err error) {
|
||||
document.Revised = time.Now().UTC()
|
||||
|
||||
_, err = ctx.Transaction.NamedExec("UPDATE document SET labelid=:labelid, userid=:userid, job=:job, location=:location, title=:title, excerpt=:excerpt, slug=:slug, tags=:tags, template=:template, protection=:protection, approval=:approval, revised=:revised WHERE orgid=:orgid AND refid=:refid",
|
||||
_, err = ctx.Transaction.NamedExec(`
|
||||
UPDATE document
|
||||
SET
|
||||
labelid=:labelid, userid=:userid, job=:job, location=:location, title=:title, excerpt=:excerpt, slug=:slug, tags=:tags, template=:template,
|
||||
protection=:protection, approval=:approval, lifecycle=:lifecycle, versioned=:versioned, versionid=:versionid, versionorder=:versionorder, groupid=:groupid, revised=:revised
|
||||
WHERE orgid=:orgid AND refid=:refid`,
|
||||
&document)
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -176,7 +176,12 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
|
|||
h.Store.Audit.Record(ctx, audit.EventTypeSectionAdd)
|
||||
|
||||
np, _ := h.Store.Page.Get(ctx, pageID)
|
||||
go h.Indexer.IndexContent(ctx, np)
|
||||
|
||||
if doc.Lifecycle == workflow.LifecycleLive {
|
||||
go h.Indexer.IndexContent(ctx, np)
|
||||
} else {
|
||||
go h.Indexer.DeleteDocument(ctx, doc.RefID)
|
||||
}
|
||||
|
||||
response.WriteJSON(w, np)
|
||||
}
|
||||
|
@ -309,6 +314,7 @@ func (h *Handler) GetMeta(w http.ResponseWriter, r *http.Request) {
|
|||
// Update will persist changed page and note the fact
|
||||
// that this is a new revision. If the page is the first in a document
|
||||
// then the corresponding document title will also be changed.
|
||||
// Draft documents do not get revision entry.
|
||||
func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
|
||||
method := "page.update"
|
||||
ctx := domain.GetRequestContext(r)
|
||||
|
@ -406,6 +412,11 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
|
|||
skipRevision = true
|
||||
}
|
||||
|
||||
// We only track revisions for live documents
|
||||
if doc.Lifecycle != workflow.LifecycleLive {
|
||||
skipRevision = true
|
||||
}
|
||||
|
||||
err = h.Store.Page.Update(ctx, model.Page, refID, ctx.UserID, skipRevision)
|
||||
if err != nil {
|
||||
ctx.Transaction.Rollback()
|
||||
|
@ -470,7 +481,11 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
ctx.Transaction.Commit()
|
||||
|
||||
go h.Indexer.IndexContent(ctx, model.Page)
|
||||
if doc.Lifecycle == workflow.LifecycleLive {
|
||||
go h.Indexer.IndexContent(ctx, model.Page)
|
||||
} else {
|
||||
go h.Indexer.DeleteDocument(ctx, doc.RefID)
|
||||
}
|
||||
|
||||
updatedPage, err := h.Store.Page.Get(ctx, pageID)
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/documize/community/model/page"
|
||||
pm "github.com/documize/community/model/permission"
|
||||
"github.com/documize/community/model/template"
|
||||
"github.com/documize/community/model/workflow"
|
||||
uuid "github.com/nu7hatch/gouuid"
|
||||
)
|
||||
|
||||
|
@ -377,7 +378,12 @@ func (h *Handler) Use(w http.ResponseWriter, r *http.Request) {
|
|||
event.Handler().Publish(string(event.TypeAddDocument), nd.Title)
|
||||
|
||||
a, _ := h.Store.Attachment.GetAttachments(ctx, documentID)
|
||||
go h.Indexer.IndexDocument(ctx, nd, a)
|
||||
|
||||
if nd.Lifecycle == workflow.LifecycleLive {
|
||||
go h.Indexer.IndexDocument(ctx, nd, a)
|
||||
} else {
|
||||
go h.Indexer.DeleteDocument(ctx, d.RefID)
|
||||
}
|
||||
|
||||
response.WriteJSON(w, nd)
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func main() {
|
|||
// product details
|
||||
rt.Product = env.ProdInfo{}
|
||||
rt.Product.Major = "1"
|
||||
rt.Product.Minor = "58"
|
||||
rt.Product.Minor = "59"
|
||||
rt.Product.Patch = "0"
|
||||
rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch)
|
||||
rt.Product.Edition = "Community"
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,12 +19,12 @@ export default Component.extend(ModalMixin, {
|
|||
groupSvc: service('group'),
|
||||
spaceSvc: service('folder'),
|
||||
userSvc: service('user'),
|
||||
appMeta: service(),
|
||||
appMeta: service(),
|
||||
store: service(),
|
||||
spacePermissions: null,
|
||||
users: null,
|
||||
searchText: '',
|
||||
|
||||
|
||||
didReceiveAttrs() {
|
||||
let spacePermissions = A([]);
|
||||
let constants = this.get('constants');
|
||||
|
@ -65,7 +65,7 @@ export default Component.extend(ModalMixin, {
|
|||
// always show everyone
|
||||
if (!hasEveryoneId) {
|
||||
let pr = this.permissionRecord(constants.WhoType.User, constants.EveryoneUserId, ' ' + constants.EveryoneUserName);
|
||||
spacePermissions.pushObject(pr);
|
||||
spacePermissions.pushObject(pr);
|
||||
}
|
||||
|
||||
this.set('spacePermissions', spacePermissions.sortBy('who', 'name'));
|
||||
|
@ -93,6 +93,8 @@ export default Component.extend(ModalMixin, {
|
|||
documentCopy: false,
|
||||
documentTemplate: false,
|
||||
documentApprove: false,
|
||||
documentLifecycle: false,
|
||||
documentVersion: false,
|
||||
};
|
||||
|
||||
let rec = this.get('store').normalize('space-permission', raw);
|
||||
|
@ -132,7 +134,8 @@ export default Component.extend(ModalMixin, {
|
|||
let hasEveryone = _.find(permissions, (permission) => {
|
||||
return permission.get('whoId') === constants.EveryoneUserId &&
|
||||
(permission.get('spaceView') || permission.get('documentAdd') || permission.get('documentEdit') || permission.get('documentDelete') ||
|
||||
permission.get('documentMove') || permission.get('documentCopy') || permission.get('documentTemplate') || permission.get('documentApprove'));
|
||||
permission.get('documentMove') || permission.get('documentCopy') || permission.get('documentTemplate') ||
|
||||
permission.get('documentApprove') || permission.get('documentLifecycle') || permission.get('documentVersion'));
|
||||
});
|
||||
|
||||
// see if more than oen user is granted access to space (excluding everyone)
|
||||
|
@ -140,8 +143,9 @@ export default Component.extend(ModalMixin, {
|
|||
permissions.forEach((permission) => {
|
||||
if (permission.get('whoId') !== constants.EveryoneUserId &&
|
||||
(permission.get('spaceView') || permission.get('documentAdd') || permission.get('documentEdit') || permission.get('documentDelete') ||
|
||||
permission.get('documentMove') || permission.get('documentCopy') || permission.get('documentTemplate') || permission.get('documentApprove'))) {
|
||||
roleCount += 1;
|
||||
permission.get('documentMove') || permission.get('documentCopy') || permission.get('documentTemplate') ||
|
||||
permission.get('documentApprove') || permission.get('documentLifecycle') || permission.get('documentVersion'))) {
|
||||
roleCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -161,7 +165,7 @@ export default Component.extend(ModalMixin, {
|
|||
},
|
||||
|
||||
onSearch() {
|
||||
debounce(this, function() {
|
||||
debounce(this, function () {
|
||||
let searchText = this.get('searchText').trim();
|
||||
|
||||
if (searchText.length === 0) {
|
||||
|
@ -181,7 +185,6 @@ export default Component.extend(ModalMixin, {
|
|||
if (is.undefined(exists)) {
|
||||
spacePermissions.pushObject(this.permissionRecord(constants.WhoType.User, user.get('id'), user.get('fullname')));
|
||||
this.set('spacePermissions', spacePermissions);
|
||||
// this.set('spacePermissions', spacePermissions.sortBy('who', 'name'));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ export default Model.extend({
|
|||
documentCopy: attr('boolean'),
|
||||
documentTemplate: attr('boolean'),
|
||||
documentApprove: attr('boolean'),
|
||||
documentLifecycle: attr('boolean'),
|
||||
documentVersion: attr('boolean'),
|
||||
name: attr('string'), // read-only
|
||||
members: attr('number') // read-only
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="modal-header">Space Permissions</div>
|
||||
<div class="modal-body" style="overflow-x: auto;">
|
||||
<div class="space-admin table-responsive">
|
||||
|
||||
|
||||
<table class="table table-hover permission-table mb-3">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -24,6 +24,8 @@
|
|||
<th class="text-info">Copy</th>
|
||||
<th class="text-info">Templates</th>
|
||||
<th class="text-info">Approval</th>
|
||||
<th class="text-info">Lifecycle</th>
|
||||
<th class="text-info">Versions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -38,53 +40,35 @@
|
|||
<small class="form-text text-muted d-inline-block">({{permission.members}})</small>
|
||||
</span>
|
||||
{{else}}
|
||||
{{#if (eq permission.whoId constants.EveryoneUserId)}}
|
||||
<span class="button-icon-green button-icon-small align-middle">
|
||||
<i class="material-icons">language</i>
|
||||
</span>
|
||||
<span class="color-green"> {{permission.name}}</span>
|
||||
{{else}}
|
||||
<span class="button-icon-gray button-icon-small align-middle">
|
||||
<i class="material-icons">person</i>
|
||||
</span>
|
||||
<span class=""> {{permission.name}}
|
||||
{{#if (eq permission.whoId session.user.id)}}
|
||||
<small class="form-text text-muted d-inline-block">(you)</small>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
{{#if (eq permission.whoId constants.EveryoneUserId)}}
|
||||
<span class="button-icon-green button-icon-small align-middle">
|
||||
<i class="material-icons">language</i>
|
||||
</span>
|
||||
<span class="color-green"> {{permission.name}}</span>
|
||||
{{else}}
|
||||
<span class="button-icon-gray button-icon-small align-middle">
|
||||
<i class="material-icons">person</i>
|
||||
</span>
|
||||
<span class=""> {{permission.name}}
|
||||
{{#if (eq permission.whoId session.user.id)}}
|
||||
<small class="form-text text-muted d-inline-block">(you)</small>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'space-role-view-' permission.whoId) checked=permission.spaceView}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'space-role-manage-' permission.whoId) checked=permission.spaceManage}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'space-role-owner-' permission.whoId) checked=permission.spaceOwner}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-add-' permission.whoId) checked=permission.documentAdd}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-edit-' permission.whoId) checked=permission.documentEdit}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-delete-' permission.whoId) checked=permission.documentDelete}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-move-' permission.whoId) checked=permission.documentMove}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-copy-' permission.whoId) checked=permission.documentCopy}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-template-' permission.whoId) checked=permission.documentTemplate}}
|
||||
</td>
|
||||
<td>
|
||||
{{input type="checkbox" id=(concat 'doc-role-approve-' permission.whoId) checked=permission.documentApprove}}
|
||||
</td>
|
||||
<td>{{input type="checkbox" id=(concat 'space-role-view-' permission.whoId) checked=permission.spaceView}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'space-role-manage-' permission.whoId) checked=permission.spaceManage}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'space-role-owner-' permission.whoId) checked=permission.spaceOwner}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-add-' permission.whoId) checked=permission.documentAdd}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-edit-' permission.whoId) checked=permission.documentEdit}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-delete-' permission.whoId) checked=permission.documentDelete}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-move-' permission.whoId) checked=permission.documentMove}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-copy-' permission.whoId) checked=permission.documentCopy}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-template-' permission.whoId) checked=permission.documentTemplate}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-approve-' permission.whoId) checked=permission.documentApprove}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-lifecycle-' permission.whoId) checked=permission.documentLifecycle}}</td>
|
||||
<td>{{input type="checkbox" id=(concat 'doc-role-version-' permission.whoId) checked=permission.documentVersion}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
|
@ -108,13 +92,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-success" onclick={{action 'setPermissions'}}>Save</button>
|
||||
<button type="button" class="btn btn-success" onclick= {{action 'setPermissions'}}>Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "documize",
|
||||
"version": "1.58.0",
|
||||
"version": "1.59.0",
|
||||
"description": "The Document IDE",
|
||||
"private": true,
|
||||
"repository": "",
|
||||
|
|
16
meta.json
16
meta.json
|
@ -1,16 +1,14 @@
|
|||
{
|
||||
"community":
|
||||
{
|
||||
"version": "1.58.0",
|
||||
"community": {
|
||||
"version": "1.59.0",
|
||||
"major": 1,
|
||||
"minor": 58,
|
||||
"minor": 59,
|
||||
"patch": 0
|
||||
},
|
||||
"enterprise":
|
||||
{
|
||||
"version": "1.60.0",
|
||||
"enterprise": {
|
||||
"version": "1.61.0",
|
||||
"major": 1,
|
||||
"minor": 60,
|
||||
"minor": 61,
|
||||
"patch": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,18 +22,23 @@ import (
|
|||
// Document represents the purpose of Documize.
|
||||
type Document struct {
|
||||
model.BaseEntity
|
||||
OrgID string `json:"orgId"`
|
||||
LabelID string `json:"folderId"`
|
||||
UserID string `json:"userId"`
|
||||
Job string `json:"job"`
|
||||
Location string `json:"location"`
|
||||
Title string `json:"name"`
|
||||
Excerpt string `json:"excerpt"`
|
||||
Slug string `json:"-"`
|
||||
Tags string `json:"tags"`
|
||||
Template bool `json:"template"`
|
||||
Protection workflow.Protection `json:"protection"`
|
||||
Approval workflow.Approval `json:"approval"`
|
||||
OrgID string `json:"orgId"`
|
||||
LabelID string `json:"folderId"`
|
||||
UserID string `json:"userId"`
|
||||
Job string `json:"job"`
|
||||
Location string `json:"location"`
|
||||
Title string `json:"name"`
|
||||
Excerpt string `json:"excerpt"`
|
||||
Slug string `json:"-"`
|
||||
Tags string `json:"tags"`
|
||||
Template bool `json:"template"`
|
||||
Protection workflow.Protection `json:"protection"`
|
||||
Approval workflow.Approval `json:"approval"`
|
||||
Lifecycle workflow.Lifecycle `json:"lifecycle"`
|
||||
Versioned bool `json:"versioned"`
|
||||
VersionID string `json:"versionId"`
|
||||
VersionOrder int `json:"versionOrder"`
|
||||
GroupID string `json:"groupId"`
|
||||
}
|
||||
|
||||
// SetDefaults ensures on blanks and cleans.
|
||||
|
|
|
@ -93,6 +93,12 @@ const (
|
|||
// DocumentApprove means you can approve a change to a document
|
||||
DocumentApprove Action = "doc-approve"
|
||||
|
||||
// DocumentLifecycle means you can move a document between DRAFT/LIVE/ARCHIVE states
|
||||
DocumentLifecycle Action = "doc-lifecycle"
|
||||
|
||||
// DocumentVersion means you can manage document versions
|
||||
DocumentVersion Action = "doc-version"
|
||||
|
||||
// CategoryView action means you can view a category and documents therein
|
||||
CategoryView Action = "view"
|
||||
)
|
||||
|
|
|
@ -15,21 +15,23 @@ package permission
|
|||
// This data structure is made from database permission records for the space,
|
||||
// and it is designed to be sent to HTTP clients (web, mobile).
|
||||
type Record struct {
|
||||
OrgID string `json:"orgId"`
|
||||
SpaceID string `json:"folderId"`
|
||||
WhoID string `json:"whoId"`
|
||||
Who WhoType `json:"who"`
|
||||
SpaceView bool `json:"spaceView"`
|
||||
SpaceManage bool `json:"spaceManage"`
|
||||
SpaceOwner bool `json:"spaceOwner"`
|
||||
DocumentAdd bool `json:"documentAdd"`
|
||||
DocumentEdit bool `json:"documentEdit"`
|
||||
DocumentDelete bool `json:"documentDelete"`
|
||||
DocumentMove bool `json:"documentMove"`
|
||||
DocumentCopy bool `json:"documentCopy"`
|
||||
DocumentTemplate bool `json:"documentTemplate"`
|
||||
DocumentApprove bool `json:"documentApprove"`
|
||||
Name string `json:"name"` // read-only, user or group name
|
||||
OrgID string `json:"orgId"`
|
||||
SpaceID string `json:"folderId"`
|
||||
WhoID string `json:"whoId"`
|
||||
Who WhoType `json:"who"`
|
||||
SpaceView bool `json:"spaceView"`
|
||||
SpaceManage bool `json:"spaceManage"`
|
||||
SpaceOwner bool `json:"spaceOwner"`
|
||||
DocumentAdd bool `json:"documentAdd"`
|
||||
DocumentEdit bool `json:"documentEdit"`
|
||||
DocumentDelete bool `json:"documentDelete"`
|
||||
DocumentMove bool `json:"documentMove"`
|
||||
DocumentCopy bool `json:"documentCopy"`
|
||||
DocumentTemplate bool `json:"documentTemplate"`
|
||||
DocumentApprove bool `json:"documentApprove"`
|
||||
DocumentLifecycle bool `json:"documentLifecycle"`
|
||||
DocumentVersion bool `json:"documentVersion"`
|
||||
Name string `json:"name"` // read-only, user or group name
|
||||
}
|
||||
|
||||
// DecodeUserPermissions returns a flat, usable permission summary record
|
||||
|
@ -67,6 +69,10 @@ func DecodeUserPermissions(perm []Permission) (r Record) {
|
|||
r.DocumentTemplate = true
|
||||
case DocumentApprove:
|
||||
r.DocumentApprove = true
|
||||
case DocumentLifecycle:
|
||||
r.DocumentLifecycle = true
|
||||
case DocumentVersion:
|
||||
r.DocumentVersion = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +113,12 @@ func EncodeUserPermissions(r Record) (perm []Permission) {
|
|||
if r.DocumentApprove {
|
||||
perm = append(perm, EncodeRecord(r, DocumentApprove))
|
||||
}
|
||||
if r.DocumentVersion {
|
||||
perm = append(perm, EncodeRecord(r, DocumentVersion))
|
||||
}
|
||||
if r.DocumentLifecycle {
|
||||
perm = append(perm, EncodeRecord(r, DocumentLifecycle))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -114,7 +126,8 @@ func EncodeUserPermissions(r Record) (perm []Permission) {
|
|||
// HasAnyPermission returns true if user has at least one permission.
|
||||
func HasAnyPermission(p Record) bool {
|
||||
return p.SpaceView || p.SpaceManage || p.SpaceOwner || p.DocumentAdd || p.DocumentEdit ||
|
||||
p.DocumentDelete || p.DocumentMove || p.DocumentCopy || p.DocumentTemplate || p.DocumentApprove
|
||||
p.DocumentDelete || p.DocumentMove || p.DocumentCopy || p.DocumentTemplate || p.DocumentApprove ||
|
||||
p.DocumentLifecycle || p.DocumentVersion
|
||||
}
|
||||
|
||||
// EncodeRecord creates standard permission record representing user permissions for a space.
|
||||
|
@ -138,7 +151,6 @@ type CategoryViewRequestModel struct {
|
|||
CategoryID string `json:"categoryID"`
|
||||
WhoID string `json:"whoId"`
|
||||
Who WhoType `json:"who"`
|
||||
// UserID string `json:"userId"`
|
||||
}
|
||||
|
||||
// SpaceRequestModel details which users have what permissions on a given space.
|
||||
|
|
|
@ -63,3 +63,17 @@ const (
|
|||
// ChangePendingNew means a new section to a document is pending review
|
||||
ChangePendingNew ChangeStatus = 4
|
||||
)
|
||||
|
||||
// Lifecycle tells us if document is in Draft, Live, Archived
|
||||
type Lifecycle int
|
||||
|
||||
const (
|
||||
// LifecycleDraft means document is in draft mode with restricted viewing
|
||||
LifecycleDraft Lifecycle = 0
|
||||
|
||||
// LifecycleLive means document can be seen by all
|
||||
LifecycleLive Lifecycle = 1
|
||||
|
||||
// LifecycleArchived means document has been archived
|
||||
LifecycleArchived Lifecycle = 2
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue