1
0
Fork 0
mirror of synced 2024-10-03 10:36:59 +13:00

Ensure grid schema structure is predictable and prevent copying IDs for query datasources

This commit is contained in:
Andrew Kingston 2023-10-04 09:25:35 +01:00
parent d03fdb6df9
commit c4a516ccb3
6 changed files with 61 additions and 48 deletions

View file

@ -22,6 +22,7 @@
columns,
definition,
datasource,
schema,
} = getContext("grid")
const bannedDisplayColumnTypes = [
@ -126,16 +127,16 @@
// Generate new name
let newName = `${column.name} copy`
let attempts = 2
while ($definition.schema[newName]) {
while ($schema[newName]) {
newName = `${column.name} copy ${attempts++}`
}
// Save schema with new column
const existingColumnDefinition = $definition.schema[column.name]
const existingColumnDefinition = $schema[column.name]
await datasource.actions.saveDefinition({
...$definition,
schema: {
...$definition.schema,
...$schema,
[newName]: {
...existingColumnDefinition,
name: newName,

View file

@ -75,7 +75,9 @@
</MenuItem>
<MenuItem
icon="Copy"
disabled={isNewRow || !$focusedRow?._id}
disabled={isNewRow ||
!$focusedRow?._id ||
$focusedRow?._id?.startsWith("fake-")}
on:click={() => copyToClipboard($focusedRow?._id)}
on:click={menu.actions.close}
>

View file

@ -69,7 +69,7 @@ export const deriveStores = context => {
}
export const createActions = context => {
const { columns, stickyColumn, datasource, definition } = context
const { columns, stickyColumn, datasource, definition, schema } = context
// Updates the datasources primary display column
const changePrimaryDisplay = async column => {
@ -101,7 +101,7 @@ export const createActions = context => {
const $columns = get(columns)
const $definition = get(definition)
const $stickyColumn = get(stickyColumn)
const newSchema = cloneDeep($definition.schema)
let newSchema = cloneDeep(get(schema)) || {}
// Build new updated datasource schema
Object.keys(newSchema).forEach(column => {
@ -142,11 +142,11 @@ export const createActions = context => {
}
export const initialise = context => {
const { definition, columns, stickyColumn, schema } = context
const { definition, columns, stickyColumn, enrichedSchema } = context
// Merge new schema fields with existing schema in order to preserve widths
schema.subscribe($schema => {
if (!$schema) {
enrichedSchema.subscribe($enrichedSchema => {
if (!$enrichedSchema) {
columns.set([])
stickyColumn.set(null)
return
@ -155,13 +155,16 @@ export const initialise = context => {
// Find primary display
let primaryDisplay
if ($definition.primaryDisplay && $schema[$definition.primaryDisplay]) {
if (
$definition.primaryDisplay &&
$enrichedSchema[$definition.primaryDisplay]
) {
primaryDisplay = $definition.primaryDisplay
}
// Get field list
let fields = []
Object.keys($schema).forEach(field => {
Object.keys($enrichedSchema).forEach(field => {
if (field !== primaryDisplay) {
fields.push(field)
}
@ -172,11 +175,11 @@ export const initialise = context => {
fields
.map(field => ({
name: field,
label: $schema[field].displayName || field,
schema: $schema[field],
width: $schema[field].width || DefaultColumnWidth,
visible: $schema[field].visible ?? true,
order: $schema[field].order,
label: $enrichedSchema[field].displayName || field,
schema: $enrichedSchema[field],
width: $enrichedSchema[field].width || DefaultColumnWidth,
visible: $enrichedSchema[field].visible ?? true,
order: $enrichedSchema[field].order,
}))
.sort((a, b) => {
// Sort by order first
@ -207,9 +210,9 @@ export const initialise = context => {
}
stickyColumn.set({
name: primaryDisplay,
label: $schema[primaryDisplay].displayName || primaryDisplay,
schema: $schema[primaryDisplay],
width: $schema[primaryDisplay].width || DefaultColumnWidth,
label: $enrichedSchema[primaryDisplay].displayName || primaryDisplay,
schema: $enrichedSchema[primaryDisplay],
width: $enrichedSchema[primaryDisplay].width || DefaultColumnWidth,
visible: true,
order: 0,
left: GutterWidth,

View file

@ -12,27 +12,36 @@ export const createStores = () => {
export const deriveStores = context => {
const { definition, schemaOverrides, columnWhitelist } = context
const schema = derived(
[definition, schemaOverrides, columnWhitelist],
([$definition, $schemaOverrides, $columnWhitelist]) => {
if (!$definition?.schema) {
const schema = derived(definition, $definition => {
let schema = $definition?.schema
if (!schema) {
return null
}
// Ensure schema is configured as objects.
// Certain datasources like queries use primitives.
Object.keys(schema || {}).forEach(key => {
if (typeof schema[key] !== "object") {
schema[key] = { type: schema[key] }
}
})
return schema
})
const enrichedSchema = derived(
[schema, schemaOverrides, columnWhitelist],
([$schema, $schemaOverrides, $columnWhitelist]) => {
if (!$schema) {
return null
}
let newSchema = { ...$definition?.schema }
// Ensure schema is configured as objects.
// Certain datasources like queries use primitives.
Object.keys(newSchema).forEach(key => {
if (typeof newSchema[key] !== "object") {
newSchema[key] = { type: newSchema[key] }
}
})
let enrichedSchema = { ...$schema }
// Apply schema overrides
Object.keys($schemaOverrides || {}).forEach(field => {
if (newSchema[field]) {
newSchema[field] = {
...newSchema[field],
if (enrichedSchema[field]) {
enrichedSchema[field] = {
...enrichedSchema[field],
...$schemaOverrides[field],
}
}
@ -40,19 +49,20 @@ export const deriveStores = context => {
// Apply whitelist if specified
if ($columnWhitelist?.length) {
Object.keys(newSchema).forEach(key => {
Object.keys(enrichedSchema).forEach(key => {
if (!$columnWhitelist.includes(key)) {
delete newSchema[key]
delete enrichedSchema[key]
}
})
}
return newSchema
return enrichedSchema
}
)
return {
schema,
enrichedSchema,
}
}

View file

@ -418,7 +418,7 @@ export const createActions = context => {
// Ensure we have a unique _id.
// This means generating one for non DS+.
if (!newRow._id) {
newRow._id = Helpers.hashString(JSON.stringify(newRow))
newRow._id = `fake-${Helpers.hashString(JSON.stringify(newRow))}`
}
if (!rowCacheMap[newRow._id]) {

View file

@ -17,7 +17,7 @@ export const createStores = context => {
}
export const initialise = context => {
const { sort, initialSortColumn, initialSortOrder, definition } = context
const { sort, initialSortColumn, initialSortOrder, schema } = context
// Reset sort when initial sort props change
initialSortColumn.subscribe(newSortColumn => {
@ -28,15 +28,12 @@ export const initialise = context => {
})
// Derive if the current sort column exists in the schema
const sortColumnExists = derived(
[sort, definition],
([$sort, $definition]) => {
if (!$sort?.column || !$definition) {
return true
}
return $definition.schema?.[$sort.column] != null
const sortColumnExists = derived([sort, schema], ([$sort, $schema]) => {
if (!$sort?.column || !$schema) {
return true
}
)
return $schema[$sort.column] != null
})
// Clear sort state if our sort column does not exist
sortColumnExists.subscribe(exists => {