-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
Copy pathindex.ts
151 lines (138 loc) · 4.52 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/**
* This module manages data sources within the editor.
* You can initialize the module with the editor by passing an instance of `EditorModel`.
*
* ```js
* const editor = new EditorModel();
* const dsm = new DataSourceManager(editor);
* ```
*
* Once the editor is instantiated, you can use the following API to manage data sources:
*
* ```js
* const dsm = editor.DataSources;
* ```
*
* * [add](#add) - Add a new data source.
* * [get](#get) - Retrieve a data source by its ID.
* * [getAll](#getall) - Retrieve all data sources.
* * [remove](#remove) - Remove a data source by its ID.
* * [clear](#clear) - Remove all data sources.
*
* Example of adding a data source:
*
* ```js
* const ds = dsm.add({
* id: 'my_data_source_id',
* records: [
* { id: 'id1', name: 'value1' },
* { id: 'id2', name: 'value2' }
* ]
* });
* ```
*
* @module DataSources
* @param {EditorModel} em - Editor model.
*/
import { ItemManagerModule, ModuleConfig } from '../abstract/Module';
import { AddOptions, ObjectAny, RemoveOptions } from '../common';
import EditorModel from '../editor/model/Editor';
import { get, stringToPath } from '../utils/mixins';
import DataRecord from './model/DataRecord';
import DataSource from './model/DataSource';
import DataSources from './model/DataSources';
import { DataSourcesEvents, DataSourceProps } from './types';
import { Events } from 'backbone';
export default class DataSourceManager extends ItemManagerModule<ModuleConfig, DataSources> {
storageKey = '';
events = DataSourcesEvents;
destroy(): void {}
constructor(em: EditorModel) {
super(em, 'DataSources', new DataSources([], em), DataSourcesEvents);
Object.assign(this, Events); // Mixin Backbone.Events
}
/**
* Add new data source.
* @param {Object} props Data source properties.
* @returns {[DataSource]} Added data source.
* @example
* const ds = dsm.add({
* id: 'my_data_source_id',
* records: [
* { id: 'id1', name: 'value1' },
* { id: 'id2', name: 'value2' }
* ]
* });
*/
add(props: DataSourceProps, opts: AddOptions = {}) {
const { all } = this;
props.id = props.id || this._createId();
return all.add(props, opts);
}
/**
* Get data source.
* @param {String} id Data source id.
* @returns {[DataSource]} Data source.
* @example
* const ds = dsm.get('my_data_source_id');
*/
get(id: string) {
return this.all.get(id);
}
/**
* Get value from data sources by key
* @param {String} key Path to value.
* @param {any} defValue
* @returns {any}
* const value = dsm.getValue('ds_id.record_id.propName', 'defaultValue');
*/
getValue(key: string | string[], defValue: any) {
return get(this.getContext(), key, defValue);
}
private getContext() {
return this.all.reduce((acc, ds) => {
acc[ds.id] = ds.records.reduce((accR, dr, i) => {
const dataRecord = dr;
accR[i] = dataRecord.attributes;
accR[dataRecord.id || i] = dataRecord.attributes;
return accR;
}, {} as ObjectAny);
return acc;
}, {} as ObjectAny);
}
/**
* Remove data source.
* @param {String|[DataSource]} id Id of the data source.
* @returns {[DataSource]} Removed data source.
* @example
* const removed = dsm.remove('DS_ID');
*/
remove(id: string | DataSource, opts?: RemoveOptions) {
return this.__remove(id, opts);
}
/**
* Retrieve a data source, data record, and optional property path based on a string path.
* This method parses a string path to identify and retrieve the corresponding data source
* and data record. If a property path is included in the input, it will also be returned.
* The method is useful for accessing nested data within data sources.
*
* @param {String} path - The string path in the format 'dataSourceId.recordId.property'.
* @returns {[DataSource?, DataRecord?, String?]} - An array containing the data source,
* data record, and optional property path.
* @example
* const [dataSource, dataRecord, propPath] = dsm.fromPath('my_data_source_id.record_id.myProp');
* // e.g., [DataSource, DataRecord, 'myProp']
*/
fromPath(path: string) {
const result: [DataSource?, DataRecord?, string?] = [];
const [dsId, drId, ...resPath] = stringToPath(path || '');
const dataSource = this.get(dsId);
const dataRecord = dataSource?.records.get(drId);
dataSource && result.push(dataSource);
if (dataRecord) {
result.push(dataRecord);
resPath.length && result.push(resPath.join('.'));
}
return result;
}
}