@airtable/blocks 1.11.1 → 1.12.0
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/dist/cjs/global_config.js +3 -3
- package/dist/cjs/models/base.js +10 -10
- package/dist/cjs/models/cursor.js +4 -6
- package/dist/cjs/models/field.js +3 -3
- package/dist/cjs/models/record_query_result.js +1 -1
- package/dist/cjs/models/record_store.js +68 -16
- package/dist/cjs/models/session.js +3 -3
- package/dist/cjs/models/table.js +25 -25
- package/dist/cjs/sdk.js +1 -1
- package/dist/cjs/settings_button.js +1 -1
- package/dist/cjs/ui/expand_record_picker_async.js +1 -1
- package/dist/cjs/ui/icon_config.js +4 -2
- package/dist/cjs/ui/initialize_block.js +3 -3
- package/dist/cjs/ui/use_global_config.js +1 -1
- package/dist/cjs/ui/use_loadable.js +3 -3
- package/dist/cjs/ui/use_record_action_data.js +11 -11
- package/dist/cjs/ui/use_settings_button.js +1 -1
- package/dist/cjs/ui/viewport_constraint.js +1 -1
- package/dist/cjs/viewport.js +9 -9
- package/dist/types/src/global_config.d.ts +3 -3
- package/dist/types/src/models/base.d.ts +9 -9
- package/dist/types/src/models/cursor.d.ts +4 -6
- package/dist/types/src/models/cursor.d.ts.map +1 -1
- package/dist/types/src/models/field.d.ts +3 -3
- package/dist/types/src/models/record_query_result.d.ts +2 -2
- package/dist/types/src/models/session.d.ts +3 -3
- package/dist/types/src/models/table.d.ts +25 -25
- package/dist/types/src/settings_button.d.ts +1 -1
- package/dist/types/src/ui/expand_record_picker_async.d.ts +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/initialize_block.d.ts +1 -1
- package/dist/types/src/ui/use_global_config.d.ts +1 -1
- package/dist/types/src/ui/use_loadable.d.ts +2 -2
- package/dist/types/src/ui/use_record_action_data.d.ts +11 -11
- package/dist/types/src/ui/use_settings_button.d.ts +1 -1
- package/dist/types/src/ui/viewport_constraint.d.ts +3 -3
- package/dist/types/src/ui/viewport_constraint.d.ts.map +1 -1
- package/dist/types/src/viewport.d.ts +9 -9
- package/package.json +1 -1
- package/CHANGELOG.md +0 -495
|
@@ -59,7 +59,7 @@ var _private_utils = require("./private_utils");
|
|
|
59
59
|
// as a name seems a bit too vague in terms of intended usage).
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* A key-value store for persisting configuration options for an
|
|
62
|
+
* A key-value store for persisting configuration options for an extension installation.
|
|
63
63
|
*
|
|
64
64
|
* The contents will be synced in real-time to all logged-in users of the installation.
|
|
65
65
|
* Contents will not be updated in real-time when the installation is running in
|
|
@@ -287,7 +287,7 @@ function (_Watchable) {
|
|
|
287
287
|
* if (globalConfig.hasPermissionToSetPaths('favoriteColor', color)) {
|
|
288
288
|
* globalConfig.setAsync('favoriteColor', color);
|
|
289
289
|
* }
|
|
290
|
-
* // The update is now applied within your
|
|
290
|
+
* // The update is now applied within your extension (eg will be
|
|
291
291
|
* // reflected in globalConfig) but are still being saved to
|
|
292
292
|
* // Airtable servers (e.g. may not be updated for other users yet)
|
|
293
293
|
* }
|
|
@@ -423,7 +423,7 @@ function (_Watchable) {
|
|
|
423
423
|
* if (globalConfig.hasPermissionToSetPaths(updates)) {
|
|
424
424
|
* globalConfig.setPathsAsync(updates);
|
|
425
425
|
* }
|
|
426
|
-
* // The updates are now applied within your
|
|
426
|
+
* // The updates are now applied within your extension (eg will be reflected in
|
|
427
427
|
* // globalConfig) but are still being saved to Airtable servers (e.g. they
|
|
428
428
|
* // may not be updated for other users yet)
|
|
429
429
|
* }
|
package/dist/cjs/models/base.js
CHANGED
|
@@ -186,8 +186,8 @@ function (_AbstractModel) {
|
|
|
186
186
|
* The user matching the given ID, name, or email address. Returns null if that user does not
|
|
187
187
|
* exist or does not have access to this base.
|
|
188
188
|
*
|
|
189
|
-
* This method is convenient when building an
|
|
190
|
-
*
|
|
189
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
190
|
+
* extensions the best practice is to use the {@link getCollaboratorByIdIfExists} method instead.
|
|
191
191
|
*
|
|
192
192
|
* @param collaboratorIdOrNameOrEmail The ID of the user.
|
|
193
193
|
*/
|
|
@@ -254,8 +254,8 @@ function (_AbstractModel) {
|
|
|
254
254
|
* or does not have access to this base. Use {@link getCollaboratorIfExists} instead if you are
|
|
255
255
|
* unsure whether a collaborator with the given ID exists and has access to this base.
|
|
256
256
|
*
|
|
257
|
-
* This method is convenient when building an
|
|
258
|
-
*
|
|
257
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
258
|
+
* extensions the best practice is to use the {@link getCollaboratorById} method instead.
|
|
259
259
|
*
|
|
260
260
|
* @param collaboratorIdOrNameOrEmail The ID of the user.
|
|
261
261
|
*/
|
|
@@ -397,8 +397,8 @@ function (_AbstractModel) {
|
|
|
397
397
|
* The table matching the given ID or name. Returns `null` if no matching table exists within
|
|
398
398
|
* this base.
|
|
399
399
|
*
|
|
400
|
-
* This method is convenient when building an
|
|
401
|
-
*
|
|
400
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
401
|
+
* extensions the best practice is to use the {@link getTableByIdIfExists} or
|
|
402
402
|
* {@link getTableByNameIfExists} methods instead.
|
|
403
403
|
*
|
|
404
404
|
* @param tableIdOrName The ID or name of the table you're looking for.
|
|
@@ -416,8 +416,8 @@ function (_AbstractModel) {
|
|
|
416
416
|
* Use {@link getTableIfExists} instead if you are unsure whether a table exists with the given
|
|
417
417
|
* name/ID.
|
|
418
418
|
*
|
|
419
|
-
* This method is convenient when building an
|
|
420
|
-
*
|
|
419
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
420
|
+
* extensions the best practice is to use the {@link getTableById} or {@link getTableByName} methods
|
|
421
421
|
* instead.
|
|
422
422
|
*
|
|
423
423
|
* @param tableIdOrName The ID or name of the table you're looking for.
|
|
@@ -521,7 +521,7 @@ function (_AbstractModel) {
|
|
|
521
521
|
*
|
|
522
522
|
* This action is asynchronous. Unlike new records, new tables are **not** created
|
|
523
523
|
* optimistically locally. You must `await` the returned promise before using the new
|
|
524
|
-
* table in your
|
|
524
|
+
* table in your extension.
|
|
525
525
|
*
|
|
526
526
|
* @param name name for the table. must be case-insensitive unique
|
|
527
527
|
* @param fields array of fields to create in the table: see below for an example. `name` and
|
|
@@ -607,7 +607,7 @@ function (_AbstractModel) {
|
|
|
607
607
|
value: function getMaxRecordsPerTable() {
|
|
608
608
|
var _this$_data$maxRowsPe;
|
|
609
609
|
|
|
610
|
-
return (_this$_data$maxRowsPe = this._data.maxRowsPerTable) !== null && _this$_data$maxRowsPe !== void 0 ? _this$_data$maxRowsPe :
|
|
610
|
+
return (_this$_data$maxRowsPe = this._data.maxRowsPerTable) !== null && _this$_data$maxRowsPe !== void 0 ? _this$_data$maxRowsPe : 100000;
|
|
611
611
|
}
|
|
612
612
|
/**
|
|
613
613
|
* @internal
|
|
@@ -268,9 +268,8 @@ function (_AbstractModelWithAsy) {
|
|
|
268
268
|
key: "setActiveTable",
|
|
269
269
|
|
|
270
270
|
/**
|
|
271
|
-
* Sets the specified table to active in the Airtable UI. If the
|
|
272
|
-
*
|
|
273
|
-
* fullscreen.
|
|
271
|
+
* Sets the specified table to active in the Airtable UI. If the extension installation or extensions pane
|
|
272
|
+
* is fullscreen, fullscreen mode will be exited.
|
|
274
273
|
*
|
|
275
274
|
* @param tableOrTableId The target table or table ID to set as active in the Airtable main page.
|
|
276
275
|
*/
|
|
@@ -280,9 +279,8 @@ function (_AbstractModelWithAsy) {
|
|
|
280
279
|
this._sdk.__airtableInterface.setActiveViewOrTable(tableId);
|
|
281
280
|
}
|
|
282
281
|
/**
|
|
283
|
-
* Sets the specified view (and corresponding table) to active in the Airtable UI. If the
|
|
284
|
-
* pane is fullscreen,
|
|
285
|
-
* to be displayed fullscreen.
|
|
282
|
+
* Sets the specified view (and corresponding table) to active in the Airtable UI. If the extension
|
|
283
|
+
* installation or extensions pane is fullscreen, fullscreen mode will be exited.
|
|
286
284
|
*
|
|
287
285
|
* @param tableOrTableId The table or table ID that the target view belongs to.
|
|
288
286
|
* @param viewOrViewId The target view or view ID to set as active in the Airtable main page.
|
package/dist/cjs/models/field.js
CHANGED
|
@@ -225,7 +225,7 @@ function (_AbstractModel) {
|
|
|
225
225
|
*
|
|
226
226
|
* This action is asynchronous. Unlike updates to cell values, updates to field options are
|
|
227
227
|
* **not** applied optimistically locally. You must `await` the returned promise before
|
|
228
|
-
* relying on the change in your
|
|
228
|
+
* relying on the change in your extension.
|
|
229
229
|
*
|
|
230
230
|
* Optionally, you can pass an `opts` object as the second argument. See {@link UpdateFieldOptionsOpts}
|
|
231
231
|
* for available options.
|
|
@@ -342,7 +342,7 @@ function (_AbstractModel) {
|
|
|
342
342
|
*
|
|
343
343
|
* This action is asynchronous. Unlike updates to cell values, updates to field name are
|
|
344
344
|
* **not** applied optimistically locally. You must `await` the returned promise before
|
|
345
|
-
* relying on the change in your
|
|
345
|
+
* relying on the change in your extension.
|
|
346
346
|
*
|
|
347
347
|
* @param name new name for the field
|
|
348
348
|
*
|
|
@@ -440,7 +440,7 @@ function (_AbstractModel) {
|
|
|
440
440
|
*
|
|
441
441
|
* This action is asynchronous. Unlike updates to cell values, updates to field descriptions are
|
|
442
442
|
* **not** applied optimistically locally. You must `await` the returned promise before
|
|
443
|
-
* relying on the change in your
|
|
443
|
+
* relying on the change in your extension.
|
|
444
444
|
*
|
|
445
445
|
* @param description new description for the field
|
|
446
446
|
*
|
|
@@ -127,7 +127,7 @@ function normalizeSortsOrGroups(table, sortsOrGroups) {
|
|
|
127
127
|
* You can get one of these with `record.selectLinkedRecordsFromCell(someField)`.
|
|
128
128
|
*
|
|
129
129
|
* Once you've got a query result, you need to load it before you can start working with it -
|
|
130
|
-
*
|
|
130
|
+
* extensions don't load record data by default. We recommend using {@link useRecords},
|
|
131
131
|
* {@link useRecordIds}, {@link useRecordById} or {@link useLoadable} to handle this.
|
|
132
132
|
*
|
|
133
133
|
* If you're not using a query result in a React component, you can manually load the data and
|
|
@@ -12,6 +12,8 @@ require("core-js/modules/es.array.iterator");
|
|
|
12
12
|
|
|
13
13
|
require("core-js/modules/es.array.map");
|
|
14
14
|
|
|
15
|
+
require("core-js/modules/es.object.entries");
|
|
16
|
+
|
|
15
17
|
require("core-js/modules/es.object.to-string");
|
|
16
18
|
|
|
17
19
|
require("core-js/modules/es.promise");
|
|
@@ -110,6 +112,7 @@ function (_AbstractModelWithAsy) {
|
|
|
110
112
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_areCellValuesLoadedByFieldId", {});
|
|
111
113
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_pendingCellValuesLoadPromiseByFieldId", {});
|
|
112
114
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_cellValuesRetainCountByFieldId", {});
|
|
115
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_timeoutForRemovingFieldIds", null);
|
|
113
116
|
_this._airtableInterface = sdk.__airtableInterface;
|
|
114
117
|
_this.tableId = tableId; // A bit of a hack, but we use the primary field ID to load record
|
|
115
118
|
// metadata (see _getFieldIdForCausingRecordMetadataToLoad). We copy the
|
|
@@ -502,10 +505,15 @@ function (_AbstractModelWithAsy) {
|
|
|
502
505
|
});
|
|
503
506
|
|
|
504
507
|
case 45:
|
|
505
|
-
|
|
508
|
+
// Since we are incrementing fieldIds, it's necessary to restart any pending timeouts
|
|
509
|
+
// to unload data. This is because it's possible for a timeout to fire while a queryResult
|
|
510
|
+
// is actively unloading, and erroneously unload data. Data must be unloaded _after_ the queryResult.
|
|
511
|
+
this._restartTimeoutToUnloadFieldIdsIfTimeoutIsActive();
|
|
512
|
+
|
|
513
|
+
_context2.next = 48;
|
|
506
514
|
return _regenerator.default.awrap(Promise.all(pendingLoadPromises));
|
|
507
515
|
|
|
508
|
-
case
|
|
516
|
+
case 48:
|
|
509
517
|
case "end":
|
|
510
518
|
return _context2.stop();
|
|
511
519
|
}
|
|
@@ -638,7 +646,6 @@ function (_AbstractModelWithAsy) {
|
|
|
638
646
|
return;
|
|
639
647
|
}
|
|
640
648
|
|
|
641
|
-
var fieldIdsWithZeroRetainCount = [];
|
|
642
649
|
var _iteratorNormalCompletion8 = true;
|
|
643
650
|
var _didIteratorError8 = false;
|
|
644
651
|
var _iteratorError8 = undefined;
|
|
@@ -656,11 +663,10 @@ function (_AbstractModelWithAsy) {
|
|
|
656
663
|
}
|
|
657
664
|
|
|
658
665
|
this._cellValuesRetainCountByFieldId[fieldId] = fieldRetainCount;
|
|
666
|
+
} // Don't unload immediately. Wait a while in case something else
|
|
667
|
+
// requests the data, so we can avoid going back to liveapp or
|
|
668
|
+
// the network.
|
|
659
669
|
|
|
660
|
-
if (fieldRetainCount === 0) {
|
|
661
|
-
fieldIdsWithZeroRetainCount.push(fieldId);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
670
|
} catch (err) {
|
|
665
671
|
_didIteratorError8 = true;
|
|
666
672
|
_iteratorError8 = err;
|
|
@@ -676,16 +682,45 @@ function (_AbstractModelWithAsy) {
|
|
|
676
682
|
}
|
|
677
683
|
}
|
|
678
684
|
|
|
685
|
+
this._startTimeoutToUnloadForFieldIdsIfNeeded();
|
|
686
|
+
} // This unloads all fields where the retain count is at zero, and if any other
|
|
687
|
+
// request to unload fields is pending - cancels it and restarts it.
|
|
688
|
+
// This is important because fields must always be unloaded at least __DATA_UNLOAD_DELAY_MS
|
|
689
|
+
// after the unload is requested so that any QueryResults relying on them properly
|
|
690
|
+
// unload either first, or at the same time
|
|
691
|
+
|
|
692
|
+
}, {
|
|
693
|
+
key: "_startTimeoutToUnloadForFieldIdsIfNeeded",
|
|
694
|
+
value: function _startTimeoutToUnloadForFieldIdsIfNeeded() {
|
|
695
|
+
var fieldIdsWithZeroRetainCount = [];
|
|
696
|
+
|
|
697
|
+
for (var _i2 = 0, _Object$entries = Object.entries(this._cellValuesRetainCountByFieldId); _i2 < _Object$entries.length; _i2++) {
|
|
698
|
+
var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i2], 2),
|
|
699
|
+
fieldId = _Object$entries$_i[0],
|
|
700
|
+
retainCount = _Object$entries$_i[1];
|
|
701
|
+
|
|
702
|
+
if (retainCount === 0) {
|
|
703
|
+
fieldIdsWithZeroRetainCount.push(fieldId);
|
|
704
|
+
}
|
|
705
|
+
} // Cancel any pending timeouts before proceeding
|
|
706
|
+
// This should be canceled even if there aren't any fields to unload as that means
|
|
707
|
+
// that there has been loading that's occured that makes the pending request invalid
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
if (this._timeoutForRemovingFieldIds) {
|
|
711
|
+
clearTimeout(this._timeoutForRemovingFieldIds);
|
|
712
|
+
this._timeoutForRemovingFieldIds = null;
|
|
713
|
+
}
|
|
714
|
+
|
|
679
715
|
if (fieldIdsWithZeroRetainCount.length > 0) {
|
|
680
|
-
|
|
681
|
-
// requests the data, so we can avoid going back to liveapp or
|
|
682
|
-
// the network.
|
|
683
|
-
setTimeout(() => {
|
|
716
|
+
this._timeoutForRemovingFieldIds = setTimeout(() => {
|
|
684
717
|
// Make sure the retain count is still zero, since it may
|
|
685
718
|
// have been incremented before the timeout fired.
|
|
686
719
|
var fieldIdsToUnload = fieldIdsWithZeroRetainCount.filter(fieldId => {
|
|
687
|
-
|
|
688
|
-
|
|
720
|
+
// It's necessary to also check that the field is loaded, as it's possible
|
|
721
|
+
// for an unload to trigger with fields that have already been removed.
|
|
722
|
+
return this._cellValuesRetainCountByFieldId[fieldId] === 0 && this._areCellValuesLoadedByFieldId[fieldId];
|
|
723
|
+
}); // istanbul ignore else
|
|
689
724
|
|
|
690
725
|
if (fieldIdsToUnload.length > 0) {
|
|
691
726
|
// Set _areCellValuesLoadedByFieldId to false before calling _unloadCellValuesInFieldIds
|
|
@@ -715,10 +750,23 @@ function (_AbstractModelWithAsy) {
|
|
|
715
750
|
}
|
|
716
751
|
|
|
717
752
|
this._unloadCellValuesInFieldIds(fieldIdsToUnload);
|
|
753
|
+
} else {
|
|
754
|
+
// This shouldn't be possible because we always cancel the timer if fieldIds loadedness
|
|
755
|
+
// status ever changes
|
|
756
|
+
(0, _error_utils.logErrorToSentry)('fieldIdsToUnload is empty, this likely means the unload timer is not properly reset.');
|
|
718
757
|
}
|
|
758
|
+
|
|
759
|
+
this._timeoutForRemovingFieldIds = null;
|
|
719
760
|
}, _abstract_model_with_async_data.default.__DATA_UNLOAD_DELAY_MS);
|
|
720
761
|
}
|
|
721
762
|
}
|
|
763
|
+
}, {
|
|
764
|
+
key: "_restartTimeoutToUnloadFieldIdsIfTimeoutIsActive",
|
|
765
|
+
value: function _restartTimeoutToUnloadFieldIdsIfTimeoutIsActive() {
|
|
766
|
+
if (this._timeoutForRemovingFieldIds) {
|
|
767
|
+
this._startTimeoutToUnloadForFieldIdsIfNeeded();
|
|
768
|
+
}
|
|
769
|
+
}
|
|
722
770
|
}, {
|
|
723
771
|
key: "_unloadCellValuesInFieldIds",
|
|
724
772
|
value: function _unloadCellValuesInFieldIds(fieldIds) {
|
|
@@ -811,11 +859,15 @@ function (_AbstractModelWithAsy) {
|
|
|
811
859
|
if (!areAnyFieldsLoaded) {
|
|
812
860
|
this._data.recordsById = undefined;
|
|
813
861
|
} else if (!this.isDataLoaded) {
|
|
814
|
-
var fieldIdsToClear;
|
|
862
|
+
var fieldIdsToClear; // This should be impossible - for fields should always be loaded
|
|
863
|
+
// when attempting to unload specific fields. This codepath was previously possible
|
|
864
|
+
// due to a bug. It could be converted to an invariant, but that is higher risk.
|
|
865
|
+
// istanbul ignore if
|
|
815
866
|
|
|
816
867
|
if (unloadedFieldIds) {
|
|
817
868
|
// Specific fields were unloaded, so clear out the cell values for those fields.
|
|
818
869
|
fieldIdsToClear = unloadedFieldIds;
|
|
870
|
+
(0, _error_utils.logErrorToSentry)('Field Ids are being unloaded when record_store is unloaded');
|
|
819
871
|
} else {
|
|
820
872
|
// The entire table was unloaded, but some individual fields are still loaded.
|
|
821
873
|
// We need to clear out the cell values of every field that was unloaded.
|
|
@@ -907,8 +959,8 @@ function (_AbstractModelWithAsy) {
|
|
|
907
959
|
var cellValuesByFieldId = dirtyRecordPaths.cellValuesByFieldId;
|
|
908
960
|
|
|
909
961
|
if (cellValuesByFieldId) {
|
|
910
|
-
for (var
|
|
911
|
-
var fieldId = _Object$keys2[
|
|
962
|
+
for (var _i3 = 0, _Object$keys2 = Object.keys(cellValuesByFieldId); _i3 < _Object$keys2.length; _i3++) {
|
|
963
|
+
var fieldId = _Object$keys2[_i3];
|
|
912
964
|
dirtyFieldIdsSet[fieldId] = true;
|
|
913
965
|
}
|
|
914
966
|
}
|
|
@@ -72,7 +72,7 @@ var WatchableSessionKeys = Object.freeze({
|
|
|
72
72
|
* if (session.currentUser !== null) {
|
|
73
73
|
* return <span>The current user's name is {session.currentUser.name}</span>;
|
|
74
74
|
* } else {
|
|
75
|
-
* return <span>This
|
|
75
|
+
* return <span>This extension is being viewed in a public share</span>;
|
|
76
76
|
* }
|
|
77
77
|
* }
|
|
78
78
|
* ```
|
|
@@ -384,7 +384,7 @@ function (_AbstractModel) {
|
|
|
384
384
|
return this._sessionData;
|
|
385
385
|
}
|
|
386
386
|
/**
|
|
387
|
-
* The current user, or `null` if the
|
|
387
|
+
* The current user, or `null` if the extension is running in a publicly shared base.
|
|
388
388
|
*
|
|
389
389
|
* @example
|
|
390
390
|
* ```js
|
|
@@ -394,7 +394,7 @@ function (_AbstractModel) {
|
|
|
394
394
|
* const session = useSession();
|
|
395
395
|
*
|
|
396
396
|
* if (!session.currentUser) {
|
|
397
|
-
* return <div>This
|
|
397
|
+
* return <div>This extension is being used in a public share.</div>;
|
|
398
398
|
* }
|
|
399
399
|
*
|
|
400
400
|
* return <ul>
|
package/dist/cjs/models/table.js
CHANGED
|
@@ -279,8 +279,8 @@ function (_AbstractModel) {
|
|
|
279
279
|
* The field matching the given ID or name. Returns `null` if no matching field exists within
|
|
280
280
|
* this table.
|
|
281
281
|
*
|
|
282
|
-
* This method is convenient when building an
|
|
283
|
-
*
|
|
282
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
283
|
+
* extensions the best practice is to use the {@link getFieldByIdIfExists} or
|
|
284
284
|
* {@link getFieldByNameIfExists} methods instead.
|
|
285
285
|
*
|
|
286
286
|
* @param fieldIdOrName The ID or name of the field you're looking for.
|
|
@@ -298,8 +298,8 @@ function (_AbstractModel) {
|
|
|
298
298
|
* Use {@link getFieldIfExists} instead if you are unsure whether a field exists with the given
|
|
299
299
|
* name/ID.
|
|
300
300
|
*
|
|
301
|
-
* This method is convenient when building an
|
|
302
|
-
*
|
|
301
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
302
|
+
* extensions the best practice is to use the {@link getFieldById} or {@link getFieldByName} methods
|
|
303
303
|
* instead.
|
|
304
304
|
*
|
|
305
305
|
* @param fieldIdOrName The ID or name of the field you're looking for.
|
|
@@ -460,8 +460,8 @@ function (_AbstractModel) {
|
|
|
460
460
|
* The view matching the given ID or name. Returns `null` if no matching view exists within
|
|
461
461
|
* this table.
|
|
462
462
|
*
|
|
463
|
-
* This method is convenient when building an
|
|
464
|
-
*
|
|
463
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
464
|
+
* extensions the best practice is to use the {@link getViewByIdIfExists} or
|
|
465
465
|
* {@link getViewByNameIfExists} methods instead.
|
|
466
466
|
*
|
|
467
467
|
* @param viewIdOrName The ID or name of the view you're looking for.
|
|
@@ -479,8 +479,8 @@ function (_AbstractModel) {
|
|
|
479
479
|
* Use {@link getViewIfExists} instead if you are unsure whether a view exists with the given
|
|
480
480
|
* name/ID.
|
|
481
481
|
*
|
|
482
|
-
* This method is convenient when building an
|
|
483
|
-
*
|
|
482
|
+
* This method is convenient when building an extension for a specific base, but for more generic
|
|
483
|
+
* extensions the best practice is to use the {@link getViewById} or {@link getViewByName} methods
|
|
484
484
|
* instead.
|
|
485
485
|
*
|
|
486
486
|
* @param viewIdOrName The ID or name of the view you're looking for.
|
|
@@ -662,7 +662,7 @@ function (_AbstractModel) {
|
|
|
662
662
|
*
|
|
663
663
|
* This action is asynchronous: `await` the returned promise if you wish to wait for the updated
|
|
664
664
|
* cell values to be persisted to Airtable servers.
|
|
665
|
-
* Updates are applied optimistically locally, so your changes will be reflected in your
|
|
665
|
+
* Updates are applied optimistically locally, so your changes will be reflected in your extension
|
|
666
666
|
* before the promise resolves.
|
|
667
667
|
*
|
|
668
668
|
* @param recordOrRecordId the record to update
|
|
@@ -673,7 +673,7 @@ function (_AbstractModel) {
|
|
|
673
673
|
* if (table.hasPermissionToUpdateRecord(record, recordFields)) {
|
|
674
674
|
* table.updateRecordAsync(record, recordFields);
|
|
675
675
|
* }
|
|
676
|
-
* // The updated values will now show in your
|
|
676
|
+
* // The updated values will now show in your extension (eg in
|
|
677
677
|
* // `table.selectRecords()` result) but are still being saved to Airtable
|
|
678
678
|
* // servers (e.g. other users may not be able to see them yet).
|
|
679
679
|
* }
|
|
@@ -768,7 +768,7 @@ function (_AbstractModel) {
|
|
|
768
768
|
*
|
|
769
769
|
* // Check if user could update specific fields, when you don't know the
|
|
770
770
|
* // specific record that will be updated yet. (for example, if the field is
|
|
771
|
-
* // selected by the user and you want to check if your
|
|
771
|
+
* // selected by the user and you want to check if your extension can write to it).
|
|
772
772
|
* const updateUnknownRecordCheckResult =
|
|
773
773
|
* table.checkPermissionsForUpdateRecord(undefined, {
|
|
774
774
|
* 'My field name': 'updated value',
|
|
@@ -779,7 +779,7 @@ function (_AbstractModel) {
|
|
|
779
779
|
*
|
|
780
780
|
* // Check if user could perform updates within the table, without knowing the
|
|
781
781
|
* // specific record or fields that will be updated yet (e.g., to render your
|
|
782
|
-
* //
|
|
782
|
+
* // extension in "read only" mode).
|
|
783
783
|
* const updateUnknownRecordAndFieldsCheckResult =
|
|
784
784
|
* table.checkPermissionsForUpdateRecord();
|
|
785
785
|
* ```
|
|
@@ -829,7 +829,7 @@ function (_AbstractModel) {
|
|
|
829
829
|
*
|
|
830
830
|
* // Check if user could update specific fields, when you don't know the
|
|
831
831
|
* // specific record that will be updated yet (e.g. if the field is selected
|
|
832
|
-
* // by the user and you want to check if your
|
|
832
|
+
* // by the user and you want to check if your extension can write to it).
|
|
833
833
|
* const canUpdateUnknownRecord =
|
|
834
834
|
* table.hasPermissionToUpdateRecord(undefined, {
|
|
835
835
|
* 'My field name': 'updated value',
|
|
@@ -840,7 +840,7 @@ function (_AbstractModel) {
|
|
|
840
840
|
*
|
|
841
841
|
* // Check if user could perform updates within the table, without knowing the
|
|
842
842
|
* // specific record or fields that will be updated yet. (for example, to
|
|
843
|
-
* // render your
|
|
843
|
+
* // render your extension in "read only" mode)
|
|
844
844
|
* const canUpdateUnknownRecordAndFields = table.hasPermissionToUpdateRecord();
|
|
845
845
|
* ```
|
|
846
846
|
*/
|
|
@@ -864,7 +864,7 @@ function (_AbstractModel) {
|
|
|
864
864
|
*
|
|
865
865
|
* This action is asynchronous: `await` the returned promise if you wish to wait for the
|
|
866
866
|
* updates to be persisted to Airtable servers.
|
|
867
|
-
* Updates are applied optimistically locally, so your changes will be reflected in your
|
|
867
|
+
* Updates are applied optimistically locally, so your changes will be reflected in your extension
|
|
868
868
|
* before the promise resolves.
|
|
869
869
|
*
|
|
870
870
|
* @param records Array of objects containing recordId and fields/cellValues to update for that record (specified as an object mapping `FieldId` or field name to cell value)
|
|
@@ -911,7 +911,7 @@ function (_AbstractModel) {
|
|
|
911
911
|
* if (table.hasPermissionToUpdateRecords(recordsToUpdate)) {
|
|
912
912
|
* table.updateRecordsAsync(recordsToUpdate);
|
|
913
913
|
* }
|
|
914
|
-
* // The records are now updated within your
|
|
914
|
+
* // The records are now updated within your extension (eg will be reflected in
|
|
915
915
|
* // `table.selectRecords()`) but are still being saved to Airtable servers
|
|
916
916
|
* // (e.g. they may not be updated for other users yet).
|
|
917
917
|
* }
|
|
@@ -1093,7 +1093,7 @@ function (_AbstractModel) {
|
|
|
1093
1093
|
*
|
|
1094
1094
|
* This action is asynchronous: `await` the returned promise if you wish to wait for the
|
|
1095
1095
|
* delete to be persisted to Airtable servers.
|
|
1096
|
-
* Updates are applied optimistically locally, so your changes will be reflected in your
|
|
1096
|
+
* Updates are applied optimistically locally, so your changes will be reflected in your extension
|
|
1097
1097
|
* before the promise resolves.
|
|
1098
1098
|
*
|
|
1099
1099
|
* @param recordOrRecordId the record to be deleted
|
|
@@ -1103,7 +1103,7 @@ function (_AbstractModel) {
|
|
|
1103
1103
|
* if (table.hasPermissionToDeleteRecord(record)) {
|
|
1104
1104
|
* table.deleteRecordAsync(record);
|
|
1105
1105
|
* }
|
|
1106
|
-
* // The record is now deleted within your
|
|
1106
|
+
* // The record is now deleted within your extension (eg will not be returned
|
|
1107
1107
|
* // in `table.selectRecords`) but it is still being saved to Airtable
|
|
1108
1108
|
* // servers (e.g. it may not look deleted to other users yet).
|
|
1109
1109
|
* }
|
|
@@ -1208,7 +1208,7 @@ function (_AbstractModel) {
|
|
|
1208
1208
|
*
|
|
1209
1209
|
* This action is asynchronous: `await` the returned promise if you wish to wait for the
|
|
1210
1210
|
* delete to be persisted to Airtable servers.
|
|
1211
|
-
* Updates are applied optimistically locally, so your changes will be reflected in your
|
|
1211
|
+
* Updates are applied optimistically locally, so your changes will be reflected in your extension
|
|
1212
1212
|
* before the promise resolves.
|
|
1213
1213
|
*
|
|
1214
1214
|
* @param recordsOrRecordIds Array of Records and RecordIds
|
|
@@ -1219,7 +1219,7 @@ function (_AbstractModel) {
|
|
|
1219
1219
|
* if (table.hasPermissionToDeleteRecords(records)) {
|
|
1220
1220
|
* table.deleteRecordsAsync(records);
|
|
1221
1221
|
* }
|
|
1222
|
-
* // The records are now deleted within your
|
|
1222
|
+
* // The records are now deleted within your extension (eg will not be
|
|
1223
1223
|
* // returned in `table.selectRecords()`) but are still being saved to
|
|
1224
1224
|
* // Airtable servers (e.g. they may not look deleted to other users yet).
|
|
1225
1225
|
* }
|
|
@@ -1336,7 +1336,7 @@ function (_AbstractModel) {
|
|
|
1336
1336
|
*
|
|
1337
1337
|
* This action is asynchronous: `await` the returned promise if you wish to wait for the new
|
|
1338
1338
|
* record to be persisted to Airtable servers.
|
|
1339
|
-
* Updates are applied optimistically locally, so your changes will be reflected in your
|
|
1339
|
+
* Updates are applied optimistically locally, so your changes will be reflected in your extension
|
|
1340
1340
|
* before the promise resolves.
|
|
1341
1341
|
*
|
|
1342
1342
|
* The returned promise will resolve to the RecordId of the new record once it is persisted.
|
|
@@ -1348,7 +1348,7 @@ function (_AbstractModel) {
|
|
|
1348
1348
|
* if (table.hasPermissionToCreateRecord(recordFields)) {
|
|
1349
1349
|
* table.createRecordAsync(recordFields);
|
|
1350
1350
|
* }
|
|
1351
|
-
* // You can now access the new record in your
|
|
1351
|
+
* // You can now access the new record in your extension (eg
|
|
1352
1352
|
* // `table.selectRecords()`) but it is still being saved to Airtable
|
|
1353
1353
|
* // servers (e.g. other users may not be able to see it yet).
|
|
1354
1354
|
* }
|
|
@@ -1507,7 +1507,7 @@ function (_AbstractModel) {
|
|
|
1507
1507
|
*
|
|
1508
1508
|
* This action is asynchronous: `await` the returned promise if you wish to wait for the new
|
|
1509
1509
|
* record to be persisted to Airtable servers.
|
|
1510
|
-
* Updates are applied optimistically locally, so your changes will be reflected in your
|
|
1510
|
+
* Updates are applied optimistically locally, so your changes will be reflected in your extension
|
|
1511
1511
|
* before the promise resolves.
|
|
1512
1512
|
*
|
|
1513
1513
|
* The returned promise will resolve to an array of RecordIds of the new records once the new
|
|
@@ -1551,7 +1551,7 @@ function (_AbstractModel) {
|
|
|
1551
1551
|
* if (table.hasPermissionToCreateRecords(recordDefs)) {
|
|
1552
1552
|
* table.createRecordsAsync(recordDefs);
|
|
1553
1553
|
* }
|
|
1554
|
-
* // You can now access the new records in your
|
|
1554
|
+
* // You can now access the new records in your extension (e.g.
|
|
1555
1555
|
* // `table.selectRecords()`) but they are still being saved to Airtable
|
|
1556
1556
|
* // servers (e.g. other users may not be able to see them yet.)
|
|
1557
1557
|
* }
|
|
@@ -1805,7 +1805,7 @@ function (_AbstractModel) {
|
|
|
1805
1805
|
*
|
|
1806
1806
|
* This action is asynchronous. Unlike new records, new fields are **not** created
|
|
1807
1807
|
* optimistically locally. You must `await` the returned promise before using the new
|
|
1808
|
-
* field in your
|
|
1808
|
+
* field in your extension.
|
|
1809
1809
|
*
|
|
1810
1810
|
* @param name name for the field. must be case-insensitive unique
|
|
1811
1811
|
* @param type type for the field
|
package/dist/cjs/sdk.js
CHANGED
|
@@ -39,7 +39,7 @@ var WatchableSettingsButtonKeys = Object.freeze({
|
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* Interface to the settings button that lives outside the
|
|
42
|
+
* Interface to the settings button that lives outside the extension's viewport.
|
|
43
43
|
*
|
|
44
44
|
* The {@link useSettingsButton} hook is the recommended way to use the settings button, but you can
|
|
45
45
|
* also use it with {@link useWatchable} if you want more granular control (for example, to only
|
|
@@ -25,7 +25,7 @@ var _error_utils = require("../error_utils");
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Expands a list of records in the Airtable UI, and prompts the user to pick
|
|
28
|
-
* one. The selected record is returned to the
|
|
28
|
+
* one. The selected record is returned to the extension, and the modal is
|
|
29
29
|
* automatically closed.
|
|
30
30
|
*
|
|
31
31
|
* If the user dismisses the modal, or another one is opened before this one
|