1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-18 20:59:43 +02:00

Specify default categories for new documents

Closes #339

All new documents will be assigned default categories.

Documents created from templates that already have categories take precedence.
This commit is contained in:
HarveyKandola 2019-11-15 14:51:52 +00:00
parent 5c1ad25dc9
commit f117e91bcb
18 changed files with 1284 additions and 1134 deletions

View file

@ -13,9 +13,9 @@ All you need to provide is PostgreSQL, Microsoft SQL Server or any MySQL variant
## Latest Release ## Latest Release
[Community Edition: v3.4.3](https://github.com/documize/community/releases) [Community Edition: v3.5.0](https://github.com/documize/community/releases)
[Enterprise Edition: v3.4.3](https://www.documize.com/downloads) [Enterprise Edition: v3.5.0](https://www.documize.com/downloads)
> *We provide frequent product updates for both cloud and self-hosted customers.* > *We provide frequent product updates for both cloud and self-hosted customers.*
> >

View file

@ -0,0 +1,7 @@
/* Community Edition */
-- Increase column sizes to support rich text data entry
ALTER TABLE dmz_org MODIFY `c_message` VARCHAR(800) NOT NULL DEFAULT '';
ALTER TABLE dmz_space MODIFY `c_desc` VARCHAR(800) NOT NULL DEFAULT '';
ALTER TABLE dmz_category MODIFY `c_name` VARCHAR(200) NOT NULL DEFAULT '';
ALTER TABLE dmz_category ADD COLUMN `c_default` BOOL NOT NULL DEFAULT 0 AFTER `c_name`;

View file

@ -0,0 +1,7 @@
/* Community Edition */
-- Increase column sizes to support rich text data entry
ALTER TABLE dmz_org ALTER COLUMN c_message TYPE VARCHAR(2000);
ALTER TABLE dmz_space ALTER COLUMN c_desc TYPE VARCHAR(2000);
ALTER TABLE dmz_category ALTER COLUMN c_name TYPE VARCHAR(200);
ALTER TABLE dmz_category ADD COLUMN c_default bool NOT NULL DEFAULT '0';

View file

@ -1,4 +1,4 @@
/* Enterprise edition */ /* Community edition */
-- Fulltext search support -- Fulltext search support
IF EXISTS (SELECT * FROM sysfulltextcatalogs ftc WHERE ftc.name = N'dmz_search_catalog') IF EXISTS (SELECT * FROM sysfulltextcatalogs ftc WHERE ftc.name = N'dmz_search_catalog')

View file

@ -0,0 +1,7 @@
/* Community edition */
-- Increase column sizes to support rich text data entry
ALTER TABLE dmz_org ALTER COLUMN c_message TYPE NVARCHAR(2000) NOT NULL DEFAULT '';
ALTER TABLE dmz_space ALTER COLUMN c_desc TYPE NVARCHAR(2000) NOT NULL DEFAULT '';
ALTER TABLE dmz_category ALTER COLUMN c_name TYPE NVARCHAR(200) NOT NULL DEFAULT '';
ALTER TABLE dmz_category ADD COLUMN c_default BIT NOT NULL DEFAULT '0';

View file

@ -545,7 +545,8 @@ func (b backerHandler) dmzCategory(files *[]backupItem) (err error) {
err = b.Runtime.Db.Select(&cat, ` err = b.Runtime.Db.Select(&cat, `
SELECT id, c_refid AS refid, SELECT id, c_refid AS refid,
c_orgid AS orgid, c_spaceid AS spaceid, c_orgid AS orgid, c_spaceid AS spaceid,
c_name AS name, c_created AS created, c_revised AS revised c_name AS name, c_default AS isdefault,
c_created AS created, c_revised AS revised
FROM dmz_category`+w) FROM dmz_category`+w)
if err != nil { if err != nil {
return errors.Wrap(err, "select.category") return errors.Wrap(err, "select.category")

View file

@ -743,9 +743,9 @@ func (r *restoreHandler) dmzCategory() (err error) {
for i := range ct { for i := range ct {
_, err = r.Context.Transaction.Exec(r.Runtime.Db.Rebind(` _, err = r.Context.Transaction.Exec(r.Runtime.Db.Rebind(`
INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_created, c_revised) INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_default, c_created, c_revised)
VALUES (?, ?, ?, ?, ?, ?)`), VALUES (?, ?, ?, ?, ?, ?, ?`),
ct[i].RefID, r.remapOrg(ct[i].OrgID), ct[i].SpaceID, ct[i].Name, ct[i].Created, ct[i].Revised) ct[i].RefID, r.remapOrg(ct[i].OrgID), ct[i].SpaceID, ct[i].Name, ct[i].IsDefault, ct[i].Created, ct[i].Revised)
if err != nil { if err != nil {
r.Context.Transaction.Rollback() r.Context.Transaction.Rollback()

View file

@ -33,8 +33,8 @@ func (s Store) Add(ctx domain.RequestContext, c category.Category) (err error) {
c.Created = time.Now().UTC() c.Created = time.Now().UTC()
c.Revised = time.Now().UTC() c.Revised = time.Now().UTC()
_, err = ctx.Transaction.Exec(s.Bind("INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_created, c_revised) VALUES (?, ?, ?, ?, ?, ?)"), _, err = ctx.Transaction.Exec(s.Bind("INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_default, c_created, c_revised) VALUES (?, ?, ?, ?, ?, ?, ?)"),
c.RefID, c.OrgID, c.SpaceID, c.Name, c.Created, c.Revised) c.RefID, c.OrgID, c.SpaceID, c.Name, c.IsDefault, c.Created, c.Revised)
if err != nil { if err != nil {
err = errors.Wrap(err, "unable to execute insert category") err = errors.Wrap(err, "unable to execute insert category")
@ -47,7 +47,7 @@ func (s Store) Add(ctx domain.RequestContext, c category.Category) (err error) {
// Context is used to for user ID. // Context is used to for user ID.
func (s Store) GetBySpace(ctx domain.RequestContext, spaceID string) (c []category.Category, err error) { func (s Store) GetBySpace(ctx domain.RequestContext, spaceID string) (c []category.Category, err error) {
err = s.Runtime.Db.Select(&c, s.Bind(` err = s.Runtime.Db.Select(&c, s.Bind(`
SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_created AS created, c_revised AS revised SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_default AS isdefault, c_created AS created, c_revised AS revised
FROM dmz_category FROM dmz_category
WHERE c_orgid=? AND c_spaceid=? AND c_refid IN WHERE c_orgid=? AND c_spaceid=? AND c_refid IN
( (
@ -77,7 +77,7 @@ func (s Store) GetAllBySpace(ctx domain.RequestContext, spaceID string) (c []cat
c = []category.Category{} c = []category.Category{}
err = s.Runtime.Db.Select(&c, s.Bind(` err = s.Runtime.Db.Select(&c, s.Bind(`
SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_created AS created, c_revised AS revised SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_default AS isdefault, c_created AS created, c_revised AS revised
FROM dmz_category FROM dmz_category
WHERE c_orgid=? AND c_spaceid=? AND c_spaceid IN WHERE c_orgid=? AND c_spaceid=? AND c_spaceid IN
( (
@ -105,7 +105,7 @@ func (s Store) GetAllBySpace(ctx domain.RequestContext, spaceID string) (c []cat
// GetByOrg returns all categories accessible by user for their org. // GetByOrg returns all categories accessible by user for their org.
func (s Store) GetByOrg(ctx domain.RequestContext, userID string) (c []category.Category, err error) { func (s Store) GetByOrg(ctx domain.RequestContext, userID string) (c []category.Category, err error) {
err = s.Runtime.Db.Select(&c, s.Bind(` err = s.Runtime.Db.Select(&c, s.Bind(`
SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_created AS created, c_revised AS revised SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_default AS isdefault, c_created AS created, c_revised AS revised
FROM dmz_category FROM dmz_category
WHERE c_orgid=? AND c_refid IN WHERE c_orgid=? AND c_refid IN
(SELECT c_refid FROM dmz_permission WHERE c_orgid=? AND c_location='category' AND c_refid IN ( (SELECT c_refid FROM dmz_permission WHERE c_orgid=? AND c_location='category' AND c_refid IN (
@ -131,7 +131,7 @@ func (s Store) GetByOrg(ctx domain.RequestContext, userID string) (c []category.
func (s Store) Update(ctx domain.RequestContext, c category.Category) (err error) { func (s Store) Update(ctx domain.RequestContext, c category.Category) (err error) {
c.Revised = time.Now().UTC() c.Revised = time.Now().UTC()
_, err = ctx.Transaction.NamedExec(s.Bind("UPDATE dmz_category SET c_name=:name, c_revised=:revised WHERE c_orgid=:orgid AND c_refid=:refid"), c) _, err = ctx.Transaction.NamedExec(s.Bind("UPDATE dmz_category SET c_name=:name, c_default=:isdefault, c_revised=:revised WHERE c_orgid=:orgid AND c_refid=:refid"), c)
if err != nil { if err != nil {
err = errors.Wrap(err, fmt.Sprintf("unable to execute update for category %s", c.RefID)) err = errors.Wrap(err, fmt.Sprintf("unable to execute update for category %s", c.RefID))
} }
@ -142,7 +142,7 @@ func (s Store) Update(ctx domain.RequestContext, c category.Category) (err error
// Get returns specified category // Get returns specified category
func (s Store) Get(ctx domain.RequestContext, id string) (c category.Category, err error) { func (s Store) Get(ctx domain.RequestContext, id string) (c category.Category, err error) {
err = s.Runtime.Db.Get(&c, s.Bind(` err = s.Runtime.Db.Get(&c, s.Bind(`
SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_created AS created, c_revised AS revised SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_default AS isdefault, c_created AS created, c_revised AS revised
FROM dmz_category FROM dmz_category
WHERE c_orgid=? AND c_refid=?`), WHERE c_orgid=? AND c_refid=?`),
ctx.OrgID, id) ctx.OrgID, id)
@ -263,7 +263,7 @@ func (s Store) GetSpaceCategorySummary(ctx domain.RequestContext, spaceID string
// GetDocumentCategoryMembership returns all space categories associated with given document. // GetDocumentCategoryMembership returns all space categories associated with given document.
func (s Store) GetDocumentCategoryMembership(ctx domain.RequestContext, documentID string) (c []category.Category, err error) { func (s Store) GetDocumentCategoryMembership(ctx domain.RequestContext, documentID string) (c []category.Category, err error) {
err = s.Runtime.Db.Select(&c, s.Bind(` err = s.Runtime.Db.Select(&c, s.Bind(`
SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_created AS created, c_revised AS revised SELECT id, c_refid AS refid, c_orgid AS orgid, c_spaceid AS spaceid, c_name AS name, c_default AS isdefault, c_created AS created, c_revised AS revised
FROM dmz_category FROM dmz_category
WHERE c_orgid=? AND c_refid IN (SELECT c_categoryid FROM dmz_category_member WHERE c_orgid=? AND c_docid=?)`), WHERE c_orgid=? AND c_refid IN (SELECT c_categoryid FROM dmz_category_member WHERE c_orgid=? AND c_docid=?)`),
ctx.OrgID, ctx.OrgID, documentID) ctx.OrgID, ctx.OrgID, documentID)

View file

@ -34,6 +34,7 @@ import (
"github.com/documize/community/model/activity" "github.com/documize/community/model/activity"
"github.com/documize/community/model/attachment" "github.com/documize/community/model/attachment"
"github.com/documize/community/model/audit" "github.com/documize/community/model/audit"
cm "github.com/documize/community/model/category"
"github.com/documize/community/model/doc" "github.com/documize/community/model/doc"
"github.com/documize/community/model/page" "github.com/documize/community/model/page"
"github.com/documize/community/model/space" "github.com/documize/community/model/space"
@ -165,7 +166,8 @@ func (h *Handler) convert(w http.ResponseWriter, r *http.Request, job, spaceID s
response.WriteJSON(w, nd) response.WriteJSON(w, nd)
} }
func processDocument(ctx domain.RequestContext, r *env.Runtime, store *store.Store, indexer indexer.Indexer, filename, job string, sp space.Space, fileResult *api.DocumentConversionResponse) (newDocument doc.Document, err error) { func processDocument(ctx domain.RequestContext, r *env.Runtime, store *store.Store, indexer indexer.Indexer, filename,
job string, sp space.Space, fileResult *api.DocumentConversionResponse) (newDocument doc.Document, err error) {
// Convert into database objects // Convert into database objects
document := convertFileResult(filename, fileResult) document := convertFileResult(filename, fileResult)
document.Job = job document.Job = job
@ -243,9 +245,30 @@ func processDocument(ctx domain.RequestContext, r *env.Runtime, store *store.Sto
da = append(da, a) da = append(da, a)
} }
// Add default categories to newly created document (if we have them).
cats, err := store.Category.GetBySpace(ctx, document.SpaceID)
if err != nil {
r.Log.Error("fetch default categories for new document", err)
}
for ic := range cats {
if cats[ic].IsDefault {
c := cm.Member{}
c.OrgID = ctx.OrgID
c.SpaceID = sp.RefID
c.RefID = uniqueid.Generate()
c.DocumentID = document.RefID
c.CategoryID = cats[ic].RefID
err = store.Category.AssociateDocument(ctx, c)
if err != nil {
r.Log.Error("apply default category to new document", err)
}
}
}
store.Activity.RecordUserActivity(ctx, activity.UserActivity{ store.Activity.RecordUserActivity(ctx, activity.UserActivity{
SpaceID: newDocument.SpaceID, SpaceID: document.SpaceID,
DocumentID: newDocument.RefID, DocumentID: document.RefID,
SourceType: activity.SourceTypeDocument, SourceType: activity.SourceTypeDocument,
ActivityType: activity.TypeCreated}) ActivityType: activity.TypeCreated})

View file

@ -204,12 +204,13 @@ func (h *Handler) processSampleData(data om.SampleData) (err error) {
h.Runtime.Log.Info(fmt.Sprintf("Installing (%d) categories", len(data.Category))) h.Runtime.Log.Info(fmt.Sprintf("Installing (%d) categories", len(data.Category)))
for i := range data.Category { for i := range data.Category {
_, err = data.Context.Transaction.Exec(h.Runtime.Db.Rebind(` _, err = data.Context.Transaction.Exec(h.Runtime.Db.Rebind(`
INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_created, c_revised) INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_default, c_created, c_revised)
VALUES (?, ?, ?, ?, ?, ?)`), VALUES (?, ?, ?, ?, ?, ?, ?)`),
h.getMappedID("category", data.Category[i].RefID), h.getMappedID("category", data.Category[i].RefID),
data.Context.OrgID, data.Context.OrgID,
h.getMappedID("space", data.Category[i].SpaceID), h.getMappedID("space", data.Category[i].SpaceID),
data.Category[i].Name, data.Category[i].Name,
data.Category[i].IsDefault,
data.Category[i].Created, data.Category[i].Created,
data.Category[i].Revised) data.Category[i].Revised)

View file

@ -34,6 +34,7 @@ import (
"github.com/documize/community/domain/store" "github.com/documize/community/domain/store"
"github.com/documize/community/model/attachment" "github.com/documize/community/model/attachment"
"github.com/documize/community/model/audit" "github.com/documize/community/model/audit"
cm "github.com/documize/community/model/category"
"github.com/documize/community/model/doc" "github.com/documize/community/model/doc"
"github.com/documize/community/model/page" "github.com/documize/community/model/page"
pm "github.com/documize/community/model/permission" pm "github.com/documize/community/model/permission"
@ -427,6 +428,30 @@ func (h *Handler) Use(w http.ResponseWriter, r *http.Request) {
} }
} }
// If document has no categories then we use
// default categories for the space.
if len(cats) == 0 {
cats, err = h.Store.Category.GetBySpace(ctx, d.SpaceID)
if err != nil {
h.Runtime.Log.Error("fetch default categories for new document", err)
}
for ic := range cats {
if cats[ic].IsDefault {
c := cm.Member{}
c.OrgID = ctx.OrgID
c.SpaceID = d.SpaceID
c.RefID = uniqueid.Generate()
c.DocumentID = d.RefID
c.CategoryID = cats[ic].RefID
err = h.Store.Category.AssociateDocument(ctx, c)
if err != nil {
h.Runtime.Log.Error("apply default category to new document", err)
}
}
}
}
ctx.Transaction.Commit() ctx.Transaction.Commit()
h.Store.Space.SetStats(ctx, d.SpaceID) h.Store.Space.SetStats(ctx, d.SpaceID)

View file

@ -56,7 +56,7 @@ func main() {
if !flagsOK { if !flagsOK {
os.Exit(0) os.Exit(0)
} }
rt.Log.Info("Configuration source: " + rt.Flags.ConfigSource) rt.Log.Info("Configuration: " + rt.Flags.ConfigSource)
// Start database init. // Start database init.
bootOK := boot.InitRuntime(&rt, &s) bootOK := boot.InitRuntime(&rt, &s)

File diff suppressed because one or more lines are too long

View file

@ -24,6 +24,7 @@ export default Component.extend(ModalMixin, Notifer, {
store: service(), store: service(),
editId: '', editId: '',
editName: '', editName: '',
editDefault: false,
deleteId: '', deleteId: '',
newCategory: '', newCategory: '',
@ -127,6 +128,7 @@ export default Component.extend(ModalMixin, Notifer, {
let cat = this.get('category').findBy('id', id); let cat = this.get('category').findBy('id', id);
this.set('editId', cat.get('id')); this.set('editId', cat.get('id'));
this.set('editName', cat.get('category')); this.set('editName', cat.get('category'));
this.set('editDefault', cat.get('isDefault'));
this.modalOpen('#category-edit-modal', {show: true}, "#edit-category-id"); this.modalOpen('#category-edit-modal', {show: true}, "#edit-category-id");
}, },
@ -155,6 +157,7 @@ export default Component.extend(ModalMixin, Notifer, {
let cat = this.get('category').findBy('id', this.get('editId')); let cat = this.get('category').findBy('id', this.get('editId'));
cat.set('category', name); cat.set('category', name);
cat.set('isDefault', this.get('editDefault'));
this.modalClose('#category-edit-modal'); this.modalClose('#category-edit-modal');
$('#edit-category-name').removeClass('is-invalid'); $('#edit-category-name').removeClass('is-invalid');

View file

@ -16,6 +16,7 @@ export default Model.extend({
orgId: attr('string'), orgId: attr('string'),
spaceId: attr('string'), spaceId: attr('string'),
category: attr('string'), category: attr('string'),
isDefault: attr('boolean'),
created: attr(), created: attr(),
revised: attr(), revised: attr(),

View file

@ -55,6 +55,11 @@
<div class="form-group"> <div class="form-group">
{{focus-input id="edit-category-name" type="text" class="form-control mousetrap" placeholder="Category name" value=editName}} {{focus-input id="edit-category-name" type="text" class="form-control mousetrap" placeholder="Category name" value=editName}}
</div> </div>
<div class="form-group">
<label>Default</label>
{{x-toggle value=editDefault size="medium" theme="light" onToggle=(action (mut editDefault))}}
<small class="form-text text-muted">Automatically aplies to newly created documents</small>
</div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
{{ui/ui-button color=constants.Color.Gray light=true label=constants.Label.Close dismiss=true}} {{ui/ui-button color=constants.Color.Gray light=true label=constants.Label.Close dismiss=true}}

View file

@ -1,6 +1,6 @@
{ {
"name": "documize", "name": "documize",
"version": "3.4.3", "version": "3.5.0",
"description": "Documize is the Integrated Document Environment (IDE)", "description": "Documize is the Integrated Document Environment (IDE)",
"repository": "", "repository": "",
"license": "AGPL", "license": "AGPL",

View file

@ -16,9 +16,10 @@ import "github.com/documize/community/model"
// Category represents a category within a space that is persisted to the database. // Category represents a category within a space that is persisted to the database.
type Category struct { type Category struct {
model.BaseEntity model.BaseEntity
OrgID string `json:"orgId"` OrgID string `json:"orgId"`
SpaceID string `json:"spaceId"` SpaceID string `json:"spaceId"`
Name string `json:"category"` Name string `json:"category"`
IsDefault bool `json:"isDefault"`
} }
// Member represents 0:M association between a document and category, persisted to the database. // Member represents 0:M association between a document and category, persisted to the database.