Browse Source

Add getResolvedRecords

data-source-schema
Artur Arseniev 5 months ago
parent
commit
fd566b195d
  1. 49
      packages/core/src/data_sources/model/DataSource.ts
  2. 2
      packages/core/src/data_sources/utils.ts
  3. 12
      packages/core/test/specs/data_sources/model/DataSource.ts

49
packages/core/src/data_sources/model/DataSource.ts

@ -38,7 +38,15 @@ import {
SetOptions,
} from '../../common';
import EditorModel from '../../editor/model/Editor';
import { DataSourceTransformers, DataSourceType, DataSourceProps, DataRecordProps } from '../types';
import {
DataFieldPrimitiveType,
DataFieldSchemaRelation,
DataRecordProps,
DataSourceProps,
DataSourceTransformers,
DataSourceType,
} from '../types';
import { DEF_DATA_FIELD_ID } from '../utils';
import DataRecord from './DataRecord';
import DataRecords from './DataRecords';
import DataSources from './DataSources';
@ -153,8 +161,8 @@ export default class DataSource<DRProps extends DataRecordProps = DataRecordProp
* @returns {DataRecord<DRProps> | undefined} The data record, or `undefined` if no record is found with the given ID.
* @name getRecord
*/
getRecord(id: string | number) {
return this.records.get(id) as DataRecord | undefined;
getRecord(id: string | number): DataRecord | undefined {
return this.records.get(id);
}
/**
@ -168,6 +176,41 @@ export default class DataSource<DRProps extends DataRecordProps = DataRecordProp
return [...this.records.models].map((record) => this.getRecord(record.id)!);
}
/**
* Retrieves all records from the data source with resolved relations based on the schema.
*/
getResolvedRecords() {
const schemaEntries = Object.entries(this.schema);
const records = this.getRecords().map((record) => {
const result = { ...record.attributes };
if (schemaEntries.length === 0) return result;
schemaEntries.forEach(([fieldName, schema]) => {
const fieldSchema = schema as DataFieldSchemaRelation;
if (fieldSchema?.type === DataFieldPrimitiveType.relation && fieldSchema.target) {
const relationValue = result[fieldName];
if (relationValue) {
const targetDs = this.em.DataSources.get(fieldSchema.target);
if (targetDs) {
const targetField = fieldSchema.targetField || DEF_DATA_FIELD_ID;
const relatedRecord = targetDs.records.find((r) => r.attributes[targetField] === relationValue);
if (relatedRecord) {
result[fieldName] = relatedRecord.attributes;
}
}
}
}
});
return result;
});
return records;
}
/**
* Removes a record from the data source by its ID.
*

2
packages/core/src/data_sources/utils.ts

@ -10,6 +10,8 @@ import { DataConditionIfFalseType, DataConditionIfTrueType } from './model/condi
import { getSymbolMain } from '../dom_components/model/SymbolUtils';
import Component from '../dom_components/model/Component';
export const DEF_DATA_FIELD_ID = 'id';
export function isDataResolverProps(value: any): value is DataResolverProps {
return typeof value === 'object' && [DataVariableType, DataConditionType].includes(value?.type);
}

12
packages/core/test/specs/data_sources/model/DataSource.ts

@ -85,17 +85,17 @@ describe('DataSource', () => {
describe('Relations', () => {
const categoryRecords = [
{ id: 'cat1', name: 'Category 1' },
{ id: 'cat2', name: 'Category 2' },
{ id: 'cat1', uid: 'cat1-uid', name: 'Category 1' },
{ id: 'cat2', uid: 'cat2-uid', name: 'Category 2' },
];
const userRecords = [
{ id: 'user1', username: 'user_one' },
{ id: 'user2', username: 'user_two' },
];
const blogRecords = [
{ id: 'blog1', title: 'First Blog', author: 'user1', categories: ['cat1'] },
{ id: 'blog1', title: 'First Blog', author: 'user1', categories: ['cat1-uid'] },
{ id: 'blog2', title: 'Second Blog', author: 'user2' },
{ id: 'blog3', title: 'Third Blog', categories: ['cat1', 'cat2'] },
{ id: 'blog3', title: 'Third Blog', categories: ['cat1-uid', 'cat2-uid'] },
];
beforeEach(() => {
@ -128,9 +128,9 @@ describe('DataSource', () => {
expect(serializeRecords(blogsDS.getRecords())).toEqual(blogRecords);
});
test('return resolved values', () => {
test('return 1:1 resolved values', () => {
const blogsDS = dsm.get('blogs');
const records = blogsDS.getRecords({ resolveRelations: true });
const records = blogsDS.getResolvedRecords();
expect(records).toEqual([
{ ...blogRecords[0], author: userRecords[0] },
{ ...blogRecords[1], author: userRecords[1] },

Loading…
Cancel
Save