mirror of
https://github.com/documize/community.git
synced 2025-07-18 20:59:43 +02:00
Allow sorting of search results and space contents
Closes #187 Sort search results and space contents by Name, Created or Revised.
This commit is contained in:
parent
0985dbf5b6
commit
1d00f8ac6e
19 changed files with 1182 additions and 807 deletions
|
@ -283,7 +283,7 @@ func (s Store) matchFullText(ctx domain.RequestContext, keywords, itemType strin
|
|||
s.id, s.c_orgid AS orgid, s.c_docid AS documentid, s.c_itemid AS itemid, s.c_itemtype AS itemtype,
|
||||
d.c_spaceid as spaceid, COALESCE(d.c_name,'Unknown') AS document, d.c_tags AS tags,
|
||||
d.c_desc AS excerpt, d.c_template AS template, d.c_versionid AS versionid,
|
||||
COALESCE(l.c_name,'Unknown') AS space
|
||||
COALESCE(l.c_name,'Unknown') AS space, d.c_created AS created, d.c_revised AS revised
|
||||
FROM
|
||||
dmz_search s,
|
||||
dmz_doc d
|
||||
|
@ -337,7 +337,7 @@ func (s Store) matchLike(ctx domain.RequestContext, keywords, itemType string) (
|
|||
sql1 := s.Bind(`SELECT
|
||||
s.id, s.c_orgid AS orgid, s.c_docid AS documentid, s.c_itemid AS itemid, s.c_itemtype AS itemtype,
|
||||
d.c_spaceid as spaceid, COALESCE(d.c_name,'Unknown') AS document, d.c_tags AS tags, d.c_desc AS excerpt,
|
||||
COALESCE(l.c_name,'Unknown') AS space
|
||||
COALESCE(l.c_name,'Unknown') AS space, d.c_created AS created, d.c_revised AS revised
|
||||
FROM
|
||||
dmz_search s,
|
||||
dmz_doc d
|
||||
|
|
1550
embed/bindata.go
1550
embed/bindata.go
File diff suppressed because one or more lines are too long
|
@ -63,5 +63,6 @@ module.exports = {
|
|||
"slug": true,
|
||||
"iziToast": true,
|
||||
"Papa": true,
|
||||
"Popper": true,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ module.exports = {
|
|||
'no-invalid-interactive': false,
|
||||
'no-nested-interactive': false,
|
||||
'no-triple-curlies': false,
|
||||
'no-global-jquery': false,
|
||||
'style-concatenation': false,
|
||||
'simple-unless': false,
|
||||
}
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
//
|
||||
// https://documize.com
|
||||
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed } from '@ember/object';
|
||||
import { A } from '@ember/array';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
localStorage: service(),
|
||||
showDeleteDialog: false,
|
||||
showMoveDialog: false,
|
||||
selectedDocuments: A([]),
|
||||
|
@ -36,9 +38,53 @@ export default Component.extend({
|
|||
let targets = _.reject(this.get('spaces'), {id: space.get('id')});
|
||||
this.set('moveOptions', A(targets));
|
||||
this.set('selectedDocuments', A([]));
|
||||
|
||||
let sortBy = this.get('localStorage').getSessionItem('space.sortBy');
|
||||
if (!_.isNull(sortBy) && !_.isUndefined(sortBy)) {
|
||||
this.send('onSetSort', sortBy);
|
||||
}
|
||||
|
||||
let sortOrder = this.get('localStorage').getSessionItem('space.sortOrder');
|
||||
if (!_.isNull(sortOrder) && !_.isUndefined(sortOrder)) {
|
||||
this.send('onSetSort', sortOrder);
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
actions: {
|
||||
onSetSort(val) {
|
||||
switch (val) {
|
||||
case 'name':
|
||||
this.set('sortBy.name', true);
|
||||
this.set('sortBy.created', false);
|
||||
this.set('sortBy.updated', false);
|
||||
break;
|
||||
case 'created':
|
||||
this.set('sortBy.name', false);
|
||||
this.set('sortBy.created', true);
|
||||
this.set('sortBy.updated', false);
|
||||
break;
|
||||
case 'updated':
|
||||
this.set('sortBy.name', false);
|
||||
this.set('sortBy.created', false);
|
||||
this.set('sortBy.updated', true);
|
||||
break;
|
||||
case 'asc':
|
||||
this.set('sortBy.asc', true);
|
||||
this.set('sortBy.desc', false);
|
||||
break;
|
||||
case 'desc':
|
||||
this.set('sortBy.asc', false);
|
||||
this.set('sortBy.desc', true);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onSortBy(attacher) {
|
||||
// attacher.hide();
|
||||
this.get('onFiltered')(this.get('documents'));
|
||||
},
|
||||
|
||||
onShowDeleteDocuments() {
|
||||
this.set('showDeleteDialog', true);
|
||||
},
|
||||
|
|
|
@ -10,13 +10,23 @@
|
|||
// https://documize.com
|
||||
|
||||
import { computed } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
localStorage: service('localStorage'),
|
||||
resultPhrase: '',
|
||||
searchQuery: computed('keywords', function() {
|
||||
return encodeURIComponent(this.get('keywords'));
|
||||
}),
|
||||
// eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects
|
||||
sortBy: {
|
||||
name: true,
|
||||
created: false,
|
||||
updated: false,
|
||||
asc: true,
|
||||
desc: false,
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
@ -34,10 +44,84 @@ export default Component.extend({
|
|||
let docLabel = duped.length === 1 ? "document" : "documents";
|
||||
let i = docs.length;
|
||||
let j = duped.length;
|
||||
phrase = `${i} ${references} across ${j} ${docLabel}`;
|
||||
phrase = `${i} ${references} in ${j} ${docLabel}`;
|
||||
}
|
||||
|
||||
this.set('resultPhrase', phrase);
|
||||
this.set('documents', duped);
|
||||
|
||||
let sortBy = this.get('localStorage').getSessionItem('search.sortBy');
|
||||
if (!_.isNull(sortBy) && !_.isUndefined(sortBy)) {
|
||||
this.send('onSetSort', sortBy);
|
||||
}
|
||||
|
||||
let sortOrder = this.get('localStorage').getSessionItem('search.sortOrder');
|
||||
if (!_.isNull(sortOrder) && !_.isUndefined(sortOrder)) {
|
||||
this.send('onSetSort', sortOrder);
|
||||
}
|
||||
|
||||
this.sortResults(duped);
|
||||
},
|
||||
|
||||
sortResults(docs) {
|
||||
let ls = this.get('localStorage');
|
||||
let sortBy = this.get('sortBy');
|
||||
|
||||
if (_.isNull(docs)) return;
|
||||
|
||||
if (sortBy.name) {
|
||||
docs = docs.sortBy('document');
|
||||
ls.storeSessionItem('search.sortBy', 'name');
|
||||
}
|
||||
if (sortBy.created) {
|
||||
docs = docs.sortBy('created');
|
||||
ls.storeSessionItem('search.sortBy', 'created');
|
||||
}
|
||||
if (sortBy.updated) {
|
||||
docs = docs.sortBy('revised');
|
||||
ls.storeSessionItem('search.sortBy', 'updated');
|
||||
}
|
||||
if (sortBy.desc) {
|
||||
docs = docs.reverseObjects();
|
||||
ls.storeSessionItem('search.sortOrder', 'desc');
|
||||
} else {
|
||||
ls.storeSessionItem('search.sortOrder', 'asc');
|
||||
}
|
||||
|
||||
this.set('documents', docs);
|
||||
},
|
||||
|
||||
actions: {
|
||||
onSetSort(val) {
|
||||
switch (val) {
|
||||
case 'name':
|
||||
this.set('sortBy.name', true);
|
||||
this.set('sortBy.created', false);
|
||||
this.set('sortBy.updated', false);
|
||||
break;
|
||||
case 'created':
|
||||
this.set('sortBy.name', false);
|
||||
this.set('sortBy.created', true);
|
||||
this.set('sortBy.updated', false);
|
||||
break;
|
||||
case 'updated':
|
||||
this.set('sortBy.name', false);
|
||||
this.set('sortBy.created', false);
|
||||
this.set('sortBy.updated', true);
|
||||
break;
|
||||
case 'asc':
|
||||
this.set('sortBy.asc', true);
|
||||
this.set('sortBy.desc', false);
|
||||
break;
|
||||
case 'desc':
|
||||
this.set('sortBy.asc', false);
|
||||
this.set('sortBy.desc', true);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onSortBy(attacher) {
|
||||
this.sortResults(this.get('documents'));
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
@ -20,10 +20,6 @@ export default Component.extend({
|
|||
keywords: '' ,
|
||||
matchFilter: null,
|
||||
|
||||
// init() {
|
||||
// this._super(...arguments);
|
||||
// },
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
this.set('keywords', this.get('filter'));
|
||||
|
|
|
@ -21,6 +21,7 @@ export default Component.extend({
|
|||
icon: '',
|
||||
color: '',
|
||||
light: false,
|
||||
outline: false,
|
||||
themed: false,
|
||||
dismiss: false,
|
||||
truncate: false,
|
||||
|
@ -48,6 +49,10 @@ export default Component.extend({
|
|||
bc += '-light';
|
||||
}
|
||||
|
||||
if (this.outline) {
|
||||
bc += '-outline';
|
||||
}
|
||||
|
||||
if (!this.uppercase) {
|
||||
bc += ' text-case-normal';
|
||||
}
|
||||
|
|
|
@ -353,6 +353,7 @@ let constants = EmberObject.extend({
|
|||
Send: 'Send',
|
||||
Share: 'Share',
|
||||
SignIn: 'Sign In',
|
||||
Sort: 'Sort',
|
||||
Unassigned: 'Unassigned',
|
||||
Update: 'Update',
|
||||
Upload: 'Upload',
|
||||
|
|
|
@ -23,6 +23,14 @@ export default Controller.extend(NotifierMixin, {
|
|||
queryParams: ['category'],
|
||||
category: '',
|
||||
filteredDocs: null,
|
||||
// eslint-disable-next-line ember/avoid-leaking-state-in-ember-objects
|
||||
sortBy: {
|
||||
name: true,
|
||||
created: false,
|
||||
updated: false,
|
||||
asc: true,
|
||||
desc: false,
|
||||
},
|
||||
|
||||
actions: {
|
||||
onRefresh() {
|
||||
|
@ -80,6 +88,30 @@ export default Controller.extend(NotifierMixin, {
|
|||
},
|
||||
|
||||
onFiltered(docs) {
|
||||
let ls = this.get('localStorage');
|
||||
let sortBy = this.get('sortBy');
|
||||
|
||||
if (_.isNull(docs)) return;
|
||||
|
||||
if (sortBy.name) {
|
||||
docs = docs.sortBy('name');
|
||||
ls.storeSessionItem('space.sortBy', 'name');
|
||||
}
|
||||
if (sortBy.created) {
|
||||
docs = docs.sortBy('created');
|
||||
ls.storeSessionItem('space.sortBy', 'created');
|
||||
}
|
||||
if (sortBy.updated) {
|
||||
docs = docs.sortBy('revised');
|
||||
ls.storeSessionItem('space.sortBy', 'updated');
|
||||
}
|
||||
if (sortBy.desc) {
|
||||
docs = docs.reverseObjects();
|
||||
ls.storeSessionItem('space.sortOrder', 'desc');
|
||||
} else {
|
||||
ls.storeSessionItem('space.sortOrder', 'asc');
|
||||
}
|
||||
|
||||
this.set('filteredDocs', docs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,13 +44,15 @@
|
|||
onRefresh=(action "onRefresh")}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{folder/documents-list
|
||||
documents=filteredDocs
|
||||
spaces=model.folders
|
||||
space=model.folder
|
||||
templates=model.templates
|
||||
permissions=model.permissions
|
||||
sortBy=sortBy
|
||||
onFiltered=(action "onFiltered")
|
||||
onExportDocument=(action "onExportDocument")
|
||||
onDeleteDocument=(action "onDeleteDocument")
|
||||
onMoveDocument=(action "onMoveDocument")}}
|
||||
|
|
|
@ -30,11 +30,6 @@ body {
|
|||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
// list-style: none;
|
||||
// list-style-type: none;
|
||||
}
|
||||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
@import "ui-button";
|
||||
@import "ui-toolbar";
|
||||
@import "ui-icon-picker";
|
||||
@import "ui-option";
|
|
@ -4,6 +4,9 @@
|
|||
@mixin button-shadow() {
|
||||
box-shadow: 1px 1px 3px 0px map-get($gray-shades, 500);
|
||||
}
|
||||
@mixin button-shadow-none() {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
%dmz-button {
|
||||
display: inline-block;
|
||||
|
@ -153,6 +156,26 @@
|
|||
background-color: map-get($gray-shades, 300);
|
||||
}
|
||||
}
|
||||
.dmz-button-gray-outline {
|
||||
@extend %dmz-button;
|
||||
background-color: transparent;
|
||||
color: map-get($gray-shades, 700);
|
||||
border: 1px solid map-get($gray-shades, 300);
|
||||
@extend .no-select;
|
||||
outline: none;
|
||||
@include button-shadow-none();
|
||||
|
||||
&:active,
|
||||
&:focus {
|
||||
outline: none;
|
||||
@include button-shadow-none();
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: map-get($gray-shades, 800);
|
||||
border-color: map-get($gray-shades, 500);
|
||||
}
|
||||
}
|
||||
|
||||
.dmz-button-theme {
|
||||
@extend %dmz-button;
|
||||
|
|
47
gui/app/styles/core/ui/ui-option.scss
Normal file
47
gui/app/styles/core/ui/ui-option.scss
Normal file
|
@ -0,0 +1,47 @@
|
|||
.ui-option-picker {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
font-size: 0;
|
||||
|
||||
> .option {
|
||||
margin: 0;
|
||||
padding: 5px 11px;
|
||||
color: map-get($gray-shades, 600);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
list-style: none;
|
||||
|
||||
|
||||
&:hover {
|
||||
> .text {
|
||||
color: map-get($yellow-shades, 800);
|
||||
}
|
||||
}
|
||||
|
||||
> .text {
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.00375rem;
|
||||
}
|
||||
}
|
||||
|
||||
> .selected {
|
||||
> .text {
|
||||
color: map-get($yellow-shades, 700) !important;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui-option-picker-horiz {
|
||||
> .option {
|
||||
display: inline-block;
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,8 +3,12 @@
|
|||
.ember-attacher-popper {
|
||||
background-color: $color-white;
|
||||
font-size: 1rem;
|
||||
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.16), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
@include border-radius(3px);
|
||||
-webkit-box-shadow: 3px 3px 33px 0 rgba(0, 0, 0, 0.16), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
box-shadow: 3px 3px 33px 0 rgba(0, 0, 0, 0.16), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
// -webkit-box-shadow: 0 20px 66px 0 rgba(34,48,73,0.2);
|
||||
// box-shadow: 0 20px 66px 0 rgba(34,48,73,0.2);
|
||||
|
||||
@include border-radius(5px);
|
||||
|
||||
> p {
|
||||
margin: 4px;
|
||||
|
@ -31,7 +35,7 @@
|
|||
|
||||
&:hover {
|
||||
color: $color-black;
|
||||
background-color: map-get($gray-shades, 100);
|
||||
background-color: map-get($yellow-shades, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,6 +88,24 @@
|
|||
}
|
||||
}
|
||||
|
||||
> .closer {
|
||||
color: map-get($gray-shades, 500);
|
||||
font-weight: 300;
|
||||
font-size: 1.7rem;
|
||||
cursor: pointer;
|
||||
padding: 5px 5px 0 0;
|
||||
display: block;
|
||||
text-align: right;
|
||||
|
||||
&:hover {
|
||||
color: map-get($gray-shades, 700);
|
||||
}
|
||||
}
|
||||
|
||||
> .container {
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
> .form {
|
||||
padding: 20px;
|
||||
width: 300px;
|
||||
|
|
|
@ -1,4 +1,59 @@
|
|||
<div class="view-space">
|
||||
|
||||
<div class="text-right">
|
||||
{{#ui/ui-button
|
||||
light=false
|
||||
outline=true
|
||||
uppercase=false
|
||||
color=constants.Color.Gray
|
||||
label=constants.Label.Sort}}
|
||||
|
||||
{{#attach-popover class="ember-attacher-popper" hideOn="click" showOn="click" isShown=false placement="bottom-end" as |attacher|}}
|
||||
<i class="dicon {{constants.Icon.Cross}} closer" {{action attacher.hide}}/>
|
||||
<div class="container">
|
||||
{{ui/ui-spacer size=100}}
|
||||
|
||||
<div class="text-center">
|
||||
<ul class="ui-option-picker ui-option-picker-horiz">
|
||||
<li class="option {{if sortBy.name "selected"}}" {{action "onSetSort" "name"}}>
|
||||
<div class="text">Name</div>
|
||||
</li>
|
||||
<li class="option {{if sortBy.created "selected"}}" {{action "onSetSort" "created"}}>
|
||||
<div class="text">Created date</div>
|
||||
</li>
|
||||
<li class="option {{if sortBy.updated "selected"}}" {{action "onSetSort" "updated"}}>
|
||||
<div class="text">Last updated</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=100}}
|
||||
|
||||
<div class="text-center">
|
||||
<ul class="ui-option-picker ui-option-picker-horiz">
|
||||
<li class="option {{if sortBy.asc "selected"}}" {{action "onSetSort" "asc"}}>
|
||||
<div class="text">Ascending</div>
|
||||
</li>
|
||||
<li class="option {{if sortBy.desc "selected"}}" {{action "onSetSort" "desc"}}>
|
||||
<div class="text">Descending</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=300}}
|
||||
|
||||
{{ui/ui-button
|
||||
light=true
|
||||
color=constants.Color.Yellow
|
||||
label=constants.Label.Sort
|
||||
onClick=(action "onSortBy" attacher)}}
|
||||
</div>
|
||||
{{/attach-popover}}
|
||||
{{/ui/ui-button}}
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=200}}
|
||||
|
||||
<ul class="documents">
|
||||
{{#each documents key="id" as |document|}}
|
||||
<li class="document {{if document.selected "selected"}}" id="document-{{document.id}}">
|
||||
|
|
|
@ -1,4 +1,61 @@
|
|||
<div class="view-search">
|
||||
|
||||
{{#if documents}}
|
||||
<div class="text-right">
|
||||
{{#ui/ui-button
|
||||
light=false
|
||||
outline=true
|
||||
uppercase=false
|
||||
color=constants.Color.Gray
|
||||
label=constants.Label.Sort}}
|
||||
|
||||
{{#attach-popover class="ember-attacher-popper" hideOn="click" showOn="click" isShown=false placement="bottom-end" as |attacher|}}
|
||||
<i class="dicon {{constants.Icon.Cross}} closer" {{action attacher.hide}}/>
|
||||
<div class="container">
|
||||
{{ui/ui-spacer size=100}}
|
||||
|
||||
<div class="text-center">
|
||||
<ul class="ui-option-picker ui-option-picker-horiz">
|
||||
<li class="option {{if sortBy.name "selected"}}" {{action "onSetSort" "name"}}>
|
||||
<div class="text">Name</div>
|
||||
</li>
|
||||
<li class="option {{if sortBy.created "selected"}}" {{action "onSetSort" "created"}}>
|
||||
<div class="text">Created date</div>
|
||||
</li>
|
||||
<li class="option {{if sortBy.updated "selected"}}" {{action "onSetSort" "updated"}}>
|
||||
<div class="text">Last updated</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=100}}
|
||||
|
||||
<div class="text-center">
|
||||
<ul class="ui-option-picker ui-option-picker-horiz">
|
||||
<li class="option {{if sortBy.asc "selected"}}" {{action "onSetSort" "asc"}}>
|
||||
<div class="text">Ascending</div>
|
||||
</li>
|
||||
<li class="option {{if sortBy.desc "selected"}}" {{action "onSetSort" "desc"}}>
|
||||
<div class="text">Descending</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=300}}
|
||||
|
||||
{{ui/ui-button
|
||||
light=true
|
||||
color=constants.Color.Yellow
|
||||
label=constants.Label.Sort
|
||||
onClick=(action "onSortBy" attacher)}}
|
||||
</div>
|
||||
{{/attach-popover}}
|
||||
{{/ui/ui-button}}
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=200}}
|
||||
{{/if}}
|
||||
|
||||
<div class="result-summary">{{resultPhrase}}</div>
|
||||
<ul class="documents">
|
||||
{{#each documents key="id" as |result|}}
|
||||
|
@ -17,4 +74,5 @@
|
|||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
</div>
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
package search
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// QueryOptions defines how we search.
|
||||
type QueryOptions struct {
|
||||
Keywords string `json:"keywords"`
|
||||
|
@ -23,18 +27,20 @@ type QueryOptions struct {
|
|||
|
||||
// QueryResult represents 'presentable' search results.
|
||||
type QueryResult struct {
|
||||
ID string `json:"id"`
|
||||
OrgID string `json:"orgId"`
|
||||
ItemID string `json:"itemId"`
|
||||
ItemType string `json:"itemType"`
|
||||
DocumentID string `json:"documentId"`
|
||||
DocumentSlug string `json:"documentSlug"`
|
||||
Document string `json:"document"`
|
||||
Excerpt string `json:"excerpt"`
|
||||
Tags string `json:"tags"`
|
||||
SpaceID string `json:"spaceId"`
|
||||
Space string `json:"space"`
|
||||
SpaceSlug string `json:"spaceSlug"`
|
||||
Template bool `json:"template"`
|
||||
VersionID string `json:"versionId"`
|
||||
ID string `json:"id"`
|
||||
OrgID string `json:"orgId"`
|
||||
ItemID string `json:"itemId"`
|
||||
ItemType string `json:"itemType"`
|
||||
DocumentID string `json:"documentId"`
|
||||
DocumentSlug string `json:"documentSlug"`
|
||||
Document string `json:"document"`
|
||||
Excerpt string `json:"excerpt"`
|
||||
Tags string `json:"tags"`
|
||||
SpaceID string `json:"spaceId"`
|
||||
Space string `json:"space"`
|
||||
SpaceSlug string `json:"spaceSlug"`
|
||||
Template bool `json:"template"`
|
||||
VersionID string `json:"versionId"`
|
||||
Created time.Time `json:"created"`
|
||||
Revised time.Time `json:"revised"`
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue