From 899b4f978ccbeb85b9dccb877e53c7ace5fe79d6 Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Wed, 26 Oct 2016 17:31:05 -0700 Subject: [PATCH] click handlers for content links --- app/app/components/document/document-view.js | 31 ++++++ app/app/components/document/edit-tools.js | 24 ++++- app/app/components/ui/ui-tab.js | 32 +++++++ app/app/initializers/event-bus.js | 8 +- app/app/initializers/route-injector.js | 20 ++++ app/app/pods/document/index/route.js | 16 +--- app/app/pods/document/index/template.hbs | 1 + app/app/services/audit.js | 1 + app/app/services/base.js | 12 ++- app/app/services/event-bus.js | 1 + app/app/services/link.js | 95 +++++++++++++------ app/app/services/session.js | 2 + app/app/styles/base.scss | 2 +- app/app/styles/view/document/edit-tools.scss | 4 +- app/app/styles/widget/widget-tab.scss | 27 ++++++ app/app/styles/widget/widget.scss | 1 + .../components/document/edit-tools.hbs | 25 +++-- app/app/templates/components/ui/ui-tab.hbs | 5 + core/api/endpoint/link_endpoint.go | 13 +-- core/api/endpoint/router.go | 2 +- core/api/entity/objects.go | 2 + core/api/request/link.go | 10 +- core/api/request/page.go | 2 +- core/api/util/encoding_test.go | 4 +- core/api/util/links.go | 2 + core/database/scripts/autobuild/db_00000.sql | 3 +- core/database/scripts/autobuild/db_00004.sql | 3 +- 27 files changed, 265 insertions(+), 83 deletions(-) create mode 100644 app/app/components/ui/ui-tab.js create mode 100644 app/app/initializers/route-injector.js create mode 100644 app/app/styles/widget/widget-tab.scss create mode 100644 app/app/templates/components/ui/ui-tab.hbs diff --git a/app/app/components/document/document-view.js b/app/app/components/document/document-view.js index 5efb80c9..297c2af5 100644 --- a/app/app/components/document/document-view.js +++ b/app/app/components/document/document-view.js @@ -17,6 +17,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { documentService: Ember.inject.service('document'), sectionService: Ember.inject.service('section'), appMeta: Ember.inject.service(), + link: Ember.inject.service(), /* Parameters */ document: null, // pages: [], @@ -50,6 +51,10 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { }); }, + didRender() { + this.contentLinkHandler(); + }, + willDestroyElement() { this.destroyTooltips(); @@ -60,6 +65,32 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { } }, + contentLinkHandler() { + let links = this.get('link'); + let doc = this.get('document'); + let self = this; + + $("a[data-documize='true']").off('click').on('click', function() { + let link = links.getLinkObject(this); + + // local link? exists? + if (link.linkType === "section" && link.documentId === doc.get('id')) { + let exists = self.get('pages').findBy('id', link.targetId); + + if (_.isUndefined(exists) || link.orphan) { + self.showNotification('Broken link!'); + return false; + } else { + self.attrs.gotoPage(link.targetId); + return false; + } + } + + links.linkClick(doc, link); + return false; + }); + }, + actions: { confirmDeleteAttachment(id, name) { this.set('deleteAttachment', { diff --git a/app/app/components/document/edit-tools.js b/app/app/components/document/edit-tools.js index 7d4794ca..d507ea0d 100644 --- a/app/app/components/document/edit-tools.js +++ b/app/app/components/document/edit-tools.js @@ -18,20 +18,34 @@ const { export default Ember.Component.extend(TooltipMixin, { link: service(), - hasSections: false, - hasAttachments: false, linkName: '', keywords: '', selection: null, + tabs: [ + { label: 'Section', selected: true }, + { label: 'Attachment', selected: false }, + { label: 'Search', selected: false } + ], + + showSections: Ember.computed('tabs.@each.selected', function() { + return this.get('tabs').findBy('label', 'Section').selected; + }), + showAttachments: Ember.computed('tabs.@each.selected', function() { + return this.get('tabs').findBy('label', 'Attachment').selected; + }), + showSearch: Ember.computed('tabs.@each.selected', function() { + return this.get('tabs').findBy('label', 'Search').selected; + }), init() { this._super(...arguments); let self = this; + let folderId = this.get('folder.id'); let documentId = this.get('document.id'); let pageId = this.get('page.id'); - this.get('link').getCandidates(documentId, pageId).then(function (candidates) { + this.get('link').getCandidates(folderId, documentId, pageId).then(function (candidates) { self.set('candidates', candidates); self.set('hasSections', is.not.null(candidates.pages) && candidates.pages.length); self.set('hasAttachments', is.not.null(candidates.attachments) && candidates.attachments.length); @@ -69,6 +83,10 @@ export default Ember.Component.extend(TooltipMixin, { } return this.get('onInsertLink')(selection); + }, + + onTabSelect(tabs) { + this.set('tabs', tabs); } } }); diff --git a/app/app/components/ui/ui-tab.js b/app/app/components/ui/ui-tab.js new file mode 100644 index 00000000..02977065 --- /dev/null +++ b/app/app/components/ui/ui-tab.js @@ -0,0 +1,32 @@ +// Copyright 2016 Documize Inc. . 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 . +// +// https://documize.com + +import Ember from 'ember'; + +export default Ember.Component.extend({ + myWidth: Ember.computed('tabs', function() { + let count = this.get('tabs.length'); + let width = 95 / count; + return Ember.String.htmlSafe("width: " + `${width}%;`); + }), + + actions: { + onTabSelect(tab) { + this.get('tabs').forEach(t => { + Ember.set(t, 'selected', false); + }); + + Ember.set(tab, 'selected', true); + + this.attrs.onTabSelect(this.get('tabs')); + } + } +}); diff --git a/app/app/initializers/event-bus.js b/app/app/initializers/event-bus.js index 877524c9..3029b3e6 100644 --- a/app/app/initializers/event-bus.js +++ b/app/app/initializers/event-bus.js @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . 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 // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -18,6 +18,6 @@ export function initialize(application) { export default { name: 'eventBus', - after: 'session', + after: 'application', initialize: initialize -}; \ No newline at end of file +}; diff --git a/app/app/initializers/route-injector.js b/app/app/initializers/route-injector.js new file mode 100644 index 00000000..e511b15d --- /dev/null +++ b/app/app/initializers/route-injector.js @@ -0,0 +1,20 @@ +// Copyright 2016 Documize Inc. . 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 . +// +// https://documize.com + +export function initialize(application) { + application.inject('component', 'router', 'router:main'); + application.inject('service', 'router', 'router:main'); +} + +export default { + name: 'route-injector', + initialize: initialize +}; diff --git a/app/app/pods/document/index/route.js b/app/app/pods/document/index/route.js index c57664bc..b0135671 100644 --- a/app/app/pods/document/index/route.js +++ b/app/app/pods/document/index/route.js @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . 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 // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -16,7 +16,6 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { documentService: Ember.inject.service('document'), folderService: Ember.inject.service('folder'), userService: Ember.inject.service('user'), - pages: [], attachments: [], users: [], @@ -107,14 +106,5 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { controller.set('meta', meta); this.browser.setMetaDescription(model.get('excerpt')); - }, - - // Document view needs all white background! - activate() { - Ember.$('html').addClass('background-color-white'); - }, - - deactivate() { - Ember.$('html').removeClass('background-color-white'); } -}); \ No newline at end of file +}); diff --git a/app/app/pods/document/index/template.hbs b/app/app/pods/document/index/template.hbs index 4554f0ba..3302f944 100644 --- a/app/app/pods/document/index/template.hbs +++ b/app/app/pods/document/index/template.hbs @@ -20,6 +20,7 @@ {{document/document-view document=model pages=pages attachments=attachments folder=folder folders=folders isEditor=isEditor + gotoPage=(action 'gotoPage') onAttachmentDeleted=(action 'onAttachmentDeleted') onDeletePage=(action 'onPageDeleted')}} {{/layout/zone-content}} diff --git a/app/app/services/audit.js b/app/app/services/audit.js index 02385bf8..162722f7 100644 --- a/app/app/services/audit.js +++ b/app/app/services/audit.js @@ -25,6 +25,7 @@ export default Ember.Service.extend({ appId: config.APP.intercomKey, init() { + this._super(...arguments); this.start(); }, diff --git a/app/app/services/base.js b/app/app/services/base.js index 270aac4b..4adaad99 100644 --- a/app/app/services/base.js +++ b/app/app/services/base.js @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . 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 // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -28,5 +28,9 @@ export default Ember.Service.extend({ }(wait, times); setTimeout(interv, wait); - } -}); \ No newline at end of file + }, + + showNotification(msg) { + this.get('eventBus').publish('notifyUser', msg); + } +}); diff --git a/app/app/services/event-bus.js b/app/app/services/event-bus.js index 2894c81c..efbe4932 100644 --- a/app/app/services/event-bus.js +++ b/app/app/services/event-bus.js @@ -13,6 +13,7 @@ import Ember from 'ember'; export default Ember.Service.extend(Ember.Evented, { init() { + this._super(...arguments); let _this = this; window.addEventListener("scroll", _.throttle(function() { diff --git a/app/app/services/link.js b/app/app/services/link.js index 224d7838..3f4b9060 100644 --- a/app/app/services/link.js +++ b/app/app/services/link.js @@ -19,10 +19,11 @@ export default Ember.Service.extend({ sessionService: service('session'), ajax: service(), appMeta: service(), + store: service(), // Returns candidate links using provided parameters - getCandidates(documentId, pageId /*, keywords*/ ) { - return this.get('ajax').request(`links/${documentId}/${pageId}`, { + getCandidates(folderId, documentId, pageId /*, keywords*/ ) { + return this.get('ajax').request(`links/${folderId}/${documentId}/${pageId}`, { method: 'GET' }).then((response) => { return response; @@ -35,45 +36,85 @@ export default Ember.Service.extend({ let endpoint = this.get('appMeta').get('endpoint'); let orgId = this.get('appMeta').get('orgId'); - if (link.linkType === "section") { + if (link.linkType === "section" || link.linkType === "document") { href = `/link/${link.linkType}/${link.id}`; + result = `${link.title}`; } if (link.linkType === "file") { href = `${endpoint}/public/attachments/${orgId}/${link.targetId}`; - } - if (link.linkType === "document") { - href = `/link/${link.linkType}/${link.id}`; + result = `${link.title}`; } - result = `${link.title}`; return result; + }, + + getLinkObject(a) { + let link = { + linkId: a.attributes["data-link-id"].value, + linkType: a.attributes["data-link-type"].value, + documentId: a.attributes["data-link-document-id"].value, + folderId: a.attributes["data-link-space-id"].value, + targetId: a.attributes["data-link-target-id"].value, + url: a.attributes["href"].value, + orphan: false + }; + + link.orphan = _.isEmpty(link.linkId) || _.isEmpty(link.documentId) || _.isEmpty(link.folderId) || _.isEmpty(link.targetId); + + return link; + }, + + linkClick(doc, link) { + if (link.orphan) { + return; + } + + let router = this.get('router'); + let targetFolder = this.get('store').peekRecord('folder', link.folderId); + let targetDocument = this.get('store').peekRecord('document', link.documentId); + let folderSlug = is.null(targetFolder) ? "s" : targetFolder.get('slug'); + let documentSlug = is.null(targetDocument) ? "d" : targetDocument.get('slug'); + + // handle section link + if (link.linkType === "section") { + let options = {}; + options['page'] = link.targetId; + router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug, { queryParams: options }); + return; + } + + // handle document link + if (link.inkType === "document") { + router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug); + return; + } + + // handle attachment links + if (link.linkType === "file") { + window.location.href = link.url; + return; + } } }); /* + Keyword search results - docs, section, files -link handler - - implement link redirect handler -- - - for documents: client-side detect - - for sections: - - for attachments: direct link - - + The link id's get ZERO'd in Page.Body whenever: + - doc is moved to different space + - doc is deleted (set to ZERO and marked as orphan) + - page is deleted (set to ZERO and marked as orphan) + - page is moved to different doc (update data-document-id attribute value) + - attachment is deleted (remove HREF) -onDelete document/section/file: - - mark link table row as ORPHAN - - doc view: meta data fetch to load orphaned content + link/section/{documentId}/{sectionId}: + - if ZERO id show notification + - store previous positions -- localStorage, dropdown menu? -Keyword search results - docs, section, files + Markdown editor support -we should not redirect to a link that is in the same document! -what happens if we delete attachment? -UpdatePage(): find and persist links from saved content - -1. We need to deal with links server-side -2. We need to click on links in the browser and 'navigate' to linked content - -editor.insertContent(' It\'s my button! '); -Selects the first paragraph found -tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('p')[0]); + permission checks: + can view space + can view document */ diff --git a/app/app/services/session.js b/app/app/services/session.js index 8701667b..01c0aac0 100644 --- a/app/app/services/session.js +++ b/app/app/services/session.js @@ -41,6 +41,8 @@ export default SimpleAuthSession.extend({ }), init: function () { + this._super(...arguments); + this.set('isMac', is.mac()); this.set('isMobile', is.mobile()); }, diff --git a/app/app/styles/base.scss b/app/app/styles/base.scss index 811d0554..c300ac56 100644 --- a/app/app/styles/base.scss +++ b/app/app/styles/base.scss @@ -196,7 +196,7 @@ $i: 100; .width-#{$i} { width: #{$i}#{"%"}; } - $i: $i - 2; + $i: $i - 1; } .no-outline { diff --git a/app/app/styles/view/document/edit-tools.scss b/app/app/styles/view/document/edit-tools.scss index 14ecdd56..1cef28f6 100644 --- a/app/app/styles/view/document/edit-tools.scss +++ b/app/app/styles/view/document/edit-tools.scss @@ -1,10 +1,10 @@ .edit-tools { - margin: 15px 0 0 20px; + margin: 0 0 0 20px; min-height: 500px; } .content-linker-dialog { - width: 300px; + width: 350px; height: 400px; overflow-y: auto; diff --git a/app/app/styles/widget/widget-tab.scss b/app/app/styles/widget/widget-tab.scss new file mode 100644 index 00000000..d3f7ef4d --- /dev/null +++ b/app/app/styles/widget/widget-tab.scss @@ -0,0 +1,27 @@ +.widget-tab { + width: 100%; + margin: 0; + padding: 0 5px; + text-align: center; + border-bottom: 1px solid $color-border; + + > .tab { + display: inline-block; + margin: 0; + padding: 5px 10px; + color: $color-off-black; + text-align: center; + cursor: pointer; + @include ease-in(); + + &:hover { + background-color: $color-off-white; + color: $color-link; + } + } + + > .selected { + background-color: $color-off-white; + color: $color-link; + } +} diff --git a/app/app/styles/widget/widget.scss b/app/app/styles/widget/widget.scss index bc0b3b33..c88bdce8 100644 --- a/app/app/styles/widget/widget.scss +++ b/app/app/styles/widget/widget.scss @@ -71,3 +71,4 @@ @import "widget-table"; @import "widget-tooltip"; @import "widget-checkbox"; +@import "widget-tab"; diff --git a/app/app/templates/components/document/edit-tools.hbs b/app/app/templates/components/document/edit-tools.hbs index 068f0885..c3aa3e48 100644 --- a/app/app/templates/components/document/edit-tools.hbs +++ b/app/app/templates/components/document/edit-tools.hbs @@ -4,15 +4,14 @@ link - {{#dropdown-dialog target="content-linker-button" focusOn="content-linker-search" position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}} + {{#dropdown-dialog target="content-linker-button" position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}}
-
- -
Choose content below or search
- {{focus-input id="content-linker-search" type="input" value=keywords placeholder="keyword search"}} -
- {{#if hasSections}} + {{ui/ui-tab tabs=tabs onTabSelect=(action 'onTabSelect')}} + +
+ + {{#if showSections}} {{/if}} - {{#if hasAttachments}} + + {{#if showAttachments}} {{/if}} + + {{#if showSearch}} +
+ +
keywords
+ {{focus-input id="content-linker-search" type="input" value=keywords placeholder="keyword search"}} +
+ {{/if}} +
Insert
diff --git a/app/app/templates/components/ui/ui-tab.hbs b/app/app/templates/components/ui/ui-tab.hbs new file mode 100644 index 00000000..2da27644 --- /dev/null +++ b/app/app/templates/components/ui/ui-tab.hbs @@ -0,0 +1,5 @@ +
    + {{#each tabs as |tab|}} +
  • {{tab.label}}
  • + {{/each}} +
diff --git a/core/api/endpoint/link_endpoint.go b/core/api/endpoint/link_endpoint.go index 74e83436..f01f2a6b 100644 --- a/core/api/endpoint/link_endpoint.go +++ b/core/api/endpoint/link_endpoint.go @@ -29,6 +29,7 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) { p := request.GetPersister(r) params := mux.Vars(r) + folderID := params["folderID"] documentID := params["documentID"] pageID := params["pageID"] @@ -68,6 +69,7 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) { if p.RefID != pageID { c := entity.LinkCandidate{ RefID: util.UniqueID(), + FolderID: folderID, DocumentID: documentID, TargetID: p.RefID, LinkType: "section", @@ -95,6 +97,7 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) { for _, f := range files { c := entity.LinkCandidate{ RefID: util.UniqueID(), + FolderID: folderID, DocumentID: documentID, TargetID: f.RefID, LinkType: "file", @@ -124,13 +127,3 @@ func GetLinkCandidates(w http.ResponseWriter, r *http.Request) { util.WriteSuccessBytes(w, json) } - -/* - DocumentID string `json:"documentId"` - PageID string `json:"pageId"` - FileID string `json:"fileId"` - LinkType string `json:"linkType"` - Title string `json:"caption"` // what we label the link - Context string `json:"context"` // additional context (e.g. excerpt, parent) - -*/ diff --git a/core/api/endpoint/router.go b/core/api/endpoint/router.go index 28ec0e09..2d5aa904 100644 --- a/core/api/endpoint/router.go +++ b/core/api/endpoint/router.go @@ -213,7 +213,7 @@ func init() { log.IfErr(Add(RoutePrefixPrivate, "sections/refresh", []string{"GET", "OPTIONS"}, nil, RefreshSections)) // Links - log.IfErr(Add(RoutePrefixPrivate, "links/{documentID}/{pageID}", []string{"GET", "OPTIONS"}, nil, GetLinkCandidates)) + log.IfErr(Add(RoutePrefixPrivate, "links/{folderID}/{documentID}/{pageID}", []string{"GET", "OPTIONS"}, nil, GetLinkCandidates)) // Global installation-wide config log.IfErr(Add(RoutePrefixPrivate, "global", []string{"GET", "OPTIONS"}, nil, GetGlobalConfig)) diff --git a/core/api/entity/objects.go b/core/api/entity/objects.go index d99d273a..75dbfa7c 100644 --- a/core/api/entity/objects.go +++ b/core/api/entity/objects.go @@ -347,6 +347,7 @@ type SitemapDocument struct { type Link struct { BaseEntity OrgID string `json:"orgId"` + FolderID string `json:"folderId"` UserID string `json:"userId"` LinkType string `json:"linkType"` SourceID string `json:"sourceId"` @@ -359,6 +360,7 @@ type Link struct { type LinkCandidate struct { RefID string `json:"id"` LinkType string `json:"linkType"` + FolderID string `json:"folderId"` DocumentID string `json:"documentId"` TargetID string `json:"targetId"` Title string `json:"title"` // what we label the link diff --git a/core/api/request/link.go b/core/api/request/link.go index 2e20ba93..fbf5be59 100644 --- a/core/api/request/link.go +++ b/core/api/request/link.go @@ -27,7 +27,7 @@ func (p *Persister) AddContentLink(l entity.Link) (err error) { l.Created = time.Now().UTC() l.Revised = time.Now().UTC() - stmt, err := p.Context.Transaction.Preparex("INSERT INTO link (refid, orgid, userid, sourceid, documentid, targetid, linktype, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)") + stmt, err := p.Context.Transaction.Preparex("INSERT INTO link (refid, orgid, folderid, userid, sourceid, documentid, targetid, linktype, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") defer utility.Close(stmt) if err != nil { @@ -35,7 +35,7 @@ func (p *Persister) AddContentLink(l entity.Link) (err error) { return } - _, err = stmt.Exec(l.RefID, l.OrgID, l.UserID, l.SourceID, l.DocumentID, l.TargetID, l.LinkType, l.Created, l.Revised) + _, err = stmt.Exec(l.RefID, l.OrgID, l.FolderID, l.UserID, l.SourceID, l.DocumentID, l.TargetID, l.LinkType, l.Created, l.Revised) if err != nil { log.Error("Unable to execute insert for link", err) @@ -49,7 +49,7 @@ func (p *Persister) AddContentLink(l entity.Link) (err error) { func (p *Persister) GetReferencedLinks(sectionID string) (links []entity.Link, err error) { err = nil - sql := "SELECT id,refid,orgid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND sourceid=?" + sql := "SELECT id,refid,orgid,folderid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND sourceid=?" err = Db.Select(&links, sql, p.Context.OrgID, sectionID) @@ -65,7 +65,7 @@ func (p *Persister) GetReferencedLinks(sectionID string) (links []entity.Link, e func (p *Persister) GetContentLinksForSection(sectionID string) (links []entity.Link, err error) { err = nil - sql := "SELECT id,refid,orgid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND sectionid=?" + sql := "SELECT id,refid,orgid,folderid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND sectionid=?" err = Db.Select(&links, sql, p.Context.OrgID, sectionID) @@ -81,7 +81,7 @@ func (p *Persister) GetContentLinksForSection(sectionID string) (links []entity. func (p *Persister) GetContentLinksForDocument(documentID string) (links []entity.Link, err error) { err = nil - sql := "SELECT id,refid,orgid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND documentid=?" + sql := "SELECT id,refid,orgid,folderid,userid,sourceid,documentid,targetid,linktype,orphan,created,revised from link WHERE orgid=? AND documentid=?" err = Db.Select(&links, sql, p.Context.OrgID, documentID) diff --git a/core/api/request/page.go b/core/api/request/page.go index ece2c741..52cee603 100644 --- a/core/api/request/page.go +++ b/core/api/request/page.go @@ -287,7 +287,7 @@ func (p *Persister) UpdatePage(page entity.Page, refID, userID string, skipRevis //} //} - // fimnd any content links + // find any content links in the HTML links := util.GetContentLinks(page.Body) // delete previous content links for this page diff --git a/core/api/util/encoding_test.go b/core/api/util/encoding_test.go index d96993ff..397693a0 100644 --- a/core/api/util/encoding_test.go +++ b/core/api/util/encoding_test.go @@ -14,11 +14,11 @@ package util import "testing" func TestHTMLEncoding(t *testing.T) { - html(t, "", "<script>alert('test')</script>") + testHTML(t, "", "<script>alert('test')</script>") text(t, "", "") } -func html(t *testing.T, in, out string) { +func testHTML(t *testing.T, in, out string) { got := EncodeHTMLString(in) if got != out { t.Errorf("EncodeHTMLString `%s` got `%s` expected `%s`\n", in, got, out) diff --git a/core/api/util/links.go b/core/api/util/links.go index afa8ddb4..620c10b0 100644 --- a/core/api/util/links.go +++ b/core/api/util/links.go @@ -60,6 +60,8 @@ func getLink(t html.Token) (ok bool, link entity.Link) { ok = true case "data-link-id": link.RefID = strings.TrimSpace(a.Val) + case "data-link-space-id": + link.FolderID = strings.TrimSpace(a.Val) case "data-link-document-id": link.DocumentID = strings.TrimSpace(a.Val) case "data-link-target-id": diff --git a/core/database/scripts/autobuild/db_00000.sql b/core/database/scripts/autobuild/db_00000.sql index 79098323..4a4b727c 100644 --- a/core/database/scripts/autobuild/db_00000.sql +++ b/core/database/scripts/autobuild/db_00000.sql @@ -319,7 +319,8 @@ CREATE TABLE IF NOT EXISTS `link` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `refid` CHAR(16) NOT NULL COLLATE utf8_bin, `orgid` CHAR(16) NOT NULL COLLATE utf8_bin, - `userid` CHAR(16) DEFAULT '' COLLATE utf8_bin, + `folderid` CHAR(16) NOT NULL COLLATE utf8_bin, + `userid` CHAR(16) NOT NULL COLLATE utf8_bin, `sourceid` CHAR(16) NOT NULL COLLATE utf8_bin, `linktype` CHAR(16) NOT NULL COLLATE utf8_bin, `documentid` CHAR(16) NOT NULL COLLATE utf8_bin, diff --git a/core/database/scripts/autobuild/db_00004.sql b/core/database/scripts/autobuild/db_00004.sql index 3872dc4b..6e4aa26a 100644 --- a/core/database/scripts/autobuild/db_00004.sql +++ b/core/database/scripts/autobuild/db_00004.sql @@ -5,7 +5,8 @@ CREATE TABLE IF NOT EXISTS `link` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `refid` CHAR(16) NOT NULL COLLATE utf8_bin, `orgid` CHAR(16) NOT NULL COLLATE utf8_bin, - `userid` CHAR(16) DEFAULT '' COLLATE utf8_bin, + `folderid` CHAR(16) NOT NULL COLLATE utf8_bin, + `userid` CHAR(16) NOT NULL COLLATE utf8_bin, `sourceid` CHAR(16) NOT NULL COLLATE utf8_bin, `linktype` CHAR(16) NOT NULL COLLATE utf8_bin, `documentid` CHAR(16) NOT NULL COLLATE utf8_bin,