mirror of
https://github.com/documize/community.git
synced 2025-07-20 05:39:42 +02:00
using all new permissions for securing spaces and documents
WIP
This commit is contained in:
parent
ef285c91de
commit
300b617583
51 changed files with 517 additions and 868 deletions
|
@ -135,24 +135,24 @@ func (h *Handler) DocumentLinks(w http.ResponseWriter, r *http.Request) {
|
||||||
response.WriteJSON(w, l)
|
response.WriteJSON(w, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BySpace is an endpoint that returns the documents in a given folder.
|
// BySpace is an endpoint that returns the documents for given space.
|
||||||
func (h *Handler) BySpace(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) BySpace(w http.ResponseWriter, r *http.Request) {
|
||||||
method := "document.space"
|
method := "document.space"
|
||||||
ctx := domain.GetRequestContext(r)
|
ctx := domain.GetRequestContext(r)
|
||||||
|
|
||||||
folderID := request.Query(r, "folder")
|
spaceID := request.Query(r, "space")
|
||||||
|
|
||||||
if len(folderID) == 0 {
|
if len(spaceID) == 0 {
|
||||||
response.WriteMissingDataError(w, method, "folder")
|
response.WriteMissingDataError(w, method, "space")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !space.CanViewSpace(ctx, *h.Store, folderID) {
|
if !space.CanViewSpace(ctx, *h.Store, spaceID) {
|
||||||
response.WriteForbiddenError(w)
|
response.WriteForbiddenError(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
documents, err := h.Store.Document.GetBySpace(ctx, folderID)
|
documents, err := h.Store.Document.GetBySpace(ctx, spaceID)
|
||||||
|
|
||||||
if len(documents) == 0 {
|
if len(documents) == 0 {
|
||||||
documents = []doc.Document{}
|
documents = []doc.Document{}
|
||||||
|
|
|
@ -134,20 +134,19 @@ func (s Scope) GetBySpace(ctx domain.RequestContext, folderID string) (documents
|
||||||
func (s Scope) GetByTag(ctx domain.RequestContext, tag string) (documents []doc.Document, err error) {
|
func (s Scope) GetByTag(ctx domain.RequestContext, tag string) (documents []doc.Document, err error) {
|
||||||
tagQuery := "tags LIKE '%#" + tag + "#%'"
|
tagQuery := "tags LIKE '%#" + tag + "#%'"
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&documents,
|
err = s.Runtime.Db.Select(&documents, `
|
||||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND template=0 AND `+tagQuery+` AND labelid IN
|
SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND template=0 AND `+tagQuery+`
|
||||||
(SELECT refid from label WHERE orgid=? AND type=2 AND userid=?
|
AND labelid IN
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=1 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=3 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY title`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
ctx.OrgID,
|
UNION ALL
|
||||||
ctx.UserID,
|
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=?
|
||||||
ctx.OrgID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY title
|
||||||
ctx.OrgID,
|
`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "select documents by tag")
|
err = errors.Wrap(err, "select documents by tag")
|
||||||
|
@ -160,19 +159,17 @@ func (s Scope) GetByTag(ctx domain.RequestContext, tag string) (documents []doc.
|
||||||
// Templates returns a slice containing the documents available as templates to the client's organisation, in title order.
|
// 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) {
|
func (s Scope) Templates(ctx domain.RequestContext) (documents []doc.Document, err error) {
|
||||||
err = s.Runtime.Db.Select(&documents,
|
err = s.Runtime.Db.Select(&documents,
|
||||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND template=1 AND labelid IN
|
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND template=1
|
||||||
(SELECT refid from label WHERE orgid=? AND type=2 AND userid=?
|
AND labelid IN
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=1 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=3 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY title`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
ctx.OrgID,
|
UNION ALL
|
||||||
ctx.UserID,
|
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=?
|
||||||
ctx.OrgID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY title`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "select document templates")
|
err = errors.Wrap(err, "select document templates")
|
||||||
|
@ -185,20 +182,17 @@ func (s Scope) Templates(ctx domain.RequestContext) (documents []doc.Document, e
|
||||||
// TemplatesBySpace returns a slice containing the documents available as templates for given space.
|
// 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) {
|
func (s Scope) TemplatesBySpace(ctx domain.RequestContext, spaceID string) (documents []doc.Document, err error) {
|
||||||
err = s.Runtime.Db.Select(&documents,
|
err = s.Runtime.Db.Select(&documents,
|
||||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND labelid=? AND template=1 AND labelid IN
|
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND labelid=? AND template=1
|
||||||
(SELECT refid from label WHERE orgid=? AND type=2 AND userid=?
|
AND labelid IN
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=1 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=3 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY title`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
spaceID,
|
UNION ALL
|
||||||
ctx.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.action='view' AND r.userid=?
|
||||||
ctx.UserID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY title`, ctx.OrgID, spaceID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.OrgID,
|
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
err = nil
|
err = nil
|
||||||
|
@ -233,19 +227,17 @@ 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.
|
// 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) {
|
func (s Scope) DocumentList(ctx domain.RequestContext) (documents []doc.Document, err error) {
|
||||||
err = s.Runtime.Db.Select(&documents,
|
err = s.Runtime.Db.Select(&documents,
|
||||||
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND template=0 AND labelid IN
|
`SELECT id, refid, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, layout, created, revised FROM document WHERE orgid=? AND template=0
|
||||||
(SELECT refid from label WHERE orgid=? AND type=2 AND userid=?
|
AND labelid IN
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=1 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=3 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY title`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
ctx.OrgID,
|
UNION ALL
|
||||||
ctx.UserID,
|
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=?
|
||||||
ctx.OrgID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY title`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
|
@ -169,21 +169,19 @@ func (s Scope) SearchCandidates(ctx domain.RequestContext, keywords string) (doc
|
||||||
keywords = strings.TrimSpace(strings.ToLower(keywords))
|
keywords = strings.TrimSpace(strings.ToLower(keywords))
|
||||||
likeQuery := "LOWER(title) LIKE '%" + keywords + "%'"
|
likeQuery := "LOWER(title) LIKE '%" + keywords + "%'"
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&temp,
|
err = s.Runtime.Db.Select(&temp, `
|
||||||
`SELECT d.refid as documentid, d. labelid as folderid, d.title, l.label as context
|
SELECT d.refid as documentid, d. labelid as folderid, d.title, l.label as context
|
||||||
FROM document d LEFT JOIN label l ON d.labelid=l.refid WHERE l.orgid=? AND `+likeQuery+` AND d.labelid IN
|
FROM document d LEFT JOIN label l ON d.labelid=l.refid WHERE l.orgid=? AND `+likeQuery+`
|
||||||
(SELECT refid FROM label WHERE orgid=? AND type=2 AND userid=?
|
AND d.labelid IN
|
||||||
UNION ALL SELECT refid FROM label a WHERE orgid=? AND type=1 AND refid IN (SELECT labelid FROM labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a WHERE orgid=? AND type=3 AND refid IN (SELECT labelid FROM labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY title`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
ctx.OrgID,
|
UNION ALL
|
||||||
ctx.UserID,
|
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=?
|
||||||
ctx.OrgID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY title`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "execute search links 1")
|
err = errors.Wrap(err, "execute search links 1")
|
||||||
|
@ -210,19 +208,17 @@ func (s Scope) SearchCandidates(ctx domain.RequestContext, keywords string) (doc
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&temp,
|
err = s.Runtime.Db.Select(&temp,
|
||||||
`SELECT p.refid as targetid, p.documentid as documentid, p.title as title, p.pagetype as linktype, d.title as context, d.labelid as folderid
|
`SELECT p.refid as targetid, p.documentid as documentid, p.title as title, p.pagetype as linktype, d.title as context, d.labelid as folderid
|
||||||
FROM page p LEFT JOIN document d ON d.refid=p.documentid WHERE p.orgid=? AND `+likeQuery+` AND d.labelid IN
|
FROM page p LEFT JOIN document d ON d.refid=p.documentid WHERE p.orgid=? AND `+likeQuery+`
|
||||||
(SELECT refid FROM label WHERE orgid=? AND type=2 AND userid=?
|
AND d.labelid IN
|
||||||
UNION ALL SELECT refid FROM label a WHERE orgid=? AND type=1 AND refid IN (SELECT labelid FROM labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a WHERE orgid=? AND type=3 AND refid IN (SELECT labelid FROM labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY p.title`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
ctx.OrgID,
|
UNION ALL
|
||||||
ctx.UserID,
|
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=?
|
||||||
ctx.OrgID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY p.title`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "execute search links 2")
|
err = errors.Wrap(err, "execute search links 2")
|
||||||
|
@ -249,19 +245,17 @@ func (s Scope) SearchCandidates(ctx domain.RequestContext, keywords string) (doc
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&temp,
|
err = s.Runtime.Db.Select(&temp,
|
||||||
`SELECT a.refid as targetid, a.documentid as documentid, a.filename as title, a.extension as context, d.labelid as folderid
|
`SELECT a.refid as targetid, a.documentid as documentid, a.filename as title, a.extension as context, d.labelid as folderid
|
||||||
FROM attachment a LEFT JOIN document d ON d.refid=a.documentid WHERE a.orgid=? AND `+likeQuery+` AND d.labelid IN
|
FROM attachment a LEFT JOIN document d ON d.refid=a.documentid WHERE a.orgid=? AND `+likeQuery+`
|
||||||
(SELECT refid FROM label WHERE orgid=? AND type=2 AND userid=?
|
AND d.labelid IN
|
||||||
UNION ALL SELECT refid FROM label a WHERE orgid=? AND type=1 AND refid IN (SELECT labelid FROM labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a WHERE orgid=? AND type=3 AND refid IN (SELECT labelid FROM labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
ORDER BY a.filename`,
|
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
|
||||||
ctx.OrgID,
|
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space'
|
||||||
ctx.OrgID,
|
UNION ALL
|
||||||
ctx.UserID,
|
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=?
|
||||||
ctx.OrgID,
|
))
|
||||||
ctx.OrgID,
|
)
|
||||||
ctx.OrgID,
|
ORDER BY a.filename`, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.OrgID, ctx.UserID, ctx.OrgID, ctx.UserID)
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "execute search links 3")
|
err = errors.Wrap(err, "execute search links 3")
|
||||||
|
|
|
@ -265,21 +265,26 @@ func (s Scope) matchFullText(ctx domain.RequestContext, keywords, itemType strin
|
||||||
AND s.itemtype = ?
|
AND s.itemtype = ?
|
||||||
AND s.documentid = d.refid
|
AND s.documentid = d.refid
|
||||||
-- AND d.template = 0
|
-- AND d.template = 0
|
||||||
AND d.labelid IN (SELECT refid from label WHERE orgid=? AND type=2 AND userid=?
|
AND d.labelid IN
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=1 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=3 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
SELECT refid FROM label WHERE orgid=?
|
||||||
AND MATCH(s.content) AGAINST(? IN BOOLEAN MODE)`
|
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=? AND location='space'
|
||||||
|
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=?
|
||||||
|
))
|
||||||
|
)
|
||||||
|
AND MATCH(s.content) AGAINST(? IN BOOLEAN MODE)`
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&r,
|
err = s.Runtime.Db.Select(&r,
|
||||||
sql1,
|
sql1,
|
||||||
ctx.OrgID,
|
ctx.OrgID,
|
||||||
itemType,
|
itemType,
|
||||||
ctx.OrgID,
|
ctx.OrgID,
|
||||||
|
ctx.OrgID,
|
||||||
|
ctx.OrgID,
|
||||||
ctx.UserID,
|
ctx.UserID,
|
||||||
ctx.OrgID,
|
ctx.OrgID,
|
||||||
ctx.OrgID,
|
|
||||||
ctx.OrgID,
|
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID,
|
ctx.UserID,
|
||||||
keywords)
|
keywords)
|
||||||
|
|
||||||
|
@ -318,9 +323,15 @@ func (s Scope) matchLike(ctx domain.RequestContext, keywords, itemType string) (
|
||||||
AND s.itemtype = ?
|
AND s.itemtype = ?
|
||||||
AND s.documentid = d.refid
|
AND s.documentid = d.refid
|
||||||
-- AND d.template = 0
|
-- AND d.template = 0
|
||||||
AND d.labelid IN (SELECT refid from label WHERE orgid=? AND type=2 AND userid=?
|
AND d.labelid IN
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=1 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1))
|
(
|
||||||
UNION ALL SELECT refid FROM label a where orgid=? AND type=3 AND refid IN (SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
|
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=? AND location='space'
|
||||||
|
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=?
|
||||||
|
))
|
||||||
|
)
|
||||||
AND s.content LIKE ?`
|
AND s.content LIKE ?`
|
||||||
|
|
||||||
err = s.Runtime.Db.Select(&r,
|
err = s.Runtime.Db.Select(&r,
|
||||||
|
@ -328,11 +339,10 @@ func (s Scope) matchLike(ctx domain.RequestContext, keywords, itemType string) (
|
||||||
ctx.OrgID,
|
ctx.OrgID,
|
||||||
itemType,
|
itemType,
|
||||||
ctx.OrgID,
|
ctx.OrgID,
|
||||||
|
ctx.OrgID,
|
||||||
|
ctx.OrgID,
|
||||||
ctx.UserID,
|
ctx.UserID,
|
||||||
ctx.OrgID,
|
ctx.OrgID,
|
||||||
ctx.OrgID,
|
|
||||||
ctx.OrgID,
|
|
||||||
ctx.OrgID,
|
|
||||||
ctx.UserID,
|
ctx.UserID,
|
||||||
keywords)
|
keywords)
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ type UserStorer interface {
|
||||||
GetBySerial(ctx RequestContext, serial string) (u user.User, err error)
|
GetBySerial(ctx RequestContext, serial string) (u user.User, err error)
|
||||||
GetActiveUsersForOrganization(ctx RequestContext) (u []user.User, err error)
|
GetActiveUsersForOrganization(ctx RequestContext) (u []user.User, err error)
|
||||||
GetUsersForOrganization(ctx RequestContext) (u []user.User, err error)
|
GetUsersForOrganization(ctx RequestContext) (u []user.User, err error)
|
||||||
GetSpaceUsers(ctx RequestContext, folderID string) (u []user.User, err error)
|
GetSpaceUsers(ctx RequestContext, spaceID string) (u []user.User, err error)
|
||||||
GetVisibleUsers(ctx RequestContext) (u []user.User, err error)
|
GetVisibleUsers(ctx RequestContext) (u []user.User, err error)
|
||||||
UpdateUser(ctx RequestContext, u user.User) (err error)
|
UpdateUser(ctx RequestContext, u user.User) (err error)
|
||||||
UpdateUserPassword(ctx RequestContext, userID, salt, password string) (err error)
|
UpdateUserPassword(ctx RequestContext, userID, salt, password string) (err error)
|
||||||
|
|
|
@ -184,14 +184,16 @@ func (s Scope) GetUsersForOrganization(ctx domain.RequestContext) (u []user.User
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSpaceUsers returns a slice containing all user records for given folder.
|
// GetSpaceUsers returns a slice containing all user records for given folder.
|
||||||
func (s Scope) GetSpaceUsers(ctx domain.RequestContext, folderID string) (u []user.User, err error) {
|
func (s Scope) GetSpaceUsers(ctx domain.RequestContext, spaceID string) (u []user.User, err error) {
|
||||||
err = s.Runtime.Db.Select(&u,
|
err = s.Runtime.Db.Select(&u, `
|
||||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised
|
SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised
|
||||||
FROM user u, account a
|
FROM user u, account a
|
||||||
WHERE u.refid IN (SELECT userid from labelrole WHERE orgid=? AND labelid=?)
|
WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN (
|
||||||
AND a.orgid=? AND u.refid = a.userid AND a.active=1
|
SELECT whoid from permission WHERE orgid=? AND who='user' AND scope='object' AND location='space' AND refid=? UNION ALL
|
||||||
ORDER BY u.firstname, u.lastname`,
|
SELECT r.userid from rolemember r LEFT JOIN permission p ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' AND p.scope='object' AND p.location='space' AND p.refid=?
|
||||||
ctx.OrgID, folderID, ctx.OrgID)
|
)
|
||||||
|
ORDER BY u.firstname, u.lastname;
|
||||||
|
`, ctx.OrgID, ctx.OrgID, spaceID, ctx.OrgID, spaceID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, fmt.Sprintf("get space users for org %s", ctx.OrgID))
|
err = errors.Wrap(err, fmt.Sprintf("get space users for org %s", ctx.OrgID))
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('meta', meta);
|
this.set('meta', meta);
|
||||||
if (this.get('toEdit') === this.get('page.id') && this.get('isEditor')) {
|
if (this.get('toEdit') === this.get('page.id') && this.get('permissions.documentEdit')) {
|
||||||
this.send('onEdit');
|
this.send('onEdit');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -72,6 +72,13 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
return `move-dialog-${id}`;
|
return `move-dialog-${id}`;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
hasMenuPermissions: computed('permissions', function() {
|
||||||
|
let permissions = this.get('permissions');
|
||||||
|
|
||||||
|
return permissions.get('documentDelete') || permissions.get('documentCopy') ||
|
||||||
|
permissions.get('documentMove') || permissions.get('documentTemplate');;
|
||||||
|
}),
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
$("#" + this.get('blockTitleId')).removeClass('error');
|
$("#" + this.get('blockTitleId')).removeClass('error');
|
||||||
$("#" + this.get('blockExcerptId')).removeClass('error');
|
$("#" + this.get('blockExcerptId')).removeClass('error');
|
||||||
|
@ -131,7 +138,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.attrs.onSavePageAsBlock(block);
|
this.attrs.onSavePageAsBlock(block);
|
||||||
|
|
||||||
this.set('menuOpen', false);
|
this.set('menuOpen', false);
|
||||||
this.set('blockTitle', '');
|
this.set('blockTitle', '');
|
||||||
this.set('blockExcerpt', '');
|
this.set('blockExcerpt', '');
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
didReceiveAttrs: function () {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.set('showToc', is.not.undefined(this.get('pages')) && this.get('pages').get('length') > 0);
|
this.set('showToc', is.not.undefined(this.get('pages')) && this.get('pages').get('length') > 0);
|
||||||
|
|
||||||
if (is.not.null(this.get('currentPageId'))) {
|
if (is.not.null(this.get('currentPageId'))) {
|
||||||
|
@ -42,7 +42,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
didRender: function () {
|
didRender: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
if (this.session.authenticated) {
|
if (this.session.authenticated) {
|
||||||
this.addTooltip(document.getElementById("toc-up-button"));
|
this.addTooltip(document.getElementById("toc-up-button"));
|
||||||
this.addTooltip(document.getElementById("toc-down-button"));
|
this.addTooltip(document.getElementById("toc-down-button"));
|
||||||
|
@ -53,13 +53,13 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded');
|
this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded');
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.eventBus.unsubscribe('documentPageAdded');
|
this.eventBus.unsubscribe('documentPageAdded');
|
||||||
this.destroyTooltips();
|
this.destroyTooltips();
|
||||||
},
|
},
|
||||||
|
@ -77,7 +77,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
let page = _.findWhere(toc, { id: pageId });
|
let page = _.findWhere(toc, { id: pageId });
|
||||||
let state = tocUtil.getState(toc, page);
|
let state = tocUtil.getState(toc, page);
|
||||||
|
|
||||||
if (!this.get('isEditor') || is.empty(pageId)) {
|
if (!this.get('permissions.documentEdit') || is.empty(pageId)) {
|
||||||
state.actionablePage = false;
|
state.actionablePage = false;
|
||||||
state.upDisabled = state.downDisabled = state.indentDisabled = state.outdentDisabled = true;
|
state.upDisabled = state.downDisabled = state.indentDisabled = state.outdentDisabled = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,13 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
return `move-dialog-${id}`;
|
return `move-dialog-${id}`;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
hasMenuPermissions: computed('permissions', function() {
|
||||||
|
let permissions = this.get('permissions');
|
||||||
|
|
||||||
|
return permissions.get('documentDelete') || permissions.get('documentCopy') ||
|
||||||
|
permissions.get('documentMove') || permissions.get('documentTemplate');;
|
||||||
|
}),
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
$("#" + this.get('blockTitleId')).removeClass('error');
|
$("#" + this.get('blockTitleId')).removeClass('error');
|
||||||
$("#" + this.get('blockExcerptId')).removeClass('error');
|
$("#" + this.get('blockExcerptId')).removeClass('error');
|
||||||
|
|
|
@ -14,7 +14,6 @@ import Ember from 'ember';
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
documentTags: [],
|
documentTags: [],
|
||||||
tagz: [],
|
tagz: [],
|
||||||
isEditor: false,
|
|
||||||
newTag: "",
|
newTag: "",
|
||||||
maxTags: 3,
|
maxTags: 3,
|
||||||
canAdd: false,
|
canAdd: false,
|
||||||
|
|
|
@ -14,22 +14,36 @@ import NotifierMixin from '../../mixins/notifier';
|
||||||
import TooltipMixin from '../../mixins/tooltip';
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
import AuthMixin from '../../mixins/auth';
|
import AuthMixin from '../../mixins/auth';
|
||||||
|
|
||||||
|
const {
|
||||||
|
inject: { service }
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
||||||
folderService: Ember.inject.service('folder'),
|
folderService: service('folder'),
|
||||||
session: Ember.inject.service(),
|
session: service(),
|
||||||
appMeta: Ember.inject.service(),
|
appMeta: service(),
|
||||||
|
pinned: service(),
|
||||||
showToolbar: false,
|
showToolbar: false,
|
||||||
folder: {},
|
folder: {},
|
||||||
busy: false,
|
busy: false,
|
||||||
moveFolderId: "",
|
moveFolderId: "",
|
||||||
drop: null,
|
drop: null,
|
||||||
|
pinState : {
|
||||||
|
isPinned: false,
|
||||||
|
pinId: '',
|
||||||
|
newName: '',
|
||||||
|
},
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
console.log(this.get('permissions'));
|
|
||||||
let targets = _.reject(this.get('folders'), {
|
let targets = _.reject(this.get('folders'), {
|
||||||
id: this.get('folder').get('id')
|
id: this.get('folder').get('id')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let folder = this.get('folder');
|
||||||
|
this.set('pinState.pinId', this.get('pinned').isSpacePinned(folder.get('id')));
|
||||||
|
this.set('pinState.isPinned', this.get('pinState.pinId') !== '');
|
||||||
|
this.set('pinState.newName', folder.get('name').substring(0,3).toUpperCase());
|
||||||
|
|
||||||
this.set('movedFolderOptions', targets);
|
this.set('movedFolderOptions', targets);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -61,6 +75,35 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
onUnpin() {
|
||||||
|
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
||||||
|
this.set('pinState.isPinned', false);
|
||||||
|
this.set('pinState.pinId', '');
|
||||||
|
this.eventBus.publish('pinChange');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onPin() {
|
||||||
|
let pin = {
|
||||||
|
pin: this.get('pinState.newName'),
|
||||||
|
documentId: '',
|
||||||
|
folderId: this.get('folder.id')
|
||||||
|
};
|
||||||
|
|
||||||
|
if (is.empty(pin.pin)) {
|
||||||
|
$('#pin-space-name').addClass('error').focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get('pinned').pinItem(pin).then((pin) => {
|
||||||
|
this.set('pinState.isPinned', true);
|
||||||
|
this.set('pinState.pinId', pin.get('id'));
|
||||||
|
this.eventBus.publish('pinChange');
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
deleteDocuments() {
|
deleteDocuments() {
|
||||||
this.attrs.onDeleteDocument();
|
this.attrs.onDeleteDocument();
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,28 +14,7 @@ import TooltipMixin from '../../mixins/tooltip';
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
import NotifierMixin from '../../mixins/notifier';
|
||||||
import AuthMixin from '../../mixins/auth';
|
import AuthMixin from '../../mixins/auth';
|
||||||
|
|
||||||
const {
|
|
||||||
inject: { service }
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
|
export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
|
||||||
folderService: service('folder'),
|
|
||||||
templateService: service('template'),
|
|
||||||
appMeta: service(),
|
|
||||||
pinned: service(),
|
|
||||||
publicFolders: [],
|
|
||||||
protectedFolders: [],
|
|
||||||
privateFolders: [],
|
|
||||||
hasPublicFolders: false,
|
|
||||||
hasProtectedFolders: false,
|
|
||||||
hasPrivateFolders: false,
|
|
||||||
newFolder: "",
|
|
||||||
menuOpen: false,
|
|
||||||
pinState : {
|
|
||||||
isPinned: false,
|
|
||||||
pinId: '',
|
|
||||||
newName: '',
|
|
||||||
},
|
|
||||||
tab: '',
|
tab: '',
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -46,15 +25,6 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
didReceiveAttrs() {
|
|
||||||
if (!this.get('noFolder')) {
|
|
||||||
let folder = this.get('folder');
|
|
||||||
this.set('pinState.pinId', this.get('pinned').isSpacePinned(folder.get('id')));
|
|
||||||
this.set('pinState.isPinned', this.get('pinState.pinId') !== '');
|
|
||||||
this.set('pinState.newName', folder.get('name').substring(0,3).toUpperCase());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onAddSpace(m) {
|
onAddSpace(m) {
|
||||||
this.attrs.onAddSpace(m);
|
this.attrs.onAddSpace(m);
|
||||||
|
@ -64,38 +34,5 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
|
||||||
onChangeTab(tab) {
|
onChangeTab(tab) {
|
||||||
this.set('tab', tab);
|
this.set('tab', tab);
|
||||||
},
|
},
|
||||||
|
|
||||||
onMenuOpen() {
|
|
||||||
this.set('menuOpen', !this.get('menuOpen'));
|
|
||||||
},
|
|
||||||
|
|
||||||
onUnpin() {
|
|
||||||
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
|
||||||
this.set('pinState.isPinned', false);
|
|
||||||
this.set('pinState.pinId', '');
|
|
||||||
this.eventBus.publish('pinChange');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onPin() {
|
|
||||||
let pin = {
|
|
||||||
pin: this.get('pinState.newName'),
|
|
||||||
documentId: '',
|
|
||||||
folderId: this.get('folder.id')
|
|
||||||
};
|
|
||||||
|
|
||||||
if (is.empty(pin.pin)) {
|
|
||||||
$('#pin-space-name').addClass('error').focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.get('pinned').pinItem(pin).then((pin) => {
|
|
||||||
this.set('pinState.isPinned', true);
|
|
||||||
this.set('pinState.pinId', pin.get('id'));
|
|
||||||
this.eventBus.publish('pinChange');
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
//
|
//
|
||||||
// This software (Documize Community Edition) is licensed under
|
// This software (Documize Community Edition) is licensed under
|
||||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
//
|
//
|
||||||
// You can operate outside the AGPL restrictions by purchasing
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
// Documize Enterprise Edition and obtaining a commercial license
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
// by contacting <sales@documize.com>.
|
// by contacting <sales@documize.com>.
|
||||||
//
|
//
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
|
@ -18,4 +18,4 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
this.transitionTo('customize.general');
|
this.transitionTo('customize.general');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
{{layout/zone-navigation}}
|
{{layout/zone-navigation}}
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
<div class="sidebar-toolbar">
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-common">
|
<div class="sidebar-common">
|
||||||
{{layout/sidebar-intro title='Settings' message='Documize application settings'}}
|
{{layout/sidebar-intro title='Settings' message='Documize application settings'}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
{{document/document-heading document=model.document isEditor=false}}
|
{{document/document-heading document=model.document}}
|
||||||
{{document/block-editor document=model.document folder=model.folder block=model.block onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
{{document/block-editor document=model.document folder=model.folder block=model.block onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
{{document/document-heading document=model.document isEditor=false}}
|
{{document/document-heading document=model.document}}
|
||||||
{{#if hasRevisions}}
|
{{#if hasRevisions}}
|
||||||
{{document/document-history document=model.document folder=model.folder pages=model.pages
|
{{document/document-history document=model.document folder=model.folder pages=model.pages
|
||||||
revisions=model.revisions diff=model.diff onFetchDiff=(action 'onFetchDiff') onRollback=(action 'onRollback')}}
|
revisions=model.revisions diff=model.diff onFetchDiff=(action 'onFetchDiff') onRollback=(action 'onRollback')}}
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
pages: this.get('documentService').getPages(this.modelFor('document').document.get('id')),
|
pages: this.get('documentService').getPages(this.modelFor('document').document.get('id')),
|
||||||
links: this.modelFor('document').links,
|
links: this.modelFor('document').links,
|
||||||
sections: this.modelFor('document').sections,
|
sections: this.modelFor('document').sections,
|
||||||
permissions: this.get('folderService').get('permissions')
|
permissions: this.modelFor('document').permissions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,6 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folder: this.modelFor('folder').folder,
|
folder: this.modelFor('folder').folder,
|
||||||
isEditor: this.modelFor('folder').isEditor,
|
|
||||||
permissions: this.modelFor('folder').permissions,
|
permissions: this.modelFor('folder').permissions,
|
||||||
folders: this.modelFor('folder').folders,
|
folders: this.modelFor('folder').folders,
|
||||||
documents: this.modelFor('folder').documents,
|
documents: this.modelFor('folder').documents,
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
folder: this.get('folder'),
|
folder: this.get('folder'),
|
||||||
permissions: this.get('permissions'),
|
permissions: this.get('permissions'),
|
||||||
folders: this.get('folderService').getAll(),
|
folders: this.get('folderService').getAll(),
|
||||||
documents: this.get('documentService').getAllByFolder(params.folder_id),
|
documents: this.get('documentService').getAllBySpace(params.folder_id),
|
||||||
templates: this.get('templateService').getSavedTemplates(params.folder_id)
|
templates: this.get('templateService').getSavedTemplates(params.folder_id)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
15
gui/app/pods/folder/settings/invitation/controller.js
Normal file
15
gui/app/pods/folder/settings/invitation/controller.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
});
|
25
gui/app/pods/folder/settings/invitation/route.js
Normal file
25
gui/app/pods/folder/settings/invitation/route.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
import Ember from 'ember';
|
||||||
|
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||||
|
|
||||||
|
export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
model() {
|
||||||
|
this.get('browser').setTitle(this.modelFor('folder').folder.get('name'));
|
||||||
|
|
||||||
|
return Ember.RSVP.hash({
|
||||||
|
folder: this.modelFor('folder').folder,
|
||||||
|
permissions: this.modelFor('folder').permissions,
|
||||||
|
folders: this.modelFor('folder').folders
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
1
gui/app/pods/folder/settings/invitation/template.hbs
Normal file
1
gui/app/pods/folder/settings/invitation/template.hbs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{{folder/invite-user folders=model.folders folder=model.folder}}
|
|
@ -13,6 +13,12 @@ import Ember from 'ember';
|
||||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||||
|
|
||||||
export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
beforeModel: function (transition) {
|
||||||
|
if (is.equal(transition.targetName, 'folder.settings.index')) {
|
||||||
|
this.transitionTo('folder.settings.security');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
this.get('browser').setTitle(this.modelFor('folder').folder.get('name'));
|
this.get('browser').setTitle(this.modelFor('folder').folder.get('name'));
|
||||||
|
|
||||||
|
|
15
gui/app/pods/folder/settings/security/controller.js
Normal file
15
gui/app/pods/folder/settings/security/controller.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
});
|
25
gui/app/pods/folder/settings/security/route.js
Normal file
25
gui/app/pods/folder/settings/security/route.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
import Ember from 'ember';
|
||||||
|
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||||
|
|
||||||
|
export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
model() {
|
||||||
|
this.get('browser').setTitle(this.modelFor('folder').folder.get('name'));
|
||||||
|
|
||||||
|
return Ember.RSVP.hash({
|
||||||
|
folder: this.modelFor('folder').folder,
|
||||||
|
permissions: this.modelFor('folder').permissions,
|
||||||
|
folders: this.modelFor('folder').folders
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
1
gui/app/pods/folder/settings/security/template.hbs
Normal file
1
gui/app/pods/folder/settings/security/template.hbs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{{folder/permission-admin folders=model.folders folder=model.folder}}
|
|
@ -1,36 +1,33 @@
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
|
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
<div class="sidebar-toolbar"></div>
|
|
||||||
<div class="sidebar-common">
|
<div class="sidebar-common">
|
||||||
{{layout/sidebar-intro title="Space Settings" message="Invite users and configure space permissions. Set up categories to sub-divide the space."}}
|
{{layout/sidebar-intro title="Space Settings" message="Invite users, configure space permissions, and set up categories to sub-divide the space."}}
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-wrapper">
|
<div class="sidebar-wrapper">
|
||||||
<div class="sidebar-menu">
|
<div class="sidebar-menu">
|
||||||
<ul class="options">
|
<ul class="options">
|
||||||
<div class="option selected">Users</div>
|
{{#if isAuthProviderDocumize}}
|
||||||
<div class="option ">Categories</div>
|
{{#link-to 'folder.settings.invitation' activeClass='selected' class="option" tagName="li"}}Invite{{/link-to}}
|
||||||
|
{{/if}}
|
||||||
|
{{#link-to 'folder.settings.security' activeClass='selected' class="option" tagName="li"}}Secure{{/link-to}}
|
||||||
|
{{#link-to 'folder.settings.category' activeClass='selected' class="option" tagName="li"}}Organize{{/link-to}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/layout/zone-sidebar}}
|
{{/layout/zone-sidebar}}
|
||||||
|
|
||||||
{{#layout/zone-content}}
|
{{#layout/zone-content}}
|
||||||
<div class="folder-heading">
|
<div class="back-to-space">
|
||||||
<h1 class="folder-title">{{model.folder.name}}</h1>
|
{{#link-to 'folder' model.folder.id model.folder.slug}}
|
||||||
|
<div class="regular-button button-gray">
|
||||||
|
<i class="material-icons">arrow_back</i>
|
||||||
|
<div class="name">{{model.folder.name}}</div>
|
||||||
|
</div>
|
||||||
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
{{#link-to 'folder' model.folder.id model.folder.slug class="vertical-top"}}
|
|
||||||
<i class="material-icons">arrow_back</i> back to space
|
|
||||||
{{/link-to}}
|
|
||||||
<div class="margin-top-30" />
|
<div class="margin-top-30" />
|
||||||
|
|
||||||
{{#if isAuthProviderDocumize}}
|
{{outlet}}
|
||||||
{{folder/invite-user folders=model.folders folder=model.folder}}
|
|
||||||
<div class="margin-top-50" />
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{folder/permission-admin folders=model.folders folder=model.folder}}
|
|
||||||
<div class="margin-top-50" />
|
<div class="margin-top-50" />
|
||||||
{{/layout/zone-content}}
|
{{/layout/zone-content}}
|
||||||
|
|
||||||
{{/layout/zone-container}}
|
{{/layout/zone-container}}
|
|
@ -1,8 +1,7 @@
|
||||||
{{layout/zone-navigation}}
|
{{layout/zone-navigation}}
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
{{folder/sidebar-zone folders=model noFolder=true isFolderOwner=false isEditor=false
|
{{folder/sidebar-zone folders=model noFolder=true onAddSpace=(action 'onAddSpace')}}
|
||||||
onAddSpace=(action 'onAddSpace')}}
|
|
||||||
{{/layout/zone-sidebar}}
|
{{/layout/zone-sidebar}}
|
||||||
{{#layout/zone-content}}
|
{{#layout/zone-content}}
|
||||||
{{/layout/zone-content}}
|
{{/layout/zone-content}}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
{{layout/zone-navigation}}
|
{{layout/zone-navigation}}
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
<div class="sidebar-toolbar">
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-common">
|
<div class="sidebar-common">
|
||||||
{{layout/sidebar-intro title="Profile" message="Your user profile"}}
|
{{layout/sidebar-intro title="Profile" message="Your user profile"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
<div class="sidebar-toolbar">
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-common">
|
<div class="sidebar-common">
|
||||||
{{layout/sidebar-intro title="Search" message='Search across document name, contents, tags and attachment filenames'}}
|
{{layout/sidebar-intro title="Search" message='Search across document name, contents, tags and attachment filenames'}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -26,7 +26,17 @@ export default Router.map(function () {
|
||||||
}, function() {
|
}, function() {
|
||||||
this.route('settings', {
|
this.route('settings', {
|
||||||
path: 'settings'
|
path: 'settings'
|
||||||
});
|
}, function () {
|
||||||
|
this.route('security', {
|
||||||
|
path: 'security'
|
||||||
|
});
|
||||||
|
this.route('invitation', {
|
||||||
|
path: 'invitation'
|
||||||
|
});
|
||||||
|
this.route('category', {
|
||||||
|
path: 'category'
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('document', {
|
this.route('document', {
|
||||||
|
|
|
@ -33,9 +33,9 @@ export default Ember.Service.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns all documents for specified folder.
|
// Returns all documents for specified space.
|
||||||
getAllByFolder(folderId) {
|
getAllBySpace(spaceId) {
|
||||||
return this.get('ajax').request(`documents?folder=${folderId}`, {
|
return this.get('ajax').request(`documents?space=${spaceId}`, {
|
||||||
method: "GET"
|
method: "GET"
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
let documents = Ember.ArrayProxy.create({
|
let documents = Ember.ArrayProxy.create({
|
||||||
|
|
|
@ -1,411 +0,0 @@
|
||||||
**********************************
|
|
||||||
**********************************
|
|
||||||
***** document
|
|
||||||
**********************************
|
|
||||||
**********************************
|
|
||||||
|
|
||||||
{{layout/zone-navigation}}
|
|
||||||
|
|
||||||
{{#layout/zone-sidebar}}
|
|
||||||
{{document/document-sidebar document=model.document folder=model.folder pages=model.pages page=model.page isEditor=model.isEditor sections=model.sections
|
|
||||||
onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock') onDeleteBlock=(action 'onDeleteBlock') changePageSequence=(action 'onPageSequenceChange') changePageLevel=(action 'onPageLevelChange') gotoPage=(action 'gotoPage')}}
|
|
||||||
{{/layout/zone-sidebar}}
|
|
||||||
|
|
||||||
{{#layout/zone-content}}
|
|
||||||
{{document/document-toolbar document=model.document pages=model.pages tabs=model.tabs folder=model.folder isEditor=model.isEditor
|
|
||||||
onSaveTemplate=(action 'onSaveTemplate') onSaveMeta=(action 'onSaveMeta') onDocumentDelete=(action 'onDocumentDelete')}}
|
|
||||||
|
|
||||||
{{outlet}}
|
|
||||||
{{/layout/zone-content}}
|
|
||||||
|
|
||||||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software (Documize Community Edition) is licensed under
|
|
||||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
|
||||||
//
|
|
||||||
// You can operate outside the AGPL restrictions by purchasing
|
|
||||||
// Documize Enterprise Edition and obtaining a commercial license
|
|
||||||
// by contacting <sales@documize.com>.
|
|
||||||
//
|
|
||||||
// https://documize.com
|
|
||||||
|
|
||||||
import Ember from 'ember';
|
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
|
||||||
documentService: Ember.inject.service('document'),
|
|
||||||
templateService: Ember.inject.service('template'),
|
|
||||||
sectionService: Ember.inject.service('section'),
|
|
||||||
page: null,
|
|
||||||
folder: {},
|
|
||||||
pages: [],
|
|
||||||
|
|
||||||
// Jump to the right part of the document.
|
|
||||||
scrollToPage(pageId) {
|
|
||||||
Ember.run.schedule('afterRender', function () {
|
|
||||||
let dest;
|
|
||||||
let target = "#page-title-" + pageId;
|
|
||||||
let targetOffset = $(target).offset();
|
|
||||||
|
|
||||||
if (is.undefined(targetOffset)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest = targetOffset.top > $(document).height() - $(window).height() ? $(document).height() - $(window).height() : targetOffset.top;
|
|
||||||
// small correction to ensure we also show page title
|
|
||||||
dest = dest > 50 ? dest - 74 : dest;
|
|
||||||
|
|
||||||
$("html,body").animate({
|
|
||||||
scrollTop: dest
|
|
||||||
}, 500, "linear");
|
|
||||||
$(".toc-index-item").removeClass("selected");
|
|
||||||
$("#index-" + pageId).addClass("selected");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
gotoPage(pageId) {
|
|
||||||
if (is.null(pageId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.scrollToPage(pageId);
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageSequenceChange(changes) {
|
|
||||||
this.get('documentService').changePageSequence(this.get('model.document.id'), changes).then(() => {
|
|
||||||
_.each(changes, (change) => {
|
|
||||||
let pageContent = _.findWhere(this.get('model.pages'), {
|
|
||||||
id: change.pageId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (is.not.undefined(pageContent)) {
|
|
||||||
pageContent.set('sequence', change.sequence);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set('model.pages', this.get('model.pages').sortBy('sequence'));
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLevelChange(changes) {
|
|
||||||
this.get('documentService').changePageLevel(this.get('model.document.id'), changes).then(() => {
|
|
||||||
_.each(changes, (change) => {
|
|
||||||
let pageContent = _.findWhere(this.get('model.pages'), {
|
|
||||||
id: change.pageId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (is.not.undefined(pageContent)) {
|
|
||||||
pageContent.set('level', change.level);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let pages = this.get('model.pages');
|
|
||||||
pages = pages.sortBy('sequence');
|
|
||||||
this.set('model.pages', []);
|
|
||||||
this.set('model.pages', pages);
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onSaveTemplate(name, desc) {
|
|
||||||
this.get('templateService').saveAsTemplate(this.get('model.document.id'), name, desc).then(function () {});
|
|
||||||
},
|
|
||||||
|
|
||||||
onSaveMeta(doc) {
|
|
||||||
this.get('documentService').save(doc).then(() => {
|
|
||||||
this.transitionToRoute('document.index');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddSection(section) {
|
|
||||||
this.audit.record("added-section-" + section.get('contentType'));
|
|
||||||
|
|
||||||
let page = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
title: `${section.get('title')}`,
|
|
||||||
level: 1,
|
|
||||||
sequence: 0,
|
|
||||||
body: "",
|
|
||||||
contentType: section.get('contentType'),
|
|
||||||
pageType: section.get('pageType')
|
|
||||||
};
|
|
||||||
|
|
||||||
let meta = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
rawBody: "",
|
|
||||||
config: ""
|
|
||||||
};
|
|
||||||
|
|
||||||
let model = {
|
|
||||||
page: page,
|
|
||||||
meta: meta
|
|
||||||
};
|
|
||||||
|
|
||||||
this.get('documentService').addPage(this.get('model.document.id'), model).then((newPage) => {
|
|
||||||
let data = this.get('store').normalize('page', newPage);
|
|
||||||
this.get('store').push(data);
|
|
||||||
|
|
||||||
this.get('documentService').getPages(this.get('model.document.id')).then((pages) => {
|
|
||||||
this.set('model.pages', pages.filterBy('pageType', 'section'));
|
|
||||||
this.set('model.tabs', pages.filterBy('pageType', 'tab'));
|
|
||||||
|
|
||||||
this.get('documentService').getPageMeta(this.get('model.document.id'), newPage.id).then(() => {
|
|
||||||
this.transitionToRoute('document.edit',
|
|
||||||
this.get('model.folder.id'),
|
|
||||||
this.get('model.folder.slug'),
|
|
||||||
this.get('model.document.id'),
|
|
||||||
this.get('model.document.slug'),
|
|
||||||
newPage.id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onInsertBlock(block) {
|
|
||||||
this.audit.record("added-content-block-" + block.get('contentType'));
|
|
||||||
|
|
||||||
let page = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
title: `${block.get('title')}`,
|
|
||||||
level: 1,
|
|
||||||
sequence: 0,
|
|
||||||
body: block.get('body'),
|
|
||||||
contentType: block.get('contentType'),
|
|
||||||
pageType: block.get('pageType'),
|
|
||||||
blockId: block.get('id')
|
|
||||||
};
|
|
||||||
|
|
||||||
let meta = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
rawBody: block.get('rawBody'),
|
|
||||||
config: block.get('config'),
|
|
||||||
externalSource: block.get('externalSource')
|
|
||||||
};
|
|
||||||
|
|
||||||
let model = {
|
|
||||||
page: page,
|
|
||||||
meta: meta
|
|
||||||
};
|
|
||||||
|
|
||||||
this.get('documentService').addPage(this.get('model.document.id'), model).then((newPage) => {
|
|
||||||
let data = this.get('store').normalize('page', newPage);
|
|
||||||
this.get('store').push(data);
|
|
||||||
|
|
||||||
this.get('documentService').getPages(this.get('model.document.id')).then((pages) => {
|
|
||||||
this.set('model.pages', pages.filterBy('pageType', 'section'));
|
|
||||||
this.set('model.tabs', pages.filterBy('pageType', 'tab'));
|
|
||||||
|
|
||||||
this.get('documentService').getPageMeta(this.get('model.document.id'), newPage.id).then(() => {
|
|
||||||
this.transitionToRoute('document.edit',
|
|
||||||
this.get('model.folder.id'),
|
|
||||||
this.get('model.folder.slug'),
|
|
||||||
this.get('model.document.id'),
|
|
||||||
this.get('model.document.slug'),
|
|
||||||
newPage.id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onDeleteBlock(blockId) {
|
|
||||||
this.get('sectionService').deleteBlock(blockId).then(() => {
|
|
||||||
this.audit.record("deleted-block");
|
|
||||||
this.send("showNotification", "Deleted");
|
|
||||||
this.transitionToRoute('document.index');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onDocumentDelete() {
|
|
||||||
this.get('documentService').deleteDocument(this.get('model.document.id')).then(() => {
|
|
||||||
this.audit.record("deleted-page");
|
|
||||||
this.send("showNotification", "Deleted");
|
|
||||||
this.transitionToRoute('folder', this.get('model.folder.id'), this.get('model.folder.slug'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
**********************************
|
|
||||||
**********************************
|
|
||||||
***** document/index
|
|
||||||
**********************************
|
|
||||||
**********************************
|
|
||||||
|
|
||||||
{{document/document-view document=model.document links=model.links allPages=model.allPages tabs=model.tabs pages=model.pages folder=model.folder folders=model.folders isEditor=model.isEditor gotoPage=(action 'gotoPage') onAddBlock=(action 'onAddBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}}
|
|
||||||
|
|
||||||
|
|
||||||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software (Documize Community Edition) is licensed under
|
|
||||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
|
||||||
//
|
|
||||||
// You can operate outside the AGPL restrictions by purchasing
|
|
||||||
// Documize Enterprise Edition and obtaining a commercial license
|
|
||||||
// by contacting <sales@documize.com>.
|
|
||||||
//
|
|
||||||
// https://documize.com
|
|
||||||
|
|
||||||
import Ember from 'ember';
|
|
||||||
import NotifierMixin from '../../../mixins/notifier';
|
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
|
||||||
documentService: Ember.inject.service('document'),
|
|
||||||
sectionService: Ember.inject.service('section'),
|
|
||||||
queryParams: ['page'],
|
|
||||||
|
|
||||||
// Jump to the right part of the document.
|
|
||||||
scrollToPage(pageId) {
|
|
||||||
Ember.run.schedule('afterRender', function () {
|
|
||||||
let dest;
|
|
||||||
let target = "#page-title-" + pageId;
|
|
||||||
let targetOffset = $(target).offset();
|
|
||||||
|
|
||||||
if (is.undefined(targetOffset)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest = targetOffset.top > $(document).height() - $(window).height() ? $(document).height() - $(window).height() : targetOffset.top;
|
|
||||||
// small correction to ensure we also show page title
|
|
||||||
dest = dest > 50 ? dest - 74 : dest;
|
|
||||||
|
|
||||||
$("html,body").animate({
|
|
||||||
scrollTop: dest
|
|
||||||
}, 500, "linear");
|
|
||||||
$(".toc-index-item").removeClass("selected");
|
|
||||||
$("#index-" + pageId).addClass("selected");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
gotoPage(pageId) {
|
|
||||||
if (is.null(pageId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.scrollToPage(pageId);
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageSequenceChange(changes) {
|
|
||||||
this.get('documentService').changePageSequence(this.get('model.document.id'), changes).then(() => {
|
|
||||||
_.each(changes, (change) => {
|
|
||||||
let pageContent = _.findWhere(this.get('model.pages'), {
|
|
||||||
id: change.pageId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (is.not.undefined(pageContent)) {
|
|
||||||
pageContent.set('sequence', change.sequence);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set('model.pages', this.get('model.pages').sortBy('sequence'));
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLevelChange(changes) {
|
|
||||||
this.get('documentService').changePageLevel(this.get('model.document.id'), changes).then(() => {
|
|
||||||
_.each(changes, (change) => {
|
|
||||||
let pageContent = _.findWhere(this.get('model.pages'), {
|
|
||||||
id: change.pageId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (is.not.undefined(pageContent)) {
|
|
||||||
pageContent.set('level', change.level);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let pages = this.get('model.pages');
|
|
||||||
pages = pages.sortBy('sequence');
|
|
||||||
this.set('model.pages', pages);
|
|
||||||
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddBlock(block) {
|
|
||||||
this.get('sectionService').addBlock(block).then(() => {
|
|
||||||
this.showNotification("Published");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onCopyPage(pageId, targetDocumentId) {
|
|
||||||
let documentId = this.get('model.document.id');
|
|
||||||
this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => {
|
|
||||||
this.showNotification("Copied");
|
|
||||||
|
|
||||||
// refresh data if copied to same document
|
|
||||||
if (documentId === targetDocumentId) {
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onMovePage(pageId, targetDocumentId) {
|
|
||||||
let documentId = this.get('model.document.id');
|
|
||||||
|
|
||||||
this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => {
|
|
||||||
this.showNotification("Moved");
|
|
||||||
|
|
||||||
this.send('onPageDeleted', { id: pageId, children: false });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageDeleted(deletePage) {
|
|
||||||
let documentId = this.get('model.document.id');
|
|
||||||
let pages = this.get('model.pages');
|
|
||||||
let deleteId = deletePage.id;
|
|
||||||
let deleteChildren = deletePage.children;
|
|
||||||
let page = _.findWhere(pages, {
|
|
||||||
id: deleteId
|
|
||||||
});
|
|
||||||
let pageIndex = _.indexOf(pages, page, false);
|
|
||||||
let pendingChanges = [];
|
|
||||||
|
|
||||||
this.audit.record("deleted-page");
|
|
||||||
|
|
||||||
// select affected pages
|
|
||||||
for (var i = pageIndex + 1; i < pages.get('length'); i++) {
|
|
||||||
if (pages[i].get('level') <= page.get('level')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pendingChanges.push({
|
|
||||||
pageId: pages[i].get('id'),
|
|
||||||
level: pages[i].get('level') - 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleteChildren) {
|
|
||||||
// nuke of page tree
|
|
||||||
pendingChanges.push({
|
|
||||||
pageId: deleteId
|
|
||||||
});
|
|
||||||
|
|
||||||
this.get('documentService').deletePages(documentId, deleteId, pendingChanges).then(() => {
|
|
||||||
// update our models so we don't have to reload from db
|
|
||||||
for (var i = 0; i < pendingChanges.length; i++) {
|
|
||||||
let pageId = pendingChanges[i].pageId;
|
|
||||||
this.set('model.pages', _.reject(pages, function (p) { //jshint ignore: line
|
|
||||||
return p.get('id') === pageId;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.set('model.pages', _.sortBy(pages, "sequence"));
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// page delete followed by re-leveling child pages
|
|
||||||
this.get('documentService').deletePage(documentId, deleteId).then(() => {
|
|
||||||
this.set('model.pages', _.reject(pages, function (p) {
|
|
||||||
return p.get('id') === deleteId;
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.send('onPageLevelChange', pendingChanges);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -107,11 +107,10 @@ video.responsive-video {
|
||||||
html {
|
html {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
font-family: $font-regular;
|
font-family: $font-regular;
|
||||||
background-color: $color-off-white;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
text-shadow: 1px 1px 1px rgba(0,0,0,0.004);
|
text-shadow: 1px 1px 1px rgba(0,0,0,0.004);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,3 +13,16 @@
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.back-to-space {
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
> a {
|
||||||
|
> .regular-button {
|
||||||
|
> .name {
|
||||||
|
// max-width: 150px;
|
||||||
|
// @extend .truncate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
.zone-document-content {
|
.zone-document-content {
|
||||||
> .back-to-space {
|
|
||||||
margin: 10px 0;
|
|
||||||
|
|
||||||
> a {
|
|
||||||
> .regular-button {
|
|
||||||
> .name {
|
|
||||||
// max-width: 150px;
|
|
||||||
// @extend .truncate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.doc-title {
|
.doc-title {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
margin: 30px 0 10px;
|
margin: 30px 0 10px;
|
||||||
|
|
|
@ -14,16 +14,13 @@
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
|
|
||||||
> .permission-name-cell {
|
> .permission-name-cell {
|
||||||
padding: 10px 5px;
|
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
|
background-color: $color-off-white;
|
||||||
|
padding: 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .permission-roles-cell {
|
> .permission-roles-cell {
|
||||||
background-color: $color-off-white;
|
margin: 15px 0 20px 40px;
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 40px;
|
|
||||||
padding: 10px 10px;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
> .role-category {
|
> .role-category {
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
|
|
|
@ -10,6 +10,7 @@ $sidebar-width: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar-wrapper {
|
#sidebar-wrapper {
|
||||||
|
background-color: $color-off-white;
|
||||||
z-index: 888;
|
z-index: 888;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
@ -105,11 +106,11 @@ $sidebar-width: 400px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 340px;
|
width: 340px;
|
||||||
padding: 40px 20px 0px 20px;
|
padding: 40px 20px 0px 20px;
|
||||||
margin-left: 60px;
|
margin-left: 20px;
|
||||||
|
|
||||||
> .pinner {
|
> .pinner {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
> .material-icons {
|
> .material-icons {
|
||||||
color: $color-primary;
|
color: $color-primary;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,7 @@ $sidebar-width: 400px;
|
||||||
|
|
||||||
.sidebar-wrapper {
|
.sidebar-wrapper {
|
||||||
padding: 40px 20px 40px 20px;
|
padding: 40px 20px 40px 20px;
|
||||||
margin-left: 60px;
|
margin-left: 20px;
|
||||||
|
|
||||||
.sidebar-panel {
|
.sidebar-panel {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{{#if editMode}}
|
{{#if editMode}}
|
||||||
{{document/document-editor document=document folder=folder page=page meta=meta onCancel=(action 'onCancelEdit') onAction=(action 'onSavePage')}}
|
{{document/document-editor document=document folder=folder page=page meta=meta onCancel=(action 'onCancelEdit') onAction=(action 'onSavePage')}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{document/page-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor tabMode=tabMode
|
{{document/page-heading tagName=page.tagName document=document folder=folder page=page permissions=permissions tabMode=tabMode
|
||||||
onEdit=(action 'onEdit') onSavePageAsBlock=(action 'onSavePageAsBlock')
|
onEdit=(action 'onEdit') onSavePageAsBlock=(action 'onSavePageAsBlock')
|
||||||
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
||||||
{{section/base-renderer page=page}}
|
{{section/base-renderer page=page}}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div id="page-{{ page.id }}" class="is-a-tab wysiwyg non-printable {{if expanded 'tab-max' 'tab-min'}}" data-id="{{ page.id }}" data-type="{{ page.contentType }}">
|
<div id="page-{{ page.id }}" class="is-a-tab wysiwyg non-printable {{if expanded 'tab-max' 'tab-min'}}" data-id="{{ page.id }}" data-type="{{ page.contentType }}">
|
||||||
{{document/tab-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor
|
{{document/tab-heading tagName=page.tagName document=document folder=folder page=page permissions=permissions
|
||||||
onExpand=(action 'onExpand') onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
onExpand=(action 'onExpand') onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
||||||
{{#if expanded}}
|
{{#if expanded}}
|
||||||
{{section/base-renderer page=page}}
|
{{section/base-renderer page=page}}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{{#if hasPages}}
|
{{#if hasPages}}
|
||||||
{{#each pages key="id" as |page index|}}
|
{{#each pages key="id" as |page index|}}
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div class="start-section" data-index={{index}} data-before-id={{page.id}} id="add-section-button-{{page.id}}" {{action 'onShowSectionWizard' page}}>
|
<div class="start-section" data-index={{index}} data-before-id={{page.id}} id="add-section-button-{{page.id}}" {{action 'onShowSectionWizard' page}}>
|
||||||
<div class="start-button">
|
<div class="start-button">
|
||||||
<div class="round-button round-button-small button-green">
|
<div class="round-button round-button-small button-green">
|
||||||
|
@ -15,19 +15,19 @@
|
||||||
<div class="section-divider" />
|
<div class="section-divider" />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (is-equal page.pageType 'section')}}
|
{{#if (is-equal page.pageType 'section')}}
|
||||||
{{#document/document-page document=document folder=folder page=page isEditor=isEditor toEdit=toEdit pageId=pageId
|
{{#document/document-page document=document folder=folder page=page permissions=permissions toEdit=toEdit pageId=pageId
|
||||||
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
|
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
|
||||||
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
||||||
{{/document/document-page}}
|
{{/document/document-page}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (is-equal page.pageType 'tab')}}
|
{{#if (is-equal page.pageType 'tab')}}
|
||||||
{{#document/document-tab document=document folder=folder page=page isEditor=isEditor pageId=pageId
|
{{#document/document-tab document=document folder=folder page=page permissions=permissions pageId=pageId
|
||||||
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
|
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
|
||||||
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
|
||||||
{{/document/document-tab}}
|
{{/document/document-tab}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div class="start-section" data-index="0" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
|
<div class="start-section" data-index="0" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
|
||||||
<div class="start-button">
|
<div class="start-button">
|
||||||
<div class="round-button round-button-small button-green">
|
<div class="round-button round-button-small button-green">
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div class="start-section start-section-empty-state" data-index="-1" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
|
<div class="start-section start-section-empty-state" data-index="-1" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
|
||||||
<div class="start-button">
|
<div class="start-button">
|
||||||
<div class="round-button round-button-small button-green">
|
<div class="round-button round-button-small button-green">
|
||||||
|
|
|
@ -1,73 +1,89 @@
|
||||||
<div class="page-title">
|
<div class="page-title">
|
||||||
<span id="page-title-{{ page.id }}">{{ page.title }}</span>
|
<span id="page-title-{{ page.id }}">{{ page.title }}</span>
|
||||||
<div id="page-toolbar-{{ page.id }}" class="pull-right page-toolbar hidden-xs hidden-sm">
|
<div id="page-toolbar-{{ page.id }}" class="pull-right page-toolbar hidden-xs hidden-sm">
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div class="round-button-mono" {{action 'onEdit'}}>
|
<div class="round-button-mono" {{action 'onEdit'}}>
|
||||||
<i class="material-icons color-gray">mode_edit</i>
|
<i class="material-icons color-gray">mode_edit</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="round-button-mono" id="page-menu-{{page.id}}">
|
{{#if hasMenuPermissions}}
|
||||||
<i class="material-icons color-gray">more_vert</i>
|
<div class="round-button-mono" id="page-menu-{{page.id}}">
|
||||||
</div>
|
<i class="material-icons color-gray">more_vert</i>
|
||||||
|
</div>
|
||||||
{{#dropdown-menu target=menuTarget position="top right" open="click" onOpenCallback=(action 'onMenuOpen') onCloseCallback=(action 'onMenuOpen')}}
|
{{#dropdown-menu target=menuTarget position="top right" open="click" onOpenCallback=(action 'onMenuOpen') onCloseCallback=(action 'onMenuOpen')}}
|
||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
<li class="item" id={{copyButtonId}}>Copy</li>
|
{{#if permissions.documentCopy}}
|
||||||
<li class="item" id={{moveButtonId}}>Move</li>
|
<li class="item" id={{copyButtonId}}>Copy</li>
|
||||||
<li class="item" id={{publishButtonId}}>Publish</li>
|
{{/if}}
|
||||||
<li class="divider"></li>
|
{{#if permissions.documentMove}}
|
||||||
<li class="item danger" id={{deleteButtonId}}>Delete</li>
|
<li class="item" id={{moveButtonId}}>Move</li>
|
||||||
</ul>
|
{{/if}}
|
||||||
{{/dropdown-menu}}
|
{{#if permissions.documentTemplate}}
|
||||||
|
<li class="item" id={{publishButtonId}}>Publish</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if permissions.documentDelete}}
|
||||||
|
<li class="item danger" id={{deleteButtonId}}>Delete</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
{{/dropdown-menu}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if menuOpen}}
|
{{#if menuOpen}}
|
||||||
{{#dropdown-dialog target=deleteButtonId position="bottom right" button="Delete" color="flat-red" onAction=(action 'deletePage')}}
|
{{#if permissions.documentDelete}}
|
||||||
<p>Are you sure you want to delete <span class="bold">{{page.title}}?</span></p>
|
{{#dropdown-dialog target=deleteButtonId position="bottom right" button="Delete" color="flat-red" onAction=(action 'deletePage')}}
|
||||||
<p>
|
<p>Are you sure you want to delete <span class="bold">{{page.title}}?</span></p>
|
||||||
{{input type="checkbox" id=checkId class="margin-left-20" checked=deleteChildren}}
|
<p>
|
||||||
<label for="{{checkId}}"> Delete child sections</label>
|
{{input type="checkbox" id=checkId class="margin-left-20" checked=deleteChildren}}
|
||||||
</p>
|
<label for="{{checkId}}"> Delete child sections</label>
|
||||||
{{/dropdown-dialog}}
|
</p>
|
||||||
{{#dropdown-dialog id=publishDialogId target=publishButtonId position="bottom right" button="Publish" color="flat-green" focusOn=blockTitleId onAction=(action 'onSavePageAsBlock')}}
|
{{/dropdown-dialog}}
|
||||||
<div class="form-header">
|
{{/if}}
|
||||||
<div class="tip">
|
{{#if permissions.documentTemplate}}
|
||||||
<span class="bold">{{folder.name}}:</span> Content Block
|
{{#dropdown-dialog id=publishDialogId target=publishButtonId position="bottom right" button="Publish" color="flat-green" focusOn=blockTitleId onAction=(action 'onSavePageAsBlock')}}
|
||||||
|
<div class="form-header">
|
||||||
|
<div class="tip">
|
||||||
|
<span class="bold">{{folder.name}}:</span> Content Block
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="input-control">
|
||||||
<div class="input-control">
|
<label>Name</label>
|
||||||
<label>Name</label>
|
<div class="tip">Short title for reusable content block</div>
|
||||||
<div class="tip">Short title for reusable content block</div>
|
{{input type="text" value=blockTitle id=blockTitleId}}
|
||||||
{{input type="text" value=blockTitle id=blockTitleId}}
|
|
||||||
</div>
|
|
||||||
<div class="input-control">
|
|
||||||
<label>Description</label>
|
|
||||||
<div class="tip">Short description to help others understand<br/>the reusable content block</div>
|
|
||||||
{{textarea rows="3" value=blockExcerpt id=blockExcerptId}}
|
|
||||||
</div>
|
|
||||||
{{/dropdown-dialog}}
|
|
||||||
{{#dropdown-dialog id=copyDialogId target=copyButtonId position="bottom right" button="Copy" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onCopyPage')}}
|
|
||||||
<div class="form-header">
|
|
||||||
<div class="tip">
|
|
||||||
<span class="bold">Copy:</span> {{page.title}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="input-control">
|
||||||
<div class="input-control">
|
<label>Description</label>
|
||||||
<label>Target</label>
|
<div class="tip">Short description to help others understand<br/>the reusable content block</div>
|
||||||
<div class="tip">Select where the content should be copied to</div>
|
{{textarea rows="3" value=blockExcerpt id=blockExcerptId}}
|
||||||
{{ui-select cssClass="dropdown-page-toolbar" content=documentList action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name" selection=document}}
|
|
||||||
</div>
|
|
||||||
{{/dropdown-dialog}}
|
|
||||||
{{#dropdown-dialog id=moveDialogId target=moveButtonId position="bottom right" button="Move" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onMovePage')}}
|
|
||||||
<div class="form-header">
|
|
||||||
<div class="tip">
|
|
||||||
<span class="bold">Move:</span> {{page.title}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{/dropdown-dialog}}
|
||||||
<div class="input-control">
|
{{/if}}
|
||||||
<label>Target</label>
|
{{#if permissions.documentCopy}}
|
||||||
<div class="tip">Select where the content should be moved to</div>
|
{{#dropdown-dialog id=copyDialogId target=copyButtonId position="bottom right" button="Copy" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onCopyPage')}}
|
||||||
{{ui-select cssClass="dropdown-page-toolbar" content=documentListOthers action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name"}}
|
<div class="form-header">
|
||||||
</div>
|
<div class="tip">
|
||||||
{{/dropdown-dialog}}
|
<span class="bold">Copy:</span> {{page.title}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-control">
|
||||||
|
<label>Target</label>
|
||||||
|
<div class="tip">Select where the content should be copied to</div>
|
||||||
|
{{ui-select cssClass="dropdown-page-toolbar" content=documentList action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name" selection=document}}
|
||||||
|
</div>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if permissions.documentMove}}
|
||||||
|
{{#dropdown-dialog id=moveDialogId target=moveButtonId position="bottom right" button="Move" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onMovePage')}}
|
||||||
|
<div class="form-header">
|
||||||
|
<div class="tip">
|
||||||
|
<span class="bold">Move:</span> {{page.title}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-control">
|
||||||
|
<label>Target</label>
|
||||||
|
<div class="tip">Select where the content should be moved to</div>
|
||||||
|
{{ui-select cssClass="dropdown-page-toolbar" content=documentListOthers action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name"}}
|
||||||
|
</div>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="sidebar-panel">
|
<div class="sidebar-panel">
|
||||||
<div class="title">Attachments</div>
|
<div class="title">Attachments</div>
|
||||||
<div class="document-sidebar-view-attachments">
|
<div class="document-sidebar-view-attachments">
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div id="upload-document-files" class="upload-document-files">
|
<div id="upload-document-files" class="upload-document-files">
|
||||||
Drag-drop files or click to select files
|
Drag-drop files or click to select files
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,78 +9,94 @@
|
||||||
<i class="material-icons color-gray">expand_more</i>
|
<i class="material-icons color-gray">expand_more</i>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
{{#link-to 'document.section' page.id}}
|
{{#link-to 'document.section' page.id}}
|
||||||
<div class="round-button-mono">
|
<div class="round-button-mono">
|
||||||
<i class="material-icons color-gray">mode_edit</i>
|
<i class="material-icons color-gray">mode_edit</i>
|
||||||
</div>
|
</div>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
<div class="round-button-mono" id="page-menu-{{page.id}}">
|
{{#if hasMenuPermissions}}
|
||||||
<i class="material-icons color-gray">more_vert</i>
|
<div class="round-button-mono" id="page-menu-{{page.id}}">
|
||||||
</div>
|
<i class="material-icons color-gray">more_vert</i>
|
||||||
|
</div>
|
||||||
|
{{#dropdown-menu target=menuTarget position="top right" open="click" onOpenCallback=(action 'onMenuOpen') onCloseCallback=(action 'onMenuOpen')}}
|
||||||
|
<ul class="menu">
|
||||||
|
{{#if permissions.documentCopy}}
|
||||||
|
<li class="item" id={{copyButtonId}}>Copy</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if permissions.documentMove}}
|
||||||
|
<li class="item" id={{moveButtonId}}>Move</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if permissions.documentTemplate}}
|
||||||
|
<li class="item" id={{publishButtonId}}>Publish</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if permissions.documentDelete}}
|
||||||
|
<li class="item danger" id={{deleteButtonId}}>Delete</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
{{/dropdown-menu}}
|
||||||
|
{{/if}}
|
||||||
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
||||||
<i class="material-icons color-gray">expand_less</i>
|
<i class="material-icons color-gray">expand_less</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#dropdown-menu target=menuTarget position="top right" open="click" onOpenCallback=(action 'onMenuOpen') onCloseCallback=(action 'onMenuOpen')}}
|
|
||||||
<ul class="menu">
|
|
||||||
<li class="item" id={{copyButtonId}}>Copy</li>
|
|
||||||
<li class="item" id={{moveButtonId}}>Move</li>
|
|
||||||
<li class="item" id={{publishButtonId}}>Publish</li>
|
|
||||||
<li class="divider"></li>
|
|
||||||
<li class="item danger" id={{deleteButtonId}}>Delete</li>
|
|
||||||
</ul>
|
|
||||||
{{/dropdown-menu}}
|
|
||||||
|
|
||||||
{{#if menuOpen}}
|
{{#if menuOpen}}
|
||||||
{{#dropdown-dialog target=deleteButtonId position="bottom right" button="Delete" color="flat-red" onAction=(action 'deletePage')}}
|
{{#if permissions.documentDelete}}
|
||||||
<p>Are you sure you want to delete <span class="bold">{{page.title}}?</span></p>
|
{{#dropdown-dialog target=deleteButtonId position="bottom right" button="Delete" color="flat-red" onAction=(action 'deletePage')}}
|
||||||
<p>
|
<p>Are you sure you want to delete <span class="bold">{{page.title}}?</span></p>
|
||||||
{{input type="checkbox" id=checkId class="margin-left-20" checked=deleteChildren}}
|
<p>
|
||||||
<label for="{{checkId}}"> Delete child sections</label>
|
{{input type="checkbox" id=checkId class="margin-left-20" checked=deleteChildren}}
|
||||||
</p>
|
<label for="{{checkId}}"> Delete child sections</label>
|
||||||
{{/dropdown-dialog}}
|
</p>
|
||||||
{{#dropdown-dialog id=publishDialogId target=publishButtonId position="bottom right" button="Publish" color="flat-green" focusOn=blockTitleId onAction=(action 'onSavePageAsBlock')}}
|
{{/dropdown-dialog}}
|
||||||
<div class="form-header">
|
{{/if}}
|
||||||
<div class="tip">
|
{{#if permissions.documentTemplate}}
|
||||||
<span class="bold">{{folder.name}}:</span> Content Block
|
{{#dropdown-dialog id=publishDialogId target=publishButtonId position="bottom right" button="Publish" color="flat-green" focusOn=blockTitleId onAction=(action 'onSavePageAsBlock')}}
|
||||||
|
<div class="form-header">
|
||||||
|
<div class="tip">
|
||||||
|
<span class="bold">{{folder.name}}:</span> Content Block
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="input-control">
|
||||||
<div class="input-control">
|
<label>Name</label>
|
||||||
<label>Name</label>
|
<div class="tip">Short title for reusable content block</div>
|
||||||
<div class="tip">Short title for reusable content block</div>
|
{{input type="text" value=blockTitle id=blockTitleId}}
|
||||||
{{input type="text" value=blockTitle id=blockTitleId}}
|
|
||||||
</div>
|
|
||||||
<div class="input-control">
|
|
||||||
<label>Description</label>
|
|
||||||
<div class="tip">Short description to help others understand<br/>the reusable content block</div>
|
|
||||||
{{textarea rows="3" value=blockExcerpt id=blockExcerptId}}
|
|
||||||
</div>
|
|
||||||
{{/dropdown-dialog}}
|
|
||||||
{{#dropdown-dialog id=copyDialogId target=copyButtonId position="bottom right" button="Copy" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onCopyPage')}}
|
|
||||||
<div class="form-header">
|
|
||||||
<div class="tip">
|
|
||||||
<span class="bold">Copy:</span> {{page.title}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="input-control">
|
||||||
<div class="input-control">
|
<label>Description</label>
|
||||||
<label>Target</label>
|
<div class="tip">Short description to help others understand<br/>the reusable content block</div>
|
||||||
<div class="tip">Select where the content should be copied to</div>
|
{{textarea rows="3" value=blockExcerpt id=blockExcerptId}}
|
||||||
{{ui-select cssClass="dropdown-page-toolbar" content=documentList action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name" selection=document}}
|
|
||||||
</div>
|
|
||||||
{{/dropdown-dialog}}
|
|
||||||
{{#dropdown-dialog id=moveDialogId target=moveButtonId position="bottom right" button="Move" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onMovePage')}}
|
|
||||||
<div class="form-header">
|
|
||||||
<div class="tip">
|
|
||||||
<span class="bold">Move:</span> {{page.title}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{/dropdown-dialog}}
|
||||||
<div class="input-control">
|
{{/if}}
|
||||||
<label>Target</label>
|
{{#if permissions.documentCopy}}
|
||||||
<div class="tip">Select where the content should be moved to</div>
|
{{#dropdown-dialog id=copyDialogId target=copyButtonId position="bottom right" button="Copy" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onCopyPage')}}
|
||||||
{{ui-select cssClass="dropdown-page-toolbar" content=documentListOthers action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name"}}
|
<div class="form-header">
|
||||||
</div>
|
<div class="tip">
|
||||||
{{/dropdown-dialog}}
|
<span class="bold">Copy:</span> {{page.title}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-control">
|
||||||
|
<label>Target</label>
|
||||||
|
<div class="tip">Select where the content should be copied to</div>
|
||||||
|
{{ui-select cssClass="dropdown-page-toolbar" content=documentList action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name" selection=document}}
|
||||||
|
</div>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if permissions.documentMove}}
|
||||||
|
{{#dropdown-dialog id=moveDialogId target=moveButtonId position="bottom right" button="Move" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onMovePage')}}
|
||||||
|
<div class="form-header">
|
||||||
|
<div class="tip">
|
||||||
|
<span class="bold">Move:</span> {{page.title}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-control">
|
||||||
|
<label>Target</label>
|
||||||
|
<div class="tip">Select where the content should be moved to</div>
|
||||||
|
{{ui-select cssClass="dropdown-page-toolbar" content=documentListOthers action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name"}}
|
||||||
|
</div>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{{#each tagz as |tg|}}
|
{{#each tagz as |tg|}}
|
||||||
<div class="chip">
|
<div class="chip">
|
||||||
<span class="chip-text">#{{tg}}</span>
|
<span class="chip-text">#{{tg}}</span>
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<i class="material-icons pull-right" {{action 'removeTag' tg}}>close</i>
|
<i class="material-icons pull-right" {{action 'removeTag' tg}}>close</i>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
{{#if permissions.spaceManage}}
|
{{#if permissions.spaceManage}}
|
||||||
{{#link-to 'folder.settings' folder.id folder.slug}}{{model.document.name}}
|
{{#link-to 'folder.settings' folder.id folder.slug}}{{model.document.name}}
|
||||||
<div class="round-button button-gray" id="space-settings-button" data-tooltip="Manage permissions" data-tooltip-position="top center">
|
<div class="round-button button-blue" id="space-settings-button" data-tooltip="Manage permissions" data-tooltip-position="top center">
|
||||||
<i class="material-icons">settings</i>
|
<i class="material-icons">settings</i>
|
||||||
</div>
|
</div>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
|
@ -45,11 +45,30 @@
|
||||||
|
|
||||||
{{#if permissions.spaceOwner}}
|
{{#if permissions.spaceOwner}}
|
||||||
<div class="button-gap"></div>
|
<div class="button-gap"></div>
|
||||||
<div class="round-button button-gray" id="space-delete-button" data-tooltip="Delete everything" data-tooltip-position="top center">
|
<div class="round-button button-red" id="space-delete-button" data-tooltip="Delete everything" data-tooltip-position="top center">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if pinState.isPinned}}
|
||||||
|
<div class="button-gap"></div>
|
||||||
|
<div class="round-button button-gray" id="space-unpin-button" data-tooltip="Pin space" data-tooltip-position="top center" {{action 'onUnpin'}}>
|
||||||
|
<i class="material-icons">favorite</i>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="button-gap"></div>
|
||||||
|
<div class="round-button button-gray" id="space-pin-button" data-tooltip="Pin space" data-tooltip-position="top center">
|
||||||
|
<i class="material-icons">favorite_border</i>
|
||||||
|
</div>
|
||||||
|
{{#dropdown-dialog target="space-pin-button" position="bottom right" button="Pin" color="flat-green" onAction=(action 'onPin') focusOn="pin-space-name" }}
|
||||||
|
<div class="input-control">
|
||||||
|
<label>Pin Space</label>
|
||||||
|
<div class="tip">A 3 or 4 character name</div>
|
||||||
|
{{input type='text' id="pin-space-name" value=pinState.newName}}
|
||||||
|
</div>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,53 +1,3 @@
|
||||||
<div class="sidebar-toolbar">
|
|
||||||
{{#unless noFolder}}
|
|
||||||
<div class="margin-top-20"></div>
|
|
||||||
<div class="round-button-mono {{if (is-equal tab 'index') 'selected'}}" {{action 'onChangeTab' 'index'}}>
|
|
||||||
<i class="material-icons">view_headline</i>
|
|
||||||
</div>
|
|
||||||
<div class="margin-top-20"></div>
|
|
||||||
|
|
||||||
{{#if session.authenticated}}
|
|
||||||
{{#if permissions.spaceManage}}
|
|
||||||
{{#if isAuthProviderDocumize}}
|
|
||||||
<div class="round-button-mono {{if (is-equal tab 'share') 'selected'}}" {{action 'onChangeTab' 'share'}}>
|
|
||||||
<i class="material-icons">person_add</i>
|
|
||||||
</div>
|
|
||||||
<div class="margin-top-20"></div>
|
|
||||||
{{/if}}
|
|
||||||
<div class="round-button-mono {{if (is-equal tab 'permissions') 'selected'}}" {{action 'onChangeTab' 'permissions'}}>
|
|
||||||
<i class="material-icons">group</i>
|
|
||||||
</div>
|
|
||||||
<div class="margin-top-20"></div>
|
|
||||||
{{/if}}
|
|
||||||
<div class="round-button-mono" id="space-more-button">
|
|
||||||
<i class="material-icons">more_horiz</i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#dropdown-menu target="space-more-button" position="bottom left" open="click" onOpenCallback=(action 'onMenuOpen') onCloseCallback=(action 'onMenuOpen')}}
|
|
||||||
<ul class="menu">
|
|
||||||
{{#if pinState.isPinned}}
|
|
||||||
<li class="item" {{action 'onUnpin'}}>Unpin</li>
|
|
||||||
{{else}}
|
|
||||||
<li class="item" id="pin-space-button">Pin</li>
|
|
||||||
{{/if}}
|
|
||||||
</ul>
|
|
||||||
{{/dropdown-menu}}
|
|
||||||
|
|
||||||
{{#if menuOpen}}
|
|
||||||
{{#unless pinState.isPinned}}
|
|
||||||
{{#dropdown-dialog target="pin-space-button" position="bottom left" button="Pin" color="flat-green" onAction=(action 'onPin') focusOn="pin-space-name" }}
|
|
||||||
<div class="input-control">
|
|
||||||
<label>Pin Space</label>
|
|
||||||
<div class="tip">A 3 or 4 character name</div>
|
|
||||||
{{input type='text' id="pin-space-name" value=pinState.newName}}
|
|
||||||
</div>
|
|
||||||
{{/dropdown-dialog}}
|
|
||||||
{{/unless}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/unless}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar-common">
|
<div class="sidebar-common">
|
||||||
{{layout/sidebar-intro title=appMeta.title message=appMeta.message}}
|
{{layout/sidebar-intro title=appMeta.title message=appMeta.message}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,12 +6,4 @@
|
||||||
{{#if (is-equal tab 'index')}}
|
{{#if (is-equal tab 'index')}}
|
||||||
{{folder/sidebar-folders-list folders=folders folder=folder permissions=permissions onAddSpace=(action 'onAddSpace')}}
|
{{folder/sidebar-folders-list folders=folders folder=folder permissions=permissions onAddSpace=(action 'onAddSpace')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (is-equal tab 'share')}}
|
|
||||||
{{folder/sidebar-share folders=folders folder=folder}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if (is-equal tab 'permissions')}}
|
|
||||||
{{folder/sidebar-permissions folders=folders folder=folder}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,15 +23,6 @@ let BaseModel = Ember.Object.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let FolderPermissionModel = Ember.Object.extend({
|
|
||||||
orgId: "",
|
|
||||||
folderId: "",
|
|
||||||
userId: "",
|
|
||||||
fullname: "",
|
|
||||||
canView: false,
|
|
||||||
canEdit: false
|
|
||||||
});
|
|
||||||
|
|
||||||
// ProtectedFolderParticipant used to display folder participants that can
|
// ProtectedFolderParticipant used to display folder participants that can
|
||||||
// then be marked as folder owner.
|
// then be marked as folder owner.
|
||||||
let ProtectedFolderParticipant = Ember.Object.extend({
|
let ProtectedFolderParticipant = Ember.Object.extend({
|
||||||
|
@ -218,4 +209,4 @@ export default {
|
||||||
ProtectedFolderParticipant,
|
ProtectedFolderParticipant,
|
||||||
UserModel,
|
UserModel,
|
||||||
SectionModel
|
SectionModel
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default function(name, options = {}) {
|
||||||
server.createList('user', 2);
|
server.createList('user', 2);
|
||||||
server.createList('document', 2);
|
server.createList('document', 2);
|
||||||
server.createList('permission', 4);
|
server.createList('permission', 4);
|
||||||
server.createList('folder-permission', 2);
|
// server.createList('folder-permission', 2);
|
||||||
server.createList('organization', 1);
|
server.createList('organization', 1);
|
||||||
|
|
||||||
if (options.beforeEach) {
|
if (options.beforeEach) {
|
||||||
|
|
|
@ -117,6 +117,7 @@ func EncodeRecord(r PermissionRecord, a PermissionAction) (p Permission) {
|
||||||
p.Location = "space"
|
p.Location = "space"
|
||||||
p.RefID = r.SpaceID
|
p.RefID = r.SpaceID
|
||||||
p.Action = a
|
p.Action = a
|
||||||
|
p.Scope = "object" // default to row level permission
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue