import { FunctionData, ObjectData, ObjectDataType, PrimitiveData, Variable, Variables, XmlError } from '@cyklang/core' import { ComponentModel, objectParameter, structure } from './cykLang' import loglevel from 'loglevel' import { Ref, ref } from 'vue' import { parseOptions } from './cykTableOptions' import { DirtyManager } from './cykReact' import { AlertException } from './cykRun' const logger = loglevel.getLogger('cykCardGrid.ts') logger.setLevel('debug') /** * */ export class CardObject { objectData: ObjectData dirtyManager: DirtyManager | undefined fields: ObjectData | undefined constructor(objectData: ObjectData, isNewRecord?: boolean) { this.objectData = objectData this.dirtyManager = new DirtyManager(objectData, isNewRecord) } } export function useCykCardGrid(props: { componentArg: ComponentModel | undefined }) { if (!props.componentArg || !props.componentArg.model || !props.componentArg.objectData) throw 'QCardGrid componentArg undefined' if (!props.componentArg.model.data) throw 'QCardGrid model.data undefined' const isLoading = ref(true); const optSelected: Ref = ref(); const queryFunct: Ref = ref(); const cardObjects: Ref = ref([]) const optionsObject = (props.componentArg?.model?.data as ObjectData); const { // eslint-disable-next-line @typescript-eslint/no-unused-vars dbResult, optEntity, optCommands, optColumns, optTableCommands, optCmds, onloadFunct, optCardModel, optRenumberRows, optStyle } = parseOptions(optionsObject, optSelected, queryFunct); const metaObject = dbResult.variables.getData('meta') as ObjectData const typeObject = metaObject.variables.getData(optEntity) if (!typeObject || typeObject === null) throw 'meta ' + optEntity + ' not found' if (typeObject.type.name !== 'type') { logger.debug('typeObject: ', typeObject) throw "meta " + optEntity + " type: " + typeObject.type.name } const objType = typeObject as ObjectDataType let dbColumns = objType.dbColumns if (!objType.dbColumns) throw 'objType.dbColumns undefined' if (dbColumns === undefined) throw 'dbColumns undefined' const rowKeyName = ref('') rowKeyName.value = dbColumns.key || '' //------------------------------------------------------------------- // function row_key_fn // returns row key const row_key_fn = (row: CardObject) => { let result = ''; const keyElts = rowKeyName.value.split(';') for (let ind = 0; ind < keyElts.length; ind++) { if (ind > 0) result += '\t' result += row.objectData.variables.getString(keyElts[ind]) } return result; }; const setOptSelected = (row: ObjectData | undefined, cmdName: string) => { if (!optSelected || optSelected.value === undefined) return; let varSelectedRow = optSelected.value?.variables.getVariable('row'); if (varSelectedRow === undefined) { varSelectedRow = optSelected.value?.variables.addVariable( 'row', optSelected.value?.scope.structure.objectDataType ); } if (row) { varSelectedRow.data = row; } let varSelectedCommand = optSelected.value?.variables.getVariable('command'); if (varSelectedCommand === undefined) { varSelectedCommand = optSelected.value?.variables.addVariable( 'command', optSelected.value.scope.structure.stringDataType ); } varSelectedCommand.data = new PrimitiveData( varSelectedCommand.dataType, cmdName ); }; /** * * @param objectData * @param isNewRecord */ const newCardObject = async (objectData: ObjectData, isNewRecord?: boolean): Promise => { try { const cardObject = new CardObject(objectData, isNewRecord) const params = new Variables() const varRow = new Variable(structure.objectDataType, objectData) if (!optCardModel) throw 'optCardModel undefined' const parameterDefinition = optCardModel.parametersDefinition?.getByOrder(0) if (!parameterDefinition) throw 'card_model function should take an object parameter' if (!parameterDefinition.dataType.isObject()) throw `card_model function parameter type should be object but is ${parameterDefinition.dataType.name}` params.push(parameterDefinition.name, varRow) const cardModel = (await optCardModel.callFunction(params, structure.scope)) as ObjectData const dataFields = cardModel.variables.getData('fields') if (!dataFields || !dataFields.type.isObject()) throw 'dataFields undefined or is not object' cardObject.fields = dataFields as ObjectData return cardObject } catch (err) { logger.error(err) throw err } } /** * */ const do_loading = async () => { try { cardObjects.value.length = 0 const dbRecordset = dbResult.variables.getData(optEntity) as ObjectData; if (dbRecordset === null) { const xmlError = new XmlError('optEntity ' + optEntity + ' not found in query result', optionsObject.tag) AlertException(xmlError) } else { for (let ind = 0; ind < dbRecordset.variables.length(); ind++) { const variable = dbRecordset.variables.at(ind)?.variable if (!variable) continue const data = variable.data; if (data === null || data === undefined) { const excep = new XmlError('recordset with an empty line', optionsObject.tag); AlertException(excep) throw excep } const record = data as ObjectData const cardObject = await newCardObject(record) cardObjects.value.push(cardObject) }; } } catch (err) { logger.error(err) } finally { isLoading.value = false } } return { isLoading, newCardObject, cardObjects, row_key_fn, optSelected, setOptSelected, optCmds, do_loading } }