sending table out as datatable

This commit is contained in:
Connor Ivy
2023-04-06 12:00:47 -05:00
parent 79d3d15e9e
commit 1a5837e28a
2 changed files with 201 additions and 53 deletions
+167 -26
View File
@@ -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
View File
@@ -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,