sending table out as datatable
This commit is contained in:
+167
-26
@@ -1,4 +1,5 @@
|
||||
import { bakeTable, bakeArray, hideRowOrColumn } from './excel'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { bakeTable, bakeArray, hideRowOrColumn, getIndiciesFromRangeAddress, send } from './excel'
|
||||
export const tableName = 'SpeckleDataTable'
|
||||
|
||||
export function checkIfReceivingDataTable(item) {
|
||||
@@ -9,7 +10,7 @@ export function checkIfReceivingDataTable(item) {
|
||||
}
|
||||
|
||||
export function formatArrayDataForTable(item, arrayData) {
|
||||
arrayData[0].push('put table metadata here eventually')
|
||||
arrayData[0].push('SpeckleColumnMetadataRow')
|
||||
for (let i = 0; i < item.columnCount; i++) {
|
||||
arrayData[0].push(JSON.stringify(item.columnMetadata[i]))
|
||||
}
|
||||
@@ -34,40 +35,166 @@ export async function bakeDataTable(item, arrayData, context, sheet, rowStart, c
|
||||
}
|
||||
// hideRowOrColumn(sheet, colStart)
|
||||
await bakeArray(arrayData.splice(0, headerRowIndex), context)
|
||||
|
||||
// set table applicationId in the top left cell
|
||||
arrayData[0][0] = `{"SpeckleTableApplicationId":"${item.applicationId}"}`
|
||||
await bakeTable(arrayData, context, sheet, name, rowStart + headerRowIndex, colStart)
|
||||
hideRowOrColumn(sheet, colStart, rowStart)
|
||||
// hideRowOrColumn(sheet, colStart, rowStart)
|
||||
}
|
||||
|
||||
export function checkIfSendingDataTable(rangeAddress, values, sheet, context) {
|
||||
console.log(rangeAddress, values, sheet, context)
|
||||
// let namedRangesInSheet = getDataTables(sheet)
|
||||
// if (!namedRangesInSheet) {
|
||||
// return false
|
||||
// }
|
||||
export async function getDataTableContainingRange(range, values, sheet, context) {
|
||||
let selectedTable = null
|
||||
sheet.tables.load('count')
|
||||
await context.sync()
|
||||
|
||||
// //check if sending range matches dataTable range
|
||||
// for (let [key, value] of namedRangesInSheet) {
|
||||
// let dataTableRange = value.getRangeOrNullObject()
|
||||
for (let i = 0; i < sheet.tables.count; i++) {
|
||||
let tableRange = sheet.tables.getItemAt(i).getRange()
|
||||
let intersectionRange = tableRange.getIntersectionOrNullObject(range)
|
||||
await context.sync()
|
||||
if (intersectionRange.isNullObject) {
|
||||
continue
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
export function getDataTables(sheet) {
|
||||
let namedRanges = new Map()
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let namedRange = sheet.names.getItemOrNullObject(`${tableName}${i}`)
|
||||
if (namedRange) {
|
||||
namedRanges.set(i, namedRange)
|
||||
range.load('columnCount, rowCount')
|
||||
intersectionRange.load('columnCount, rowCount')
|
||||
await context.sync()
|
||||
if (
|
||||
intersectionRange.columnCount >= range.columnCount &&
|
||||
intersectionRange.rowCount >= range.rowCount
|
||||
) {
|
||||
selectedTable = sheet.tables.getItemAt(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
return namedRanges
|
||||
|
||||
const isDataTable = await isSpeckleDataTable(selectedTable, sheet, context)
|
||||
if (selectedTable && isDataTable) {
|
||||
return selectedTable
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
async function isSpeckleDataTable(table, sheet, context) {
|
||||
let tableRange = table.getRange()
|
||||
tableRange.load('rowIndex, columnIndex')
|
||||
await context.sync()
|
||||
// let tableRangeAddress = tableRange.address
|
||||
// let rangeIndicies = getIndiciesFromRangeAddress(tableRangeAddress)
|
||||
// let firstCellRange = sheet.getRangeByIndexes(rangeIndicies[1], rangeIndicies[0], 1, 1)
|
||||
let firstCellRange = sheet.getRangeByIndexes(tableRange.rowIndex, tableRange.columnIndex, 1, 1)
|
||||
|
||||
firstCellRange.load('values')
|
||||
await context.sync()
|
||||
|
||||
if (firstCellRange.values[0][0].includes('SpeckleTableApplicationId')) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export async function BuildDataTableObject(sendingRange, values, table, sheet, context) {
|
||||
let metaRowIndex = await GetColumnMetadataRowIndex(table, sheet, context)
|
||||
let metaColIndex = await GetRowMetadataColumnIndex(table, context)
|
||||
|
||||
let speckleTable = new DataTable()
|
||||
sendingRange.load('rowIndex, columnIndex, rowCount, columnCount')
|
||||
await context.sync()
|
||||
|
||||
let metaRowRange = sheet.getRangeByIndexes(
|
||||
metaRowIndex,
|
||||
sendingRange.columnIndex,
|
||||
1,
|
||||
sendingRange.columnCount
|
||||
)
|
||||
let metaColumnRange = sheet.getRangeByIndexes(
|
||||
sendingRange.rowIndex,
|
||||
metaColIndex,
|
||||
sendingRange.rowCount,
|
||||
1
|
||||
)
|
||||
|
||||
metaRowRange.load('values')
|
||||
metaColumnRange.load('values')
|
||||
await context.sync()
|
||||
|
||||
for (let i = 0; i < sendingRange.columnCount; i++) {
|
||||
speckleTable.defineColumn(JSON.parse(metaRowRange.values[0][i]))
|
||||
}
|
||||
|
||||
for (let i = 0; i < sendingRange.rowCount; i++) {
|
||||
speckleTable.addRow(JSON.parse(metaColumnRange.values[i][0]), values[i])
|
||||
}
|
||||
|
||||
return speckleTable
|
||||
}
|
||||
|
||||
export async function GetColumnMetadataRowIndex(table, sheet, context) {
|
||||
let tableRange = table.getRange()
|
||||
tableRange.load('columnIndex, rowCount, rowIndex')
|
||||
await context.sync()
|
||||
|
||||
// let tableRangeAddress = tableRange.address
|
||||
// let rangeIndicies = getIndiciesFromRangeAddress(tableRangeAddress)
|
||||
// let firstCellRange = sheet.getRangeByIndexes(rangeIndicies[1], rangeIndicies[0], 1, 1)
|
||||
console.log('hey')
|
||||
let bottomRowCell = sheet.getRangeByIndexes(
|
||||
tableRange.rowIndex + tableRange.rowCount - 1,
|
||||
tableRange.columnIndex,
|
||||
1,
|
||||
1
|
||||
)
|
||||
|
||||
const extendedRange = tableRange.getExtendedRange(
|
||||
window.Excel.KeyboardDirection.up,
|
||||
bottomRowCell
|
||||
)
|
||||
extendedRange.load('columnCount, columnIndex, rowCount, rowIndex')
|
||||
await context.sync()
|
||||
|
||||
let possibleMetadataRowRange = sheet.getRangeByIndexes(
|
||||
extendedRange.rowIndex,
|
||||
extendedRange.columnIndex,
|
||||
extendedRange.rowCount - tableRange.rowCount,
|
||||
extendedRange.columnCount
|
||||
)
|
||||
|
||||
var found = possibleMetadataRowRange.findOrNullObject('SpeckleColumnMetadataRow', {
|
||||
completeMatch: false, // Match the whole cell value.
|
||||
matchCase: true, // Don't match case.
|
||||
searchDirection: window.Excel.SearchDirection.forward // Start search at the beginning of the range.
|
||||
})
|
||||
found.load('rowIndex')
|
||||
await context.sync()
|
||||
if (found.isNullObject) {
|
||||
found = possibleMetadataRowRange.findOrNullObject('speckle_type', {
|
||||
completeMatch: false, // Match the whole cell value.
|
||||
matchCase: true, // Match case.
|
||||
searchDirection: window.Excel.SearchDirection.forward // Start search at the beginning of the range.
|
||||
})
|
||||
found.load('rowIndex')
|
||||
await context.sync()
|
||||
}
|
||||
|
||||
if (found.isNullObject) {
|
||||
throw new Error('Could not find column metadata')
|
||||
}
|
||||
|
||||
return found.rowIndex
|
||||
}
|
||||
|
||||
export async function GetRowMetadataColumnIndex(table, context) {
|
||||
let tableRange = table.getRange()
|
||||
tableRange.load('columnIndex, rowCount, rowIndex')
|
||||
await context.sync()
|
||||
|
||||
return tableRange.columnIndex
|
||||
}
|
||||
|
||||
class Base {
|
||||
id
|
||||
totalChildrenCount
|
||||
applicationId
|
||||
speckle_type
|
||||
}
|
||||
|
||||
export class DataTable extends Base {
|
||||
@@ -77,10 +204,11 @@ export class DataTable extends Base {
|
||||
get rowCount() {
|
||||
return this.rowMetadata.length
|
||||
}
|
||||
// eslint-disable-next-line camelcase
|
||||
get speckle_type() {
|
||||
return 'Objects.Organization.DataTable'
|
||||
}
|
||||
headerRowIndex = 1
|
||||
headerRowIndex
|
||||
columnMetadata = []
|
||||
rowMetadata = []
|
||||
data = []
|
||||
@@ -90,13 +218,26 @@ export class DataTable extends Base {
|
||||
throw new Error(
|
||||
`object length of ${objects.length} does not match the column count, ${this.columnCount}`
|
||||
)
|
||||
let list = [metadata, ...objects]
|
||||
this.data.push(list)
|
||||
this.rowMetadata.push(metadata)
|
||||
this.data.push(objects)
|
||||
}
|
||||
|
||||
defineColumn(metadata) {
|
||||
this.columnMetadata.push(metadata)
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const jsonObj = Object.assign({}, this)
|
||||
const proto = Object.getPrototypeOf(this)
|
||||
for (const key of Object.getOwnPropertyNames(proto)) {
|
||||
const desc = Object.getOwnPropertyDescriptor(proto, key)
|
||||
const hasGetter = desc && typeof desc.get === 'function'
|
||||
if (hasGetter) {
|
||||
jsonObj[key] = this[key]
|
||||
}
|
||||
}
|
||||
return jsonObj
|
||||
}
|
||||
}
|
||||
|
||||
// export function checkIfSendingDataTable(item, arrayData) {
|
||||
|
||||
+34
-27
@@ -4,9 +4,10 @@ import store from '../store/index.js'
|
||||
import { MD5, enc } from 'crypto-js'
|
||||
import {
|
||||
checkIfReceivingDataTable,
|
||||
checkIfSendingDataTable,
|
||||
getDataTableContainingRange,
|
||||
bakeDataTable,
|
||||
formatArrayDataForTable
|
||||
formatArrayDataForTable,
|
||||
BuildDataTableObject
|
||||
// getDataTables
|
||||
} from './dataTable.js'
|
||||
|
||||
@@ -165,7 +166,9 @@ export function hideRowOrColumn(sheet, columnIndex = -1, rowIndex = -1) {
|
||||
sheet.getRange(`${columnLetter}:${columnLetter}`).columnHidden = true
|
||||
}
|
||||
if (rowIndex > -1) {
|
||||
sheet.getRange(`${rowIndex + 1}:${rowIndex + 1}`).rowHidden = true
|
||||
let rowRange = sheet.getRange(`${rowIndex + 1}:${rowIndex + 1}`)
|
||||
rowRange.rowHidden = true
|
||||
rowRange.format.wrapText = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,6 +523,7 @@ export async function bake(
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export async function send(savedStream, streamId, branchName, message) {
|
||||
try {
|
||||
await window.Excel.run(async (context) => {
|
||||
@@ -532,35 +536,38 @@ export async function send(savedStream, streamId, branchName, message) {
|
||||
await context.sync()
|
||||
let values = range.values
|
||||
|
||||
// check for specific conversion
|
||||
checkIfSendingDataTable(rangeAddress, values, sheet, context)
|
||||
|
||||
let data = []
|
||||
if (savedStream.hasHeaders) {
|
||||
for (let row = 1; row < values.length; row++) {
|
||||
let object = {}
|
||||
for (let col = 0; col < values[0].length; col++) {
|
||||
let propName = values[0][col]
|
||||
//if (propName !== 'id' && propName.endsWith('.id')) continue
|
||||
let propValue = values[row][col]
|
||||
object[propName] = propValue
|
||||
}
|
||||
// generate a hash if none is present
|
||||
object.id = object.id || MD5(JSON.stringify(object)).toString(enc.Hex)
|
||||
let unlattened = unflatten(object)
|
||||
data.push(unlattened)
|
||||
}
|
||||
// check for specific conversion
|
||||
let table = await getDataTableContainingRange(range, values, sheet, context)
|
||||
if (table) {
|
||||
data = await BuildDataTableObject(range, values, table, sheet, context)
|
||||
} else {
|
||||
for (let row = 0; row < values.length; row++) {
|
||||
let rowArray = []
|
||||
for (let col = 0; col < values[0].length; col++) {
|
||||
rowArray.push(values[row][col])
|
||||
if (savedStream.hasHeaders) {
|
||||
for (let row = 1; row < values.length; row++) {
|
||||
let object = {}
|
||||
for (let col = 0; col < values[0].length; col++) {
|
||||
let propName = values[0][col]
|
||||
//if (propName !== 'id' && propName.endsWith('.id')) continue
|
||||
let propValue = values[row][col]
|
||||
object[propName] = propValue
|
||||
}
|
||||
// generate a hash if none is present
|
||||
object.id = object.id || MD5(JSON.stringify(object)).toString(enc.Hex)
|
||||
let unlattened = unflatten(object)
|
||||
data.push(unlattened)
|
||||
}
|
||||
} else {
|
||||
for (let row = 0; row < values.length; row++) {
|
||||
let rowArray = []
|
||||
for (let col = 0; col < values[0].length; col++) {
|
||||
rowArray.push(values[row][col])
|
||||
}
|
||||
data.push(rowArray)
|
||||
}
|
||||
data.push(rowArray)
|
||||
}
|
||||
}
|
||||
|
||||
data = { data: data, speckle_type: 'Base' }
|
||||
data = { data: data, speckle_type: 'Base' }
|
||||
}
|
||||
|
||||
await store.dispatch('createCommit', {
|
||||
object: data,
|
||||
|
||||
Reference in New Issue
Block a user