primary and secondary index fields
This commit is contained in:
parent
41bc7dbaf7
commit
e599854b14
|
@ -232,7 +232,7 @@ export const getBackendUiStore = () => {
|
|||
return state
|
||||
})
|
||||
},
|
||||
saveField: ({ originalName, field, primaryDisplay = false }) => {
|
||||
saveField: ({ originalName, field, primaryDisplay = false, indexes }) => {
|
||||
store.update(state => {
|
||||
// delete the original if renaming
|
||||
// need to handle if the column had no name, empty string
|
||||
|
@ -249,6 +249,10 @@ export const getBackendUiStore = () => {
|
|||
state.draftTable.primaryDisplay = field.name
|
||||
}
|
||||
|
||||
if (indexes) {
|
||||
state.draftTable.indexes = indexes
|
||||
}
|
||||
|
||||
state.draftTable.schema[field.name] = cloneDeep(field)
|
||||
store.actions.tables.save(state.draftTable)
|
||||
return state
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<script>
|
||||
import { Input, Button, TextButton, Select, Toggle } from "@budibase/bbui"
|
||||
import {
|
||||
Input,
|
||||
Button,
|
||||
Label,
|
||||
TextButton,
|
||||
Select,
|
||||
Toggle,
|
||||
} from "@budibase/bbui"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { TableNames, UNEDITABLE_USER_FIELDS } from "constants"
|
||||
|
@ -24,6 +31,7 @@
|
|||
let primaryDisplay =
|
||||
$backendUiStore.selectedTable.primaryDisplay == null ||
|
||||
$backendUiStore.selectedTable.primaryDisplay === field.name
|
||||
let indexes = [...($backendUiStore.selectedTable.indexes || [])]
|
||||
let confirmDeleteDialog
|
||||
let deletion
|
||||
|
||||
|
@ -41,6 +49,7 @@
|
|||
originalName,
|
||||
field,
|
||||
primaryDisplay,
|
||||
indexes,
|
||||
})
|
||||
return state
|
||||
})
|
||||
|
@ -79,8 +88,24 @@
|
|||
}
|
||||
}
|
||||
|
||||
function onChangeSearchable() {
|
||||
function onChangePrimaryIndex(e) {
|
||||
const enabled = e.target.checked
|
||||
if (enabled) {
|
||||
indexes[0] = field.name
|
||||
} else {
|
||||
indexes.shift()
|
||||
indexes = indexes
|
||||
}
|
||||
}
|
||||
|
||||
function onChangeSecondaryIndex(e) {
|
||||
const enabled = e.target.checked
|
||||
if (enabled) {
|
||||
indexes[1] = field.name
|
||||
} else {
|
||||
indexes.pop()
|
||||
indexes = indexes
|
||||
}
|
||||
}
|
||||
|
||||
function confirmDelete() {
|
||||
|
@ -124,10 +149,20 @@
|
|||
on:change={onChangePrimaryDisplay}
|
||||
thin
|
||||
text="Use as table display column" />
|
||||
|
||||
<Label gray small>Search Indexes</Label>
|
||||
<Toggle
|
||||
bind:checked={field.searchable}
|
||||
checked={indexes[0] === field.name}
|
||||
disabled={indexes[1] === field.name}
|
||||
on:change={onChangePrimaryIndex}
|
||||
thin
|
||||
text="Index for Search" />
|
||||
text="Primary" />
|
||||
<Toggle
|
||||
checked={indexes[1] === field.name}
|
||||
disabled={!indexes[0] || indexes[0] === field.name}
|
||||
on:change={onChangeSecondaryIndex}
|
||||
thin
|
||||
text="Secondary" />
|
||||
{/if}
|
||||
|
||||
{#if field.type === 'string'}
|
||||
|
|
|
@ -229,27 +229,8 @@ exports.fetchView = async function(ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
exports.createIndex = async function(ctx) {
|
||||
const appId = "app_1987903cf3604d459969c80cf17651a0"
|
||||
const db = new CouchDB(appId)
|
||||
|
||||
const indexes = await db.getIndexes()
|
||||
|
||||
// ctx.body = await db.get("_design/search_ddoc")
|
||||
ctx.body = await db.createIndex({
|
||||
index: {
|
||||
fields: ctx.request.body.fields,
|
||||
name: "other_search_index",
|
||||
ddoc: "search_ddoc",
|
||||
type: "json",
|
||||
},
|
||||
})
|
||||
// ctx.body = await db.getIndexes()
|
||||
}
|
||||
|
||||
exports.search = async function(ctx) {
|
||||
// const appId = ctx.user.appId
|
||||
const appId = "app_1987903cf3604d459969c80cf17651a0"
|
||||
const appId = ctx.user.appId
|
||||
|
||||
const db = new CouchDB(appId)
|
||||
|
||||
|
@ -260,20 +241,10 @@ exports.search = async function(ctx) {
|
|||
|
||||
query.tableId = ctx.params.tableId
|
||||
|
||||
// Paginating
|
||||
// if (cursor) {
|
||||
// if (backwards) {
|
||||
// query._id = { $lte: cursor }
|
||||
// } else {
|
||||
// query._id = { $gte: cursor }
|
||||
// }
|
||||
// }
|
||||
|
||||
const response = await db.find({
|
||||
selector: query,
|
||||
limit: pageSize,
|
||||
skip: pageSize * page,
|
||||
// sort: ["_id"],
|
||||
})
|
||||
|
||||
const rows = response.docs
|
||||
|
@ -285,7 +256,6 @@ exports.search = async function(ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
// ctx.body = response
|
||||
ctx.body = await linkRows.attachLinkInfo(appId, rows)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ const {
|
|||
generateTableID,
|
||||
generateRowID,
|
||||
} = require("../../db/utils")
|
||||
const { isEqual } = require("lodash/fp")
|
||||
|
||||
async function checkForColumnUpdates(db, oldTable, updatedTable) {
|
||||
let updatedRows
|
||||
|
@ -38,18 +39,6 @@ async function checkForColumnUpdates(db, oldTable, updatedTable) {
|
|||
return updatedRows
|
||||
}
|
||||
|
||||
async function updateSearchIndex(fields) {
|
||||
console.log("Updating stuff")
|
||||
const resp = await db.createIndex({
|
||||
index: {
|
||||
fields,
|
||||
name: "search_index",
|
||||
ddoc: "search_ddoc",
|
||||
type: "json",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
exports.fetch = async function(ctx) {
|
||||
const db = new CouchDB(ctx.user.appId)
|
||||
const body = await db.allDocs(
|
||||
|
@ -140,6 +129,46 @@ exports.save = async function(ctx) {
|
|||
const result = await db.post(tableToSave)
|
||||
tableToSave._rev = result.rev
|
||||
|
||||
// create relevant search indexes
|
||||
if (tableToSave.indexes && tableToSave.indexes.length > 0) {
|
||||
const currentIndexes = await db.getIndexes()
|
||||
const indexName = `search:${result.id}`
|
||||
|
||||
const existingIndex = currentIndexes.indexes.find(
|
||||
existing => existing.name === indexName
|
||||
)
|
||||
|
||||
if (existingIndex) {
|
||||
const currentFields = existingIndex.def.fields.map(
|
||||
field => Object.keys(field)[0]
|
||||
)
|
||||
|
||||
// if index fields have changed, delete the original index
|
||||
if (!isEqual(currentFields, tableToSave.indexes)) {
|
||||
await db.deleteIndex(existingIndex)
|
||||
// create/recreate the index with fields
|
||||
await db.createIndex({
|
||||
index: {
|
||||
fields: tableToSave.indexes,
|
||||
name: indexName,
|
||||
ddoc: "search_ddoc",
|
||||
type: "json",
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// create/recreate the index with fields
|
||||
await db.createIndex({
|
||||
index: {
|
||||
fields: tableToSave.indexes,
|
||||
name: indexName,
|
||||
ddoc: "search_ddoc",
|
||||
type: "json",
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitTable(`table:save`, appId, tableToSave)
|
||||
|
||||
|
|
|
@ -31,14 +31,9 @@ router
|
|||
usage,
|
||||
rowController.save
|
||||
)
|
||||
.post(
|
||||
"/api/createindex",
|
||||
// authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||
rowController.createIndex
|
||||
)
|
||||
.post(
|
||||
"/api/:tableId/rows/search",
|
||||
// authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||
authorized(PermissionTypes.TABLE, PermissionLevels.READ),
|
||||
rowController.search
|
||||
)
|
||||
.patch(
|
||||
|
|
|
@ -14,7 +14,15 @@ const selfhost = require("./selfhost")
|
|||
const app = new Koa()
|
||||
|
||||
// set up top level koa middleware
|
||||
app.use(koaBody({ multipart: true }))
|
||||
app.use(
|
||||
koaBody({
|
||||
multipart: true,
|
||||
formLimit: "10mb",
|
||||
jsonLimit: "10mb",
|
||||
textLimit: "10mb",
|
||||
enableTypes: ["json", "form", "text"],
|
||||
})
|
||||
)
|
||||
|
||||
app.use(
|
||||
logger({
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
<div class="root" use:styleable={$component.styles}>
|
||||
<div class="content">
|
||||
{#if logo}
|
||||
<div class="logo-container">
|
||||
<img src={logo} alt="logo" />
|
||||
</div>
|
||||
<div class="logo-container"><img src={logo} alt="logo" /></div>
|
||||
{/if}
|
||||
|
||||
{#if title}
|
||||
|
|
|
@ -28,8 +28,13 @@
|
|||
let page = 0
|
||||
|
||||
$: fetchData(table, page)
|
||||
$: searchable = [...(table.indexes || []), ...columns]
|
||||
// omit empty strings
|
||||
$: parsedSearch = Object.keys(search).reduce((acc, next) => search[next] === "" ? acc : { ...acc, [next]: search[next] }, {})
|
||||
$: parsedSearch = Object.keys(search).reduce(
|
||||
(acc, next) =>
|
||||
search[next] === "" ? acc : { ...acc, [next]: search[next] },
|
||||
{}
|
||||
)
|
||||
|
||||
async function fetchData(table, page) {
|
||||
if (!isEmpty(table)) {
|
||||
|
@ -40,8 +45,8 @@
|
|||
search: parsedSearch,
|
||||
pagination: {
|
||||
pageSize,
|
||||
page
|
||||
}
|
||||
page,
|
||||
},
|
||||
})
|
||||
}
|
||||
loaded = true
|
||||
|
|
Loading…
Reference in New Issue