@praxisui/core 8.0.0-beta.87 → 8.0.0-beta.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12106,13 +12106,36 @@ class SurfaceOpenMaterializerService {
12106
12106
  };
12107
12107
  }
12108
12108
  if (data && typeof data === 'object' && !Array.isArray(data)) {
12109
+ const objectData = data;
12110
+ if (payload.widget.id === 'praxis-dynamic-form') {
12111
+ return {
12112
+ ...payload,
12113
+ widget: {
12114
+ ...payload.widget,
12115
+ inputs: {
12116
+ ...this.projectMaterializedFormInputs(payload.widget.inputs || {}),
12117
+ configPersistenceStrategy: 'input-first',
12118
+ mode: payload.widget.inputs?.['mode'] || 'view',
12119
+ initialValue: objectData,
12120
+ resourceId,
12121
+ config: this.buildLocalFormConfig(objectData, payload.title),
12122
+ },
12123
+ },
12124
+ context: this.mergeMaterializationContext(payload, {
12125
+ readUrl,
12126
+ dataShape: 'object',
12127
+ recordCount: 1,
12128
+ presentation: 'materialized-form',
12129
+ }),
12130
+ };
12131
+ }
12109
12132
  return {
12110
12133
  ...payload,
12111
12134
  widget: {
12112
12135
  ...payload.widget,
12113
12136
  inputs: {
12114
12137
  ...(payload.widget.inputs || {}),
12115
- initialValue: data,
12138
+ initialValue: objectData,
12116
12139
  resourceId,
12117
12140
  },
12118
12141
  },
@@ -12125,6 +12148,93 @@ class SurfaceOpenMaterializerService {
12125
12148
  }
12126
12149
  return payload;
12127
12150
  }
12151
+ projectMaterializedFormInputs(inputs) {
12152
+ const supported = new Set([
12153
+ 'formId',
12154
+ 'componentInstanceId',
12155
+ 'mode',
12156
+ 'actions',
12157
+ 'enableCustomization',
12158
+ 'showAiAssistant',
12159
+ 'readonlyModeGlobal',
12160
+ 'disabledModeGlobal',
12161
+ 'presentationModeGlobal',
12162
+ 'visibleGlobal',
12163
+ 'layout',
12164
+ 'backConfig',
12165
+ 'hooks',
12166
+ 'removeEmptyContainersOnSave',
12167
+ 'reactiveValidation',
12168
+ 'reactiveValidationDebounceMs',
12169
+ 'notifyIfOutdated',
12170
+ 'snoozeMs',
12171
+ 'autoOpenSettingsOnOutdated',
12172
+ ]);
12173
+ return Object.fromEntries(Object.entries(inputs).filter(([key]) => supported.has(key)));
12174
+ }
12175
+ buildLocalFormConfig(data, title) {
12176
+ const fields = Object.entries(data)
12177
+ .filter(([key, value]) => this.shouldRenderMaterializedFormField(key, value))
12178
+ .map(([key, value]) => ({
12179
+ name: key,
12180
+ label: this.humanizeFieldName(key),
12181
+ controlType: this.inferFormControlType(value),
12182
+ readOnly: true,
12183
+ }));
12184
+ const fieldNames = fields.map((field) => field.name);
12185
+ const rows = this.chunk(fieldNames, 2).map((names, index) => ({
12186
+ id: `row-${index + 1}`,
12187
+ columns: names.map((name) => ({
12188
+ id: `col-${name}`,
12189
+ fields: [name],
12190
+ })),
12191
+ }));
12192
+ return {
12193
+ sections: [
12194
+ {
12195
+ id: 'details',
12196
+ title: title || 'Detalhes',
12197
+ rows,
12198
+ },
12199
+ ],
12200
+ fieldMetadata: fields,
12201
+ };
12202
+ }
12203
+ shouldRenderMaterializedFormField(key, value) {
12204
+ if (!key || key.startsWith('_'))
12205
+ return false;
12206
+ if (value == null)
12207
+ return true;
12208
+ return typeof value !== 'object' || value instanceof Date;
12209
+ }
12210
+ inferFormControlType(value) {
12211
+ if (typeof value === 'boolean')
12212
+ return 'checkbox';
12213
+ if (typeof value === 'number')
12214
+ return 'numericTextBox';
12215
+ if (typeof value === 'string') {
12216
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value))
12217
+ return 'dateInput';
12218
+ if (/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value))
12219
+ return 'email';
12220
+ }
12221
+ return 'input';
12222
+ }
12223
+ humanizeFieldName(key) {
12224
+ return key
12225
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
12226
+ .replace(/[_-]+/g, ' ')
12227
+ .replace(/\s+/g, ' ')
12228
+ .trim()
12229
+ .replace(/^./, (char) => char.toUpperCase());
12230
+ }
12231
+ chunk(items, size) {
12232
+ const result = [];
12233
+ for (let index = 0; index < items.length; index += size) {
12234
+ result.push(items.slice(index, index + size));
12235
+ }
12236
+ return result;
12237
+ }
12128
12238
  shouldMaterializeItemReadProjection(payload) {
12129
12239
  const surface = payload.context?.['surface'];
12130
12240
  const kind = String(surface?.['kind'] || '').toUpperCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/core",
3
- "version": "8.0.0-beta.87",
3
+ "version": "8.0.0-beta.89",
4
4
  "description": "Core library for Praxis UI Workspace: types, tokens, services and utilities shared across @praxisui/* packages.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -9003,6 +9003,12 @@ type SurfaceOpenMaterializationContext = {
9003
9003
  declare class SurfaceOpenMaterializerService {
9004
9004
  private readonly discovery;
9005
9005
  materialize(payload: SurfaceOpenPayload, context?: SurfaceOpenMaterializationContext): Promise<SurfaceOpenPayload>;
9006
+ private projectMaterializedFormInputs;
9007
+ private buildLocalFormConfig;
9008
+ private shouldRenderMaterializedFormField;
9009
+ private inferFormControlType;
9010
+ private humanizeFieldName;
9011
+ private chunk;
9006
9012
  private shouldMaterializeItemReadProjection;
9007
9013
  private resolveResponseCardinality;
9008
9014
  private shouldMaterializeAsCollection;