import { CloseFormInstructionType, } from './WindowManager'; import { ComponentModel, useCykLang } from './cykLang' import { computed, Ref, ref, SetupContext } from 'vue'; import loglevel from 'loglevel'; import { FunctionData, ObjectData, PrimitiveData, Tag, XmlError, } from '@cyklang/core'; import { AlertException } from './cykRun'; import { Command, buildCommands, buildQColumns, buildTableCommands, calComputedCols, callCommandFunction, loadRecords } from './cykTableView'; import { parseOptions } from './cykTableOptions'; import { RowObject } from './cykTableEdit'; const logger = loglevel.getLogger('TableSelectComponent.vue'); logger.setLevel('debug'); const { structure } = useCykLang(); function showTagError(message: string, tag: Tag) { AlertException(new XmlError(message, tag)) } //------------------------------------------------------------------ // defineComponent //------------------------------------------------------------------ export function useCykTableSelect(props: { componentArg: ComponentModel | undefined }, context: SetupContext<'reload'[]>) { if ( props.componentArg === undefined || props.componentArg.model === undefined || props.componentArg.objectData === undefined ) { throw Error('TableSelect componentArg undefined'); } if ( props.componentArg.model.data === null || props.componentArg.model.data === undefined ) throw 'table-select model.data undefined'; if (props.componentArg.model.data.type.isPrimitive()) throw 'table-select model must be an object'; const isLoading = ref(true); const filter = ref(''); const rowKeyName = ref(''); const optSelected: Ref = ref(); const qColumns: any[] = []; const records: ObjectData[] = []; const rowObjects: Ref = ref([]); const commands: Command[] = []; const tableCommands: Command[] = []; const queryFunct: Ref = ref(); // logger.debug('after loadRecords') //------------------------------------------------------------------- // calculate Computed Columns //------------------------------------------------------------------- (async () => { // logger.debug('loading...'); try { //------------------------------------------------------------------- // options validation const optionsObject = (props.componentArg?.model?.data as ObjectData); const { dbResult, optEntity, optCommands, optColumns, optTableCommands, } = parseOptions(optionsObject, optSelected, queryFunct); // logger.debug('after parseOptions') //------------------------------------------------------------------- // buildQColumns const { dbColumns, columns } = await buildQColumns( 'expand', dbResult, optEntity, optColumns, optionsObject, optCommands, rowKeyName, qColumns ); // logger.debug('after buildQColumns'); //------------------------------------------------------------------- // q-table rows building loadRecords(rowObjects, dbResult, optEntity, optionsObject); //------------------------------------------------------------------- // buildCommands buildCommands(optCommands, optionsObject, commands); //------------------------------------------------------------------- // tableCommands building buildTableCommands(optTableCommands, optionsObject, tableCommands); await calComputedCols(columns, rowObjects); } catch (err) { AlertException(err) } })().finally(() => { isLoading.value = false; }); //------------------------------------------------------------------- // function row_key_fn // returns row key const row_key_fn = (row: RowObject) => { let result = ''; try { logger.debug('row', row) 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]) } } catch (err) { logger.error(err) } return result; }; //------------------------------------------------------------------- // selected computed const selected = computed({ get(): any[] { const result: any[] = []; // logger.debug('selected.get()'); return result; }, set(nval: any[]) { if (!optSelected || optSelected.value === undefined) return; if (nval.length > 1) throw 'multiple selection is not supported'; let varSelectedRow = optSelected.value?.variables.getVariable('row'); if (varSelectedRow === undefined) { varSelectedRow = optSelected.value.variables.addVariable( 'row', optSelected.value.scope.structure.objectDataType ); } varSelectedRow.data = nval[0]; // logger.debug('selected.set'); // logger.debug(nval[0]); // const closeformInstType = // optSelected.scope.lookupInstructionType('closeform'); // if (closeformInstType === undefined) // throw 'closeform instruction type not found'; }, }); const selection = 'none'; //------------------------------------------------------------------- // clickCommandButton const clickCommandButton = async ( row: RowObject | undefined, command: Command ) => { try { logger.debug( 'selected : ' + (row === undefined ? 'none' : row_key_fn(row)) ); logger.debug('command : ' + command.name); 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 ); } varSelectedRow.data = row?.objectData; 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, command.name ); if (command.function !== undefined && command.function.trim() !== '') { // command.function has been defined if (props.componentArg === undefined) throw 'props.componentArg undefined'; const reload = await callCommandFunction( command.function, (props.componentArg.model?.data as ObjectData)?.scope || optSelected.value.scope, row ); if (reload === true) { context.emit('reload') } // if (row !== undefined) { // // row command // if (Boolean(command.result)) { // // reload directive // context.emit('reload'); // } else { // // refresh the computed columns of the row // const express = new Expression(row.scope); // for (let indi = 0; indi < columns.length; indi++) { // const column = columns[indi]; // if (column.computed === undefined) continue; // const data = await express.evaluate(column.computed); // const variable = row.variables.getVariable(column.name); // if (variable !== undefined) { // variable.data = data; // } // } // } // } else if (queryFunct !== undefined) { // // table command -> reload systematique // context.emit('reload'); // } } else { // command.function undefined // close this form and return row and command selected const closeformInstType = await optSelected.value.scope.lookupInstructionType( 'closeform' ) as CloseFormInstructionType; if (closeformInstType === undefined) throw 'closeform instruction type not found'; await closeformInstType.windowManager.closeForm(); } } catch (err) { AlertException(err) } }; // logger.debug('after buildTableCommands') // row_click called when user click on a column // other than expand, avatar or qimg const row_click = (row: RowObject) => { const command = commands[0]; if (command === undefined) return; clickCommandButton(row, command); }; return { isLoading, records, rowObjects, rowKeyName, row_key_fn, qColumns, selection, selected, clickCommandButton, commands, tableCommands, filter, row_click, }; }