Noded/frontend#75 - support searching file boxes and files from universal search
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
Garrett Mills 2021-02-04 20:41:03 -06:00
parent d8e445ba7a
commit f58fcd85b1
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
5 changed files with 86 additions and 3 deletions

View File

@ -54,6 +54,9 @@ class IonicUnit extends Unit {
const files = this.scaffold.collection('upload__File') const files = this.scaffold.collection('upload__File')
await files.createIndex({ original_name: 'text' }) await files.createIndex({ original_name: 'text' })
const boxes = this.scaffold.collection('api_files_FileBox')
await boxes.createIndex({ name: 'text' })
} }
} }

View File

@ -179,9 +179,23 @@ class FileBoxController extends Controller {
const { file_box, file } = req.form const { file_box, file } = req.form
file_box.fileIds = file_box.fileIds.filter(x => `${x}` !== `${file.id}`) file_box.fileIds = file_box.fileIds.filter(x => `${x}` !== `${file.id}`)
await file_box.save() await file_box.save()
await file.delete()
return res.api() return res.api()
} }
async get_box_history_path(req, res, next) {
const { file_box } = req.form
const history = []
let current = file_box
while ( current.parentUUID ) {
current = await current.parent()
history.push(current)
}
return res.api(await Promise.all(history.reverse().map(x => x.to_api())))
}
file_to_api(file) { file_to_api(file) {
return { return {
type: 'file', type: 'file',

View File

@ -11,7 +11,7 @@ class Misc extends Controller {
#default_token_grants = ['database'] #default_token_grants = ['database']
static get services() { static get services() {
return [...super.services, 'models'] return [...super.services, 'models', 'injector']
} }
async get_token(req, res, next) { async get_token(req, res, next) {
@ -36,6 +36,7 @@ class Misc extends Controller {
const Database = this.models.get('api:db:Database') const Database = this.models.get('api:db:Database')
const FileGroup = this.models.get('api:FileGroup') const FileGroup = this.models.get('api:FileGroup')
const File = this.models.get('upload::File') const File = this.models.get('upload::File')
const FileBox = this.models.get('api:files:FileBox')
const all_user_page_ids = (await req.user.get_accessible_pages()).map(x => x.UUID) const all_user_page_ids = (await req.user.get_accessible_pages()).map(x => x.UUID)
const results = [] const results = []
@ -125,12 +126,41 @@ class Misc extends Controller {
return self.indexOf(value) === index return self.indexOf(value) === index
} }
const matching_boxes = await FileBox.find({
active: true,
pageId: { $in: all_user_page_ids },
$text: { $search: query },
})
for ( const box of matching_boxes ) {
const page = await box.page()
results.push({
title: box.name,
short_title: `${box.name.replace(/(<([^>]+)>)/ig, '').slice(0, snip_length)}${box.name.length > snip_length ? '...' : ''}`,
type: 'file_box',
id: box.nodeId,
boxId: box.UUID,
associated: {
title: page.Name,
short_title: `${page.Name.slice(0, snip_length)}${page.Name.length > snip_length ? '...' : ''}`,
type: 'page',
id: page.UUID,
},
})
}
const all_boxes = await FileBox.find({
active: true,
pageId: { $in: all_user_page_ids },
})
const all_file_groups = await FileGroup.find({ const all_file_groups = await FileGroup.find({
PageId: { $in: all_user_page_ids }, PageId: { $in: all_user_page_ids },
}) })
let all_file_ids = [] let all_file_ids = []
const file_id_x_group = {} const file_id_x_group = {}
const file_id_x_box = {}
for ( const group of all_file_groups ) { for ( const group of all_file_groups ) {
group.FileIds.forEach(id => { group.FileIds.forEach(id => {
all_file_ids.push(id) all_file_ids.push(id)
@ -138,6 +168,13 @@ class Misc extends Controller {
}) })
} }
for ( const box of all_boxes ) {
box.fileIds.forEach(id => {
all_file_ids.push(id)
file_id_x_box[id] = box
})
}
const unique_file_ids = all_file_ids.filter(unique).map(x => File.ObjectId(x)) const unique_file_ids = all_file_ids.filter(unique).map(x => File.ObjectId(x))
const matching_files = await File.find({ const matching_files = await File.find({
@ -147,7 +184,24 @@ class Misc extends Controller {
for ( const file of matching_files ) { for ( const file of matching_files ) {
const group = file_id_x_group[file.id] const group = file_id_x_group[file.id]
if ( group ) { const box = file_id_x_box[file.id]
if ( box ) {
const page = await box.page()
results.push({
title: file.original_name,
short_title: `${file.original_name.slice(0, snip_length)}${file.original_name.length > snip_length ? '...' : ''}`,
type: `file_box-${this.injector.get('controllers').get('api:v1:FileBox.get_file_category')(file.mime_type)}`,
id: box.nodeId,
boxId: box.UUID,
associated: {
title: page.Name,
short_title: `${page.Name.slice(0, snip_length)}${page.Name.length > snip_length ? '...' : ''}`,
type: 'page',
id: page.UUID,
},
})
} else if ( group ) {
const page = await group.page const page = await group.page
results.push({ results.push({
title: file.original_name, title: file.original_name,
@ -159,7 +213,7 @@ class Misc extends Controller {
short_title: `${page.Name.slice(0, snip_length)}${page.Name.length > snip_length ? '...' : ''}`, short_title: `${page.Name.slice(0, snip_length)}${page.Name.length > snip_length ? '...' : ''}`,
type: 'page', type: 'page',
id: page.UUID, id: page.UUID,
} },
}) })
} }
} }

View File

@ -20,6 +20,13 @@ class FileBoxModel extends Model {
} }
} }
async page() {
const Page = this.models.get('api:Page')
return Page.findOne({
UUID: this.pageId,
})
}
async parent() { async parent() {
return this.constructor.findOne({ return this.constructor.findOne({
UUID: this.parentUUID, UUID: this.parentUUID,

View File

@ -10,6 +10,11 @@ module.exports = exports = {
['middleware::api:DataInjection', { access_level: 'view' }], ['middleware::api:DataInjection', { access_level: 'view' }],
'controller::api:v1:FileBox.get_box', 'controller::api:v1:FileBox.get_box',
], ],
'/:PageId/:NodeId/:FileBoxId/history': [
'middleware::auth:ApiRoute',
['middleware::api:DataInjection', { access_level: 'view' }],
'controller::api:v1:FileBox.get_box_history_path',
],
'/:PageId/:NodeId/:FileBoxId/files': [ '/:PageId/:NodeId/:FileBoxId/files': [
'middleware::auth:ApiRoute', 'middleware::auth:ApiRoute',
['middleware::api:DataInjection', { access_level: 'view' }], ['middleware::api:DataInjection', { access_level: 'view' }],