@airtable/blocks 1.8.0 → 1.9.0-experimental
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.
- package/CHANGELOG.md +16 -2
- package/dist/cjs/error_utils.js +17 -0
- package/dist/cjs/models/base.js +16 -5
- package/dist/cjs/models/cursor.js +2 -0
- package/dist/cjs/models/field.js +146 -27
- package/dist/cjs/models/grouped_record_query_result.js +5 -14
- package/dist/cjs/models/linked_records_query_result.js +75 -27
- package/dist/cjs/models/mutation_constants.js +3 -1
- package/dist/cjs/models/mutations.js +67 -176
- package/dist/cjs/models/query_manager.js +327 -0
- package/dist/cjs/models/record.js +308 -55
- package/dist/cjs/models/record_query_result.js +4 -1
- package/dist/cjs/models/record_store.js +554 -765
- package/dist/cjs/models/table.js +22 -13
- package/dist/cjs/models/table_or_view_query_result.js +480 -414
- package/dist/cjs/models/view_data_store.js +243 -295
- package/dist/cjs/private_utils.js +50 -0
- package/dist/cjs/sdk.js +12 -2
- package/dist/cjs/testing/{mock_airtable_interface.js → abstract_mock_airtable_interface.js} +71 -22
- package/dist/cjs/types/block_query_spec.js +85 -0
- package/dist/cjs/types/mutations.js +1 -0
- package/dist/cjs/ui/icon_config.js +4 -2
- package/dist/cjs/ui/use_global_config.js +1 -1
- package/dist/cjs/ui/use_records.js +5 -1
- package/dist/cjs/unstable_testing_utils.js +2 -2
- package/dist/cjs/watchable.js +123 -71
- package/dist/types/src/models/base.d.ts +10 -3
- package/dist/types/src/models/base.d.ts.map +1 -1
- package/dist/types/src/models/cursor.d.ts +2 -0
- package/dist/types/src/models/cursor.d.ts.map +1 -1
- package/dist/types/src/models/field.d.ts +65 -1
- package/dist/types/src/models/field.d.ts.map +1 -1
- package/dist/types/src/models/grouped_record_query_result.d.ts +3 -3
- package/dist/types/src/models/grouped_record_query_result.d.ts.map +1 -1
- package/dist/types/src/models/linked_records_query_result.d.ts.map +1 -1
- package/dist/types/src/models/mutation_constants.d.ts +1 -0
- package/dist/types/src/models/mutation_constants.d.ts.map +1 -1
- package/dist/types/src/models/mutations.d.ts.map +1 -1
- package/dist/types/src/models/query_manager.d.ts +2 -0
- package/dist/types/src/models/query_manager.d.ts.map +1 -0
- package/dist/types/src/models/record.d.ts +12 -3
- package/dist/types/src/models/record.d.ts.map +1 -1
- package/dist/types/src/models/record_query_result.d.ts +3 -2
- package/dist/types/src/models/record_query_result.d.ts.map +1 -1
- package/dist/types/src/models/record_store.d.ts.map +1 -1
- package/dist/types/src/models/table.d.ts +8 -4
- package/dist/types/src/models/table.d.ts.map +1 -1
- package/dist/types/src/models/table_or_view_query_result.d.ts +3 -5
- package/dist/types/src/models/table_or_view_query_result.d.ts.map +1 -1
- package/dist/types/src/models/view_data_store.d.ts +0 -1
- package/dist/types/src/models/view_data_store.d.ts.map +1 -1
- package/dist/types/src/models/view_metadata_query_result.d.ts +1 -1
- package/dist/types/src/models/view_metadata_query_result.d.ts.map +1 -1
- package/dist/types/src/private_utils.d.ts +30 -1
- package/dist/types/src/private_utils.d.ts.map +1 -1
- package/dist/types/src/sdk.d.ts.map +1 -1
- package/dist/types/src/testing/{mock_airtable_interface.d.ts → abstract_mock_airtable_interface.d.ts} +20 -15
- package/dist/types/src/testing/abstract_mock_airtable_interface.d.ts.map +1 -0
- package/dist/types/src/types/airtable_interface.d.ts +43 -19
- package/dist/types/src/types/airtable_interface.d.ts.map +1 -1
- package/dist/types/src/types/block_query_spec.d.ts +139 -0
- package/dist/types/src/types/block_query_spec.d.ts.map +1 -0
- package/dist/types/src/types/field.d.ts +80 -44
- package/dist/types/src/types/field.d.ts.map +1 -1
- package/dist/types/src/types/mutations.d.ts +31 -3
- package/dist/types/src/types/mutations.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +0 -2
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/types/view.d.ts +3 -8
- package/dist/types/src/types/view.d.ts.map +1 -1
- package/dist/types/src/ui/icon_config.d.ts +5 -3
- package/dist/types/src/ui/icon_config.d.ts.map +1 -1
- package/dist/types/src/ui/link.d.ts +1 -1
- package/dist/types/src/ui/link.d.ts.map +1 -1
- package/dist/types/src/ui/use_global_config.d.ts +1 -1
- package/dist/types/src/unstable_testing_utils.d.ts +1 -1
- package/dist/types/src/unstable_testing_utils.d.ts.map +1 -1
- package/dist/types/src/watchable.d.ts.map +1 -1
- package/dist/types/test/airtable_interface_mocks/fixture_data.d.ts +121 -0
- package/dist/types/test/airtable_interface_mocks/fixture_data.d.ts.map +1 -0
- package/dist/types/test/airtable_interface_mocks/linked_records.d.ts +2 -2
- package/dist/types/test/airtable_interface_mocks/linked_records.d.ts.map +1 -1
- package/dist/types/test/airtable_interface_mocks/{mock_airtable_interface_internal.d.ts → mock_airtable_interface.d.ts} +26 -18
- package/dist/types/test/airtable_interface_mocks/mock_airtable_interface.d.ts.map +1 -0
- package/dist/types/test/airtable_interface_mocks/mock_base_data_stores.d.ts +51 -0
- package/dist/types/test/airtable_interface_mocks/mock_base_data_stores.d.ts.map +1 -0
- package/dist/types/test/airtable_interface_mocks/project_tracker.d.ts +2 -2
- package/dist/types/test/airtable_interface_mocks/project_tracker.d.ts.map +1 -1
- package/dist/types/test/test_helpers.d.ts +2 -0
- package/dist/types/test/test_helpers.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/types/src/testing/mock_airtable_interface.d.ts.map +0 -1
- package/dist/types/test/airtable_interface_mocks/mock_airtable_interface_internal.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,9 +9,23 @@ Not every commit needs to result in a change to this file (e.g. docs and chore c
|
|
|
9
9
|
commit that affects the code in a way that consumers might care about should include edits to the
|
|
10
10
|
'Unreleased' section though. Breaking changes should be prefixed with `**BREAKING:**`.
|
|
11
11
|
|
|
12
|
-
## [Unreleased](https://github.com/airtable/blocks/compare/@airtable/blocks@1.
|
|
12
|
+
## [Unreleased](https://github.com/airtable/blocks/compare/@airtable/blocks@1.9.0...HEAD)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
<<<<<<< seankeenan-at-fixTypoAndFormattingFromOpenPR
|
|
15
|
+
|
|
16
|
+
- # Fix typo in cursor.ts documentation - thanks @m2creates!
|
|
17
|
+
- Add new `calendarDay` icon (and micro variant)
|
|
18
|
+
> > > > > > > main
|
|
19
|
+
|
|
20
|
+
## [1.9.0](https://github.com/airtable/blocks/compare/@airtable/blocks@1.8.0...@airtable/blocks@1.9.0) - 2021-09-15
|
|
21
|
+
|
|
22
|
+
- Update documentation for `FieldType.CHECKBOX` cell read & write types to be more accurate.
|
|
23
|
+
- Fetching field types & configs is now cached, making it more performant.
|
|
24
|
+
- Field descriptions can now be edited and specified when creating a new field:
|
|
25
|
+
- Added `field.updateDescriptionAsync`.
|
|
26
|
+
- Added optional `description` argument to `table.createFieldAsync`.
|
|
27
|
+
- Added optional `description` property to `field` objects accepted by
|
|
28
|
+
`base.createTableAsync`.
|
|
15
29
|
|
|
16
30
|
## [1.8.0](https://github.com/airtable/blocks/compare/@airtable/blocks@1.7.2...@airtable/blocks@1.8.0) - 2021-07-12
|
|
17
31
|
|
package/dist/cjs/error_utils.js
CHANGED
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
exports.spawnError = spawnError;
|
|
9
9
|
exports.invariant = invariant;
|
|
10
10
|
exports.spawnUnknownSwitchCaseError = spawnUnknownSwitchCaseError;
|
|
11
|
+
exports.spawnExhaustiveSwitchError = spawnExhaustiveSwitchError;
|
|
11
12
|
exports.spawnAbstractMethodError = spawnAbstractMethodError;
|
|
12
13
|
|
|
13
14
|
// If errorOriginFn is specified, all frames above and including the call to errorOriginFn
|
|
@@ -79,6 +80,22 @@ function spawnUnknownSwitchCaseError(valueDescription, providedValue, key) {
|
|
|
79
80
|
var providedValueKeyString = providedValueKey !== null && providedValueKey !== undefined ? providedValueKey : 'null';
|
|
80
81
|
return spawnErrorWithOriginOmittedFromStackTrace('Unknown value %s for %s', [providedValueKeyString, valueDescription], spawnUnknownSwitchCaseError);
|
|
81
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Forces TypeScript to prove that calling this function is impossible at a
|
|
85
|
+
* type level by accepting `never`. In the unlikely case this function is
|
|
86
|
+
* called we infer a useful error message.
|
|
87
|
+
*
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
function spawnExhaustiveSwitchError(impossibleValue) {
|
|
93
|
+
if (impossibleValue === null) {
|
|
94
|
+
return spawnErrorWithOriginOmittedFromStackTrace('Unexpected null in exhaustive switch', undefined, spawnExhaustiveSwitchError);
|
|
95
|
+
} else {
|
|
96
|
+
return spawnErrorWithOriginOmittedFromStackTrace("Unexpected %s in exhaustive switch", [typeof impossibleValue], spawnExhaustiveSwitchError);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
82
99
|
/**
|
|
83
100
|
* @internal
|
|
84
101
|
*/
|
package/dist/cjs/models/base.js
CHANGED
|
@@ -471,7 +471,8 @@ function (_AbstractModel) {
|
|
|
471
471
|
type: field.type
|
|
472
472
|
}, field.options ? {
|
|
473
473
|
options: field.options
|
|
474
|
-
} : null) : undefined
|
|
474
|
+
} : null) : undefined,
|
|
475
|
+
description: field.description
|
|
475
476
|
};
|
|
476
477
|
})
|
|
477
478
|
});
|
|
@@ -505,7 +506,8 @@ function (_AbstractModel) {
|
|
|
505
506
|
* Creates a new table.
|
|
506
507
|
*
|
|
507
508
|
* Throws an error if the user does not have permission to create a table, if an invalid
|
|
508
|
-
* table name is provided, or if invalid fields are provided (invalid name, type or
|
|
509
|
+
* table name is provided, or if invalid fields are provided (invalid name, type, options or
|
|
510
|
+
* description).
|
|
509
511
|
*
|
|
510
512
|
* Refer to {@link FieldType} for supported field types, the write format for field options, and
|
|
511
513
|
* other specifics for certain field types.
|
|
@@ -522,7 +524,10 @@ function (_AbstractModel) {
|
|
|
522
524
|
* table in your app.
|
|
523
525
|
*
|
|
524
526
|
* @param name name for the table. must be case-insensitive unique
|
|
525
|
-
* @param fields array of fields to create in the table: see below for
|
|
527
|
+
* @param fields array of fields to create in the table: see below for an example. `name` and
|
|
528
|
+
* `type` must be specified for all fields, while `options` is only required for fields that
|
|
529
|
+
* have field options. `description` is optional and will be `''` if not specified or if
|
|
530
|
+
* specified as `null`.
|
|
526
531
|
*
|
|
527
532
|
* @example
|
|
528
533
|
* ```js
|
|
@@ -530,7 +535,7 @@ function (_AbstractModel) {
|
|
|
530
535
|
* const name = 'My new table';
|
|
531
536
|
* const fields = [
|
|
532
537
|
* // Name will be the primary field of the table.
|
|
533
|
-
* {name: 'Name', type: FieldType.SINGLE_LINE_TEXT},
|
|
538
|
+
* {name: 'Name', type: FieldType.SINGLE_LINE_TEXT, description: 'This is the primary field'},
|
|
534
539
|
* {name: 'Notes', type: FieldType.RICH_TEXT},
|
|
535
540
|
* {name: 'Attachments', type: FieldType.MULTIPLE_ATTACHMENTS},
|
|
536
541
|
* {name: 'Number', type: FieldType.NUMBER, options: {
|
|
@@ -566,13 +571,19 @@ function (_AbstractModel) {
|
|
|
566
571
|
type: _mutations.MutationTypes.CREATE_SINGLE_TABLE,
|
|
567
572
|
name,
|
|
568
573
|
fields: fields.map(field => {
|
|
574
|
+
var _field$description;
|
|
575
|
+
|
|
569
576
|
return {
|
|
570
577
|
name: field.name,
|
|
571
578
|
config: _objectSpread({
|
|
572
579
|
type: field.type
|
|
573
580
|
}, field.options ? {
|
|
574
581
|
options: field.options
|
|
575
|
-
} : null)
|
|
582
|
+
} : null),
|
|
583
|
+
// Coerce undefined to null so that only old SDKs pass "undefined" for description
|
|
584
|
+
// '' is permitted, as we already set empty descriptions to '' when editing descriptions
|
|
585
|
+
// from the UI
|
|
586
|
+
description: (_field$description = field.description) !== null && _field$description !== void 0 ? _field$description : null
|
|
576
587
|
};
|
|
577
588
|
})
|
|
578
589
|
}));
|
|
@@ -89,6 +89,7 @@ var WatchableCursorKeys = Object.freeze({
|
|
|
89
89
|
* return (
|
|
90
90
|
* <div>
|
|
91
91
|
* Active table: {cursor.activeTableId}
|
|
92
|
+
* <br />
|
|
92
93
|
* Active view: {cursor.activeViewId}
|
|
93
94
|
* </div>
|
|
94
95
|
* );
|
|
@@ -109,6 +110,7 @@ var WatchableCursorKeys = Object.freeze({
|
|
|
109
110
|
* return (
|
|
110
111
|
* <div>
|
|
111
112
|
* Selected records: {cursor.selectedRecordIds.join(', ')}
|
|
113
|
+
* <br />
|
|
112
114
|
* Selected fields: {cursor.selectedFieldIds.join(', ')}
|
|
113
115
|
* </div>
|
|
114
116
|
* );
|
package/dist/cjs/models/field.js
CHANGED
|
@@ -109,7 +109,9 @@ function (_AbstractModel) {
|
|
|
109
109
|
(0, _classCallCheck2.default)(this, Field);
|
|
110
110
|
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Field).call(this, sdk, fieldId));
|
|
111
111
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_parentTable", void 0);
|
|
112
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_cachedFieldTypeConfigOrNull", void 0);
|
|
112
113
|
_this._parentTable = parentTable;
|
|
114
|
+
_this._cachedFieldTypeConfigOrNull = null;
|
|
113
115
|
return _this;
|
|
114
116
|
}
|
|
115
117
|
/**
|
|
@@ -118,6 +120,42 @@ function (_AbstractModel) {
|
|
|
118
120
|
|
|
119
121
|
|
|
120
122
|
(0, _createClass2.default)(Field, [{
|
|
123
|
+
key: "_getCachedConfigFromFieldTypeProvider",
|
|
124
|
+
// We use a cached response from FieldTypeProvider because getting the config can
|
|
125
|
+
// be an expensive operation. In particular when fieldConfigs are extremely large
|
|
126
|
+
// (eg: Select fields with lots of select options)
|
|
127
|
+
value: function _getCachedConfigFromFieldTypeProvider() {
|
|
128
|
+
if (this._cachedFieldTypeConfigOrNull !== null) {
|
|
129
|
+
return this._cachedFieldTypeConfigOrNull;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
var airtableInterface = this._sdk.__airtableInterface;
|
|
133
|
+
var appInterface = this._sdk.__appInterface;
|
|
134
|
+
this._cachedFieldTypeConfigOrNull = airtableInterface.fieldTypeProvider.getConfig(appInterface, this._data, this.parentTable.__getFieldNamesById());
|
|
135
|
+
return this._cachedFieldTypeConfigOrNull;
|
|
136
|
+
}
|
|
137
|
+
}, {
|
|
138
|
+
key: "_clearCachedConfig",
|
|
139
|
+
value: function _clearCachedConfig() {
|
|
140
|
+
this._cachedFieldTypeConfigOrNull = null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The type and options of the field to make type narrowing `FieldOptions` easier.
|
|
144
|
+
*
|
|
145
|
+
* @see {@link FieldConfig}
|
|
146
|
+
* @example
|
|
147
|
+
* const fieldConfig = field.config;
|
|
148
|
+
* if (fieldConfig.type === FieldType.SINGLE_SELECT) {
|
|
149
|
+
* return fieldConfig.options.choices;
|
|
150
|
+
* } else if (fieldConfig.type === FieldType.MULTIPLE_LOOKUP_VALUES && fieldConfig.options.isValid) {
|
|
151
|
+
* if (fieldConfig.options.result.type === FieldType.SINGLE_SELECT) {
|
|
152
|
+
* return fieldConfig.options.result.options.choices;
|
|
153
|
+
* }
|
|
154
|
+
* }
|
|
155
|
+
* return DEFAULT_CHOICES;
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
}, {
|
|
121
159
|
key: "checkPermissionsForUpdateOptions",
|
|
122
160
|
|
|
123
161
|
/**
|
|
@@ -125,7 +163,7 @@ function (_AbstractModel) {
|
|
|
125
163
|
*
|
|
126
164
|
* Accepts partial input, in the same format as {@link updateOptionsAsync}.
|
|
127
165
|
*
|
|
128
|
-
* Returns `{hasPermission: true}` if the current user can update the specified
|
|
166
|
+
* Returns `{hasPermission: true}` if the current user can update the specified field,
|
|
129
167
|
* `{hasPermission: false, reasonDisplayString: string}` otherwise. `reasonDisplayString` may be
|
|
130
168
|
* used to display an error message to the user.
|
|
131
169
|
*
|
|
@@ -241,6 +279,104 @@ function (_AbstractModel) {
|
|
|
241
279
|
}
|
|
242
280
|
}, null, this);
|
|
243
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Checks whether the current user has permission to perform the given description update.
|
|
284
|
+
*
|
|
285
|
+
* Accepts partial input, in the same format as {@link updateDescriptionAsync}.
|
|
286
|
+
*
|
|
287
|
+
* Returns `{hasPermission: true}` if the current user can update the specified field,
|
|
288
|
+
* `{hasPermission: false, reasonDisplayString: string}` otherwise. `reasonDisplayString` may be
|
|
289
|
+
* used to display an error message to the user.
|
|
290
|
+
*
|
|
291
|
+
* @param description new description for the field
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```js
|
|
295
|
+
* const updateFieldCheckResult = field.checkPermissionsForUpdateDescription();
|
|
296
|
+
*
|
|
297
|
+
* if (!updateFieldCheckResult.hasPermission) {
|
|
298
|
+
* alert(updateFieldCheckResult.reasonDisplayString);
|
|
299
|
+
* }
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
|
|
303
|
+
}, {
|
|
304
|
+
key: "checkPermissionsForUpdateDescription",
|
|
305
|
+
value: function checkPermissionsForUpdateDescription(description) {
|
|
306
|
+
return this._sdk.__mutations.checkPermissionsForMutation({
|
|
307
|
+
type: _mutations.MutationTypes.UPDATE_SINGLE_FIELD_DESCRIPTION,
|
|
308
|
+
tableId: this.parentTable.id,
|
|
309
|
+
id: this.id,
|
|
310
|
+
description
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* An alias for `checkPermissionsForUpdateDescription(options).hasPermission`.
|
|
315
|
+
*
|
|
316
|
+
* Checks whether the current user has permission to perform the description update.
|
|
317
|
+
*
|
|
318
|
+
* Accepts partial input, in the same format as {@link updateDescriptionAsync}.
|
|
319
|
+
*
|
|
320
|
+
* @param description new description for the field
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* ```js
|
|
324
|
+
* const canUpdateField = field.hasPermissionToUpdateDescription();
|
|
325
|
+
*
|
|
326
|
+
* if (!canUpdateField) {
|
|
327
|
+
* alert('not allowed!');
|
|
328
|
+
* }
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
|
|
332
|
+
}, {
|
|
333
|
+
key: "hasPermissionToUpdateDescription",
|
|
334
|
+
value: function hasPermissionToUpdateDescription(description) {
|
|
335
|
+
return this.checkPermissionsForUpdateDescription(description).hasPermission;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Updates the description for this field.
|
|
339
|
+
*
|
|
340
|
+
* To remove an existing description, pass `''` as the new description.
|
|
341
|
+
* `null` is also accepted and will be coerced to `''` for consistency with field creation.
|
|
342
|
+
*
|
|
343
|
+
* Throws an error if the user does not have permission to update the field, or if an invalid
|
|
344
|
+
* description is provided.
|
|
345
|
+
*
|
|
346
|
+
* This action is asynchronous. Unlike updates to cell values, updates to field descriptions are
|
|
347
|
+
* **not** applied optimistically locally. You must `await` the returned promise before
|
|
348
|
+
* relying on the change in your app.
|
|
349
|
+
*
|
|
350
|
+
* @param description new description for the field
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```js
|
|
354
|
+
* await myTextField.updateDescriptionAsync('This is a text field');
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
|
|
358
|
+
}, {
|
|
359
|
+
key: "updateDescriptionAsync",
|
|
360
|
+
value: function updateDescriptionAsync(description) {
|
|
361
|
+
return _regenerator.default.async(function updateDescriptionAsync$(_context2) {
|
|
362
|
+
while (1) {
|
|
363
|
+
switch (_context2.prev = _context2.next) {
|
|
364
|
+
case 0:
|
|
365
|
+
_context2.next = 2;
|
|
366
|
+
return _regenerator.default.awrap(this._sdk.__mutations.applyMutationAsync({
|
|
367
|
+
type: _mutations.MutationTypes.UPDATE_SINGLE_FIELD_DESCRIPTION,
|
|
368
|
+
tableId: this.parentTable.id,
|
|
369
|
+
id: this.id,
|
|
370
|
+
description
|
|
371
|
+
}));
|
|
372
|
+
|
|
373
|
+
case 2:
|
|
374
|
+
case "end":
|
|
375
|
+
return _context2.stop();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}, null, this);
|
|
379
|
+
}
|
|
244
380
|
/**
|
|
245
381
|
* `true` if this field is computed, `false` otherwise. A field is
|
|
246
382
|
* "computed" if it's value is not set by user input (e.g. autoNumber, formula,
|
|
@@ -329,6 +465,9 @@ function (_AbstractModel) {
|
|
|
329
465
|
}, {
|
|
330
466
|
key: "__triggerOnChangeForDirtyPaths",
|
|
331
467
|
value: function __triggerOnChangeForDirtyPaths(dirtyPaths) {
|
|
468
|
+
// Always clear the cached config when anything on the field data model changes
|
|
469
|
+
this._clearCachedConfig();
|
|
470
|
+
|
|
332
471
|
if (dirtyPaths.name) {
|
|
333
472
|
this._onChange(WatchableFieldKeys.name);
|
|
334
473
|
}
|
|
@@ -402,11 +541,8 @@ function (_AbstractModel) {
|
|
|
402
541
|
}, {
|
|
403
542
|
key: "type",
|
|
404
543
|
get: function get() {
|
|
405
|
-
var
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
var _airtableInterface$fi = airtableInterface.fieldTypeProvider.getConfig(appInterface, this._data, this.parentTable.__getFieldNamesById()),
|
|
409
|
-
type = _airtableInterface$fi.type; // We intend to switch from "lookup" to "multipleLookupValues", but need to support both
|
|
544
|
+
var _this$_getCachedConfi = this._getCachedConfigFromFieldTypeProvider(),
|
|
545
|
+
type = _this$_getCachedConfi.type; // We intend to switch from "lookup" to "multipleLookupValues", but need to support both
|
|
410
546
|
// until the transition is complete. See <https://airtable.quip.com/VxaMAmAfUscs> for more.
|
|
411
547
|
// @ts-ignore
|
|
412
548
|
|
|
@@ -437,31 +573,14 @@ function (_AbstractModel) {
|
|
|
437
573
|
}, {
|
|
438
574
|
key: "options",
|
|
439
575
|
get: function get() {
|
|
440
|
-
var
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
options = _airtableInterface$fi2.options; // TODO(emma): can we remove this cloneDeep?
|
|
576
|
+
var _this$_getCachedConfi2 = this._getCachedConfigFromFieldTypeProvider(),
|
|
577
|
+
options = _this$_getCachedConfi2.options; // TODO: In the next breaking release freeze (inside of the cache) and replace
|
|
578
|
+
// FieldOptions with readonly<FieldOptions>.
|
|
579
|
+
// Today this is required because we re-use the fieldTypeProvider.getConfig response.
|
|
445
580
|
|
|
446
581
|
|
|
447
582
|
return options ? (0, _private_utils.cloneDeep)(options) : null;
|
|
448
583
|
}
|
|
449
|
-
/**
|
|
450
|
-
* The type and options of the field to make type narrowing `FieldOptions` easier.
|
|
451
|
-
*
|
|
452
|
-
* @see {@link FieldConfig}
|
|
453
|
-
* @example
|
|
454
|
-
* const fieldConfig = field.config;
|
|
455
|
-
* if (fieldConfig.type === FieldType.SINGLE_SELECT) {
|
|
456
|
-
* return fieldConfig.options.choices;
|
|
457
|
-
* } else if (fieldConfig.type === FieldType.MULTIPLE_LOOKUP_VALUES && fieldConfig.options.isValid) {
|
|
458
|
-
* if (fieldConfig.options.result.type === FieldType.SINGLE_SELECT) {
|
|
459
|
-
* return fieldConfig.options.result.options.choices;
|
|
460
|
-
* }
|
|
461
|
-
* }
|
|
462
|
-
* return DEFAULT_CHOICES;
|
|
463
|
-
*/
|
|
464
|
-
|
|
465
584
|
}, {
|
|
466
585
|
key: "config",
|
|
467
586
|
get: function get() {
|
|
@@ -245,19 +245,13 @@ function (_RecordQueryResult) {
|
|
|
245
245
|
while (1) {
|
|
246
246
|
switch (_context2.prev = _context2.next) {
|
|
247
247
|
case 0:
|
|
248
|
-
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
// watching recordIds only changes if records in this group change.
|
|
252
|
-
// In the meantime this does ensure that a deleted GroupedRecordQuery with stale recordIds
|
|
253
|
-
// doesn't return the cached array.
|
|
248
|
+
// TODO: This entire class assumes it is torn down and re-created by the parent whenever
|
|
249
|
+
// a change to the group is made.
|
|
250
|
+
this._parentQueryResult.__groupedRecordQueryResultPool.registerObjectForReuseStrong(this);
|
|
254
251
|
|
|
255
|
-
|
|
256
|
-
this.watch(['recordIds', 'groups', 'groupLevels'], this._invalidateComputedRecordIds, this);
|
|
257
|
-
this.watch(['recordIds'], this._invalidateRecordIdsSet, this);
|
|
258
252
|
return _context2.abrupt("return", this._getChangedKeysOnLoad());
|
|
259
253
|
|
|
260
|
-
case
|
|
254
|
+
case 2:
|
|
261
255
|
case "end":
|
|
262
256
|
return _context2.stop();
|
|
263
257
|
}
|
|
@@ -269,10 +263,7 @@ function (_RecordQueryResult) {
|
|
|
269
263
|
}, {
|
|
270
264
|
key: "_unloadData",
|
|
271
265
|
value: function _unloadData() {
|
|
272
|
-
//
|
|
273
|
-
this.unwatch(['recordIds', 'groups', 'groupLevels'], this._invalidateComputedRecordIds, this);
|
|
274
|
-
this.unwatch(['recordIds'], this._invalidateRecordIdsSet, this); // Invalidate both of the caches, as this object can no longer be accessed
|
|
275
|
-
|
|
266
|
+
// Invalidate both of the caches, as this object can no longer be accessed
|
|
276
267
|
this._invalidateComputedRecordIds();
|
|
277
268
|
|
|
278
269
|
this._invalidateRecordIdsSet();
|
|
@@ -29,6 +29,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
29
29
|
});
|
|
30
30
|
exports.default = exports.getLinkedTableId = void 0;
|
|
31
31
|
|
|
32
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
33
|
+
|
|
32
34
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
33
35
|
|
|
34
36
|
require("regenerator-runtime/runtime");
|
|
@@ -53,8 +55,12 @@ var _field = require("../types/field");
|
|
|
53
55
|
|
|
54
56
|
var _error_utils = require("../error_utils");
|
|
55
57
|
|
|
58
|
+
var _block_query_spec = require("../types/block_query_spec");
|
|
59
|
+
|
|
56
60
|
var _record_query_result = _interopRequireDefault(require("./record_query_result"));
|
|
57
61
|
|
|
62
|
+
var _record_store = require("./record_store");
|
|
63
|
+
|
|
58
64
|
/** @module @airtable/blocks/models: RecordQueryResult */
|
|
59
65
|
|
|
60
66
|
/** */
|
|
@@ -118,6 +124,8 @@ function (_RecordQueryResult) {
|
|
|
118
124
|
|
|
119
125
|
/** @internal */
|
|
120
126
|
|
|
127
|
+
/** @internal */
|
|
128
|
+
|
|
121
129
|
/** @internal */
|
|
122
130
|
function LinkedRecordsQueryResult(record, field, normalizedOpts, sdk) {
|
|
123
131
|
var _this;
|
|
@@ -134,6 +142,7 @@ function (_RecordQueryResult) {
|
|
|
134
142
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_computedRecordIdsSet", null);
|
|
135
143
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_computedFilteredSortedRecordIds", null);
|
|
136
144
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_cellValueChangeHandlerByFieldId", {});
|
|
145
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_recordStoreQueryId", null);
|
|
137
146
|
(0, _error_utils.invariant)(record.parentTable === field.parentTable, 'record and field must belong to the same table');
|
|
138
147
|
_this._record = record;
|
|
139
148
|
_this._field = field;
|
|
@@ -279,7 +288,7 @@ function (_RecordQueryResult) {
|
|
|
279
288
|
}, {
|
|
280
289
|
key: "_loadDataAsync",
|
|
281
290
|
value: function _loadDataAsync() {
|
|
282
|
-
var initiallyLoaded, changedKeys, fieldIds, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, fieldId;
|
|
291
|
+
var initiallyLoaded, _ref, _ref2, recordStoreQueryId, changedKeys, fieldIds, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, fieldId;
|
|
283
292
|
|
|
284
293
|
return _regenerator.default.async(function _loadDataAsync$(_context2) {
|
|
285
294
|
while (1) {
|
|
@@ -291,11 +300,21 @@ function (_RecordQueryResult) {
|
|
|
291
300
|
|
|
292
301
|
this._watchLinkedQueryResult();
|
|
293
302
|
|
|
294
|
-
initiallyLoaded = this._linkedQueryResult.isDataLoaded;
|
|
303
|
+
initiallyLoaded = this._linkedQueryResult.isDataLoaded; // https://airtable.com/appahuJQw7qfQTBBU/tblSbpimM8Spp9txp/viweAFIus3MhU9Gxa/recNjFYJpeV23LPhH?blocks=hide
|
|
304
|
+
// TODO: (#proj-blocks-sdk-record-limits) Currently queries all cell values in a table
|
|
305
|
+
// when loading linked record data. Must add a LinkedRecord query type in the future.
|
|
306
|
+
// Since _loadDataAsync can only be called once, this recordStoreQueryId is only set once,
|
|
307
|
+
// although it is guaranteed to be stable if needed (so long as this._field.id is stable)
|
|
308
|
+
|
|
295
309
|
_context2.next = 6;
|
|
296
|
-
return _regenerator.default.awrap(Promise.all([this._sdk.base.__getRecordStore(this._record.parentTable.id).
|
|
310
|
+
return _regenerator.default.awrap(Promise.all([this._sdk.base.__getRecordStore(this._record.parentTable.id).loadAllCellValuesInFieldIdsAsync([this._field.id]), this._linkedQueryResult.loadDataAsync(), this._loadRecordColorsAsync()]));
|
|
297
311
|
|
|
298
312
|
case 6:
|
|
313
|
+
_ref = _context2.sent;
|
|
314
|
+
_ref2 = (0, _slicedToArray2.default)(_ref, 1);
|
|
315
|
+
recordStoreQueryId = _ref2[0];
|
|
316
|
+
this._recordStoreQueryId = recordStoreQueryId;
|
|
317
|
+
|
|
299
318
|
this._invalidateComputedData();
|
|
300
319
|
|
|
301
320
|
changedKeys = ['records', 'recordIds', 'recordColors']; // If the linked query result was not initially loaded, then the
|
|
@@ -311,55 +330,55 @@ function (_RecordQueryResult) {
|
|
|
311
330
|
_iteratorNormalCompletion3 = true;
|
|
312
331
|
_didIteratorError3 = false;
|
|
313
332
|
_iteratorError3 = undefined;
|
|
314
|
-
_context2.prev =
|
|
333
|
+
_context2.prev = 17;
|
|
315
334
|
|
|
316
335
|
for (_iterator3 = fieldIds[Symbol.iterator](); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
317
336
|
fieldId = _step3.value;
|
|
318
337
|
changedKeys.push(_record_query_result.default.WatchableCellValuesInFieldKeyPrefix + fieldId);
|
|
319
338
|
}
|
|
320
339
|
|
|
321
|
-
_context2.next =
|
|
340
|
+
_context2.next = 25;
|
|
322
341
|
break;
|
|
323
342
|
|
|
324
|
-
case
|
|
325
|
-
_context2.prev =
|
|
326
|
-
_context2.t0 = _context2["catch"](
|
|
343
|
+
case 21:
|
|
344
|
+
_context2.prev = 21;
|
|
345
|
+
_context2.t0 = _context2["catch"](17);
|
|
327
346
|
_didIteratorError3 = true;
|
|
328
347
|
_iteratorError3 = _context2.t0;
|
|
329
348
|
|
|
330
|
-
case
|
|
331
|
-
_context2.prev =
|
|
332
|
-
_context2.prev =
|
|
349
|
+
case 25:
|
|
350
|
+
_context2.prev = 25;
|
|
351
|
+
_context2.prev = 26;
|
|
333
352
|
|
|
334
353
|
if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
|
|
335
354
|
_iterator3.return();
|
|
336
355
|
}
|
|
337
356
|
|
|
338
|
-
case
|
|
339
|
-
_context2.prev =
|
|
357
|
+
case 28:
|
|
358
|
+
_context2.prev = 28;
|
|
340
359
|
|
|
341
360
|
if (!_didIteratorError3) {
|
|
342
|
-
_context2.next =
|
|
361
|
+
_context2.next = 31;
|
|
343
362
|
break;
|
|
344
363
|
}
|
|
345
364
|
|
|
346
365
|
throw _iteratorError3;
|
|
347
366
|
|
|
348
|
-
case
|
|
349
|
-
return _context2.finish(
|
|
367
|
+
case 31:
|
|
368
|
+
return _context2.finish(28);
|
|
350
369
|
|
|
351
|
-
case
|
|
352
|
-
return _context2.finish(
|
|
370
|
+
case 32:
|
|
371
|
+
return _context2.finish(25);
|
|
353
372
|
|
|
354
|
-
case
|
|
373
|
+
case 33:
|
|
355
374
|
return _context2.abrupt("return", changedKeys);
|
|
356
375
|
|
|
357
|
-
case
|
|
376
|
+
case 34:
|
|
358
377
|
case "end":
|
|
359
378
|
return _context2.stop();
|
|
360
379
|
}
|
|
361
380
|
}
|
|
362
|
-
}, null, this, [[
|
|
381
|
+
}, null, this, [[17, 21, 25, 33], [26,, 28, 32]]);
|
|
363
382
|
}
|
|
364
383
|
/** @internal */
|
|
365
384
|
|
|
@@ -376,7 +395,9 @@ function (_RecordQueryResult) {
|
|
|
376
395
|
|
|
377
396
|
this._unwatchLinkedQueryResult();
|
|
378
397
|
|
|
379
|
-
|
|
398
|
+
(0, _error_utils.invariant)(this._recordStoreQueryId, 'Unsubscribing from linked record record store without queryId');
|
|
399
|
+
|
|
400
|
+
this._sdk.base.__getRecordStore(this._record.parentTable.id).unloadCellValuesForQueryIdsThatAreSubscribedToAllCells([this._recordStoreQueryId]);
|
|
380
401
|
|
|
381
402
|
this._linkedQueryResult.unloadData();
|
|
382
403
|
|
|
@@ -448,7 +469,12 @@ function (_RecordQueryResult) {
|
|
|
448
469
|
// result
|
|
449
470
|
|
|
450
471
|
|
|
451
|
-
this._originRecordStore.
|
|
472
|
+
this._originRecordStore.watchWithRecordQueryResult({
|
|
473
|
+
recordQueryResult: this,
|
|
474
|
+
keys: _record_store.WatchableRecordStoreKeys.recordIds,
|
|
475
|
+
callbackForRegistration: this._onOriginRecordsChange,
|
|
476
|
+
context: this
|
|
477
|
+
}); // if the linked field in the origin table is deleted, we need to
|
|
452
478
|
// invalidate this result
|
|
453
479
|
|
|
454
480
|
|
|
@@ -592,11 +618,12 @@ function (_RecordQueryResult) {
|
|
|
592
618
|
if (Array.isArray(recordIds)) {
|
|
593
619
|
var recordIdsSet = this._getOrGenerateRecordIdsSet();
|
|
594
620
|
|
|
595
|
-
var filteredRecordIds = recordIds.filter(id => typeof id === 'string' && recordIdsSet[id] === true);
|
|
621
|
+
var filteredRecordIds = recordIds.filter(id => typeof id === 'string' && recordIdsSet[id] === true); // There should always be a filteredRecordIds found for this query
|
|
622
|
+
// type - not finding any is a fundamental mistake in our query engine
|
|
596
623
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
624
|
+
(0, _error_utils.invariant)(filteredRecordIds.length, 'Filtered record change on incorrect record, query engine issue');
|
|
625
|
+
|
|
626
|
+
this._onChange(_record_query_result.default.WatchableCellValuesInFieldKeyPrefix + fieldId, filteredRecordIds);
|
|
600
627
|
} else {
|
|
601
628
|
this._onChange(_record_query_result.default.WatchableCellValuesInFieldKeyPrefix + fieldId);
|
|
602
629
|
}
|
|
@@ -776,6 +803,27 @@ function (_RecordQueryResult) {
|
|
|
776
803
|
(0, _error_utils.invariant)(recordIdsSet, 'recordIdsSet must exist');
|
|
777
804
|
return recordIdsSet;
|
|
778
805
|
}
|
|
806
|
+
/**
|
|
807
|
+
* This allows a record query result to specify the source of the query
|
|
808
|
+
* eg: View, Table, Linked record when watching fields.
|
|
809
|
+
* This scopes the watch to those fields + rows in the query.
|
|
810
|
+
*
|
|
811
|
+
* @internal
|
|
812
|
+
*/
|
|
813
|
+
|
|
814
|
+
}, {
|
|
815
|
+
key: "__constructQuerySpecForBlockFieldSelectionSpec",
|
|
816
|
+
value: function __constructQuerySpecForBlockFieldSelectionSpec(fieldSelection) {
|
|
817
|
+
// The origin tableId is always the one referred to here as we must watch the origin record for deletion
|
|
818
|
+
var originTableId = this._record.parentTable.id;
|
|
819
|
+
return {
|
|
820
|
+
sourceType: _block_query_spec.BlockQuerySourceType.TABLE,
|
|
821
|
+
sourceTableId: originTableId,
|
|
822
|
+
recordSelection: {
|
|
823
|
+
fieldSelection
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
}
|
|
779
827
|
}, {
|
|
780
828
|
key: "isValid",
|
|
781
829
|
get: function get() {
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.MAX_NUM_FIELDS_PER_TABLE = exports.MAX_TABLE_NAME_LENGTH = exports.MAX_FIELD_NAME_LENGTH = void 0;
|
|
6
|
+
exports.MAX_NUM_FIELDS_PER_TABLE = exports.MAX_TABLE_NAME_LENGTH = exports.MAX_FIELD_DESCRIPTION_LENGTH = exports.MAX_FIELD_NAME_LENGTH = void 0;
|
|
7
7
|
// Mirrored from clientServerSharedConfigSettings
|
|
8
8
|
var MAX_FIELD_NAME_LENGTH = 255;
|
|
9
9
|
exports.MAX_FIELD_NAME_LENGTH = MAX_FIELD_NAME_LENGTH;
|
|
10
|
+
var MAX_FIELD_DESCRIPTION_LENGTH = 20000;
|
|
11
|
+
exports.MAX_FIELD_DESCRIPTION_LENGTH = MAX_FIELD_DESCRIPTION_LENGTH;
|
|
10
12
|
var MAX_TABLE_NAME_LENGTH = 255;
|
|
11
13
|
exports.MAX_TABLE_NAME_LENGTH = MAX_TABLE_NAME_LENGTH;
|
|
12
14
|
var MAX_NUM_FIELDS_PER_TABLE = 500;
|