Removed SettingsV1 code paths (#325)

* removed settingsv1 code path in collection.ts

* removed Settingsv1 code

* Moved AAD error message up the chain
This commit is contained in:
Srinath Narayanan 2020-11-18 12:11:25 -08:00 committed by GitHub
parent 84b6075ee8
commit 85d2378d3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 19 additions and 2974 deletions

View File

@ -202,8 +202,6 @@ src/Explorer/Tabs/QueryTab.test.ts
src/Explorer/Tabs/QueryTab.ts
src/Explorer/Tabs/QueryTablesTab.ts
src/Explorer/Tabs/ScriptTabBase.ts
src/Explorer/Tabs/SettingsTab.test.ts
src/Explorer/Tabs/SettingsTab.ts
src/Explorer/Tabs/SparkMasterTab.ts
src/Explorer/Tabs/StoredProcedureTab.ts
src/Explorer/Tabs/TabComponents.ts

View File

@ -16,7 +16,7 @@ const notificationsPath = () => {
};
export const fetchPortalNotifications = async (): Promise<DataModels.Notification[]> => {
if (configContext.platform === Platform.Emulator) {
if (configContext.platform === Platform.Emulator || configContext.platform === Platform.Hosted) {
return [];
}

View File

@ -44,10 +44,6 @@ describe("Component Registerer", () => {
expect(ko.components.isRegistered("user-defined-function-tab")).toBe(true);
});
it("should register settings-tab component", () => {
expect(ko.components.isRegistered("settings-tab")).toBe(true);
});
it("should register settings-tab-v2 component", () => {
expect(ko.components.isRegistered("settings-tab-v2")).toBe(true);
});

View File

@ -31,7 +31,6 @@ ko.components.register("mongo-documents-tab", new TabComponents.MongoDocumentsTa
ko.components.register("stored-procedure-tab", new TabComponents.StoredProcedureTab());
ko.components.register("trigger-tab", new TabComponents.TriggerTab());
ko.components.register("user-defined-function-tab", new TabComponents.UserDefinedFunctionTab());
ko.components.register("settings-tab", new TabComponents.SettingsTab());
ko.components.register("settings-tab-v2", new TabComponents.SettingsTabV2());
ko.components.register("query-tab", new TabComponents.QueryTab());
ko.components.register("tables-query-tab", new TabComponents.QueryTablesTab());

View File

@ -16,7 +16,7 @@ import { CommandButtonComponentProps } from "../../Controls/CommandButton/Comman
import { userContext } from "../../../UserContext";
import { updateOfferThroughputBeyondLimit } from "../../../Common/dataAccess/updateOfferThroughputBeyondLimit";
import SettingsTab from "../../Tabs/SettingsTabV2";
import { throughputUnit } from "./SettingsRenderUtils";
import { mongoIndexingPolicyAADError, throughputUnit } from "./SettingsRenderUtils";
import { ScaleComponent, ScaleComponentProps } from "./SettingsSubComponents/ScaleComponent";
import {
MongoIndexingPolicyComponent,
@ -49,6 +49,7 @@ import { MongoDBCollectionResource, MongoIndex } from "../../../Utils/arm/genera
import { readMongoDBCollectionThroughRP } from "../../../Common/dataAccess/readMongoDBCollection";
import { getIndexTransformationProgress } from "../../../Common/dataAccess/getIndexTransformationProgress";
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
import { isEmpty } from "underscore";
interface SettingsV2TabInfo {
tab: SettingsV2TabTypes;
@ -227,7 +228,6 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
public loadMongoIndexes = async (): Promise<void> => {
if (
this.container.isMongoIndexEditorEnabled() &&
this.container.isPreferredApiMongoDB() &&
this.container.isEnableMongoCapabilityPresent() &&
this.container.databaseAccount()
@ -1000,16 +1000,19 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
tab: SettingsV2TabTypes.IndexingPolicyTab,
content: <IndexingPolicyComponent {...indexingPolicyComponentProps} />
});
} else if (
this.container.isMongoIndexEditorEnabled() &&
this.container.isPreferredApiMongoDB() &&
this.container.isEnableMongoCapabilityPresent()
) {
} else if (this.container.isPreferredApiMongoDB()) {
if (isEmpty(this.container.features())) {
tabs.push({
tab: SettingsV2TabTypes.IndexingPolicyTab,
content: mongoIndexingPolicyAADError
});
} else if (this.container.isEnableMongoCapabilityPresent()) {
tabs.push({
tab: SettingsV2TabTypes.IndexingPolicyTab,
content: <MongoIndexingPolicyComponent {...mongoIndexingPolicyComponentProps} />
});
}
}
if (this.hasConflictResolution()) {
tabs.push({

View File

@ -24,7 +24,6 @@ import {
transparentDetailsRowStyles,
createAndAddMongoIndexStackProps,
separatorStyles,
mongoIndexingPolicyAADError,
indexingPolicynUnsavedWarningMessage,
infoAndToolTipTextStyle
} from "../../SettingsRenderUtils";
@ -40,7 +39,6 @@ import {
} from "../../SettingsUtils";
import { AddMongoIndexComponent } from "./AddMongoIndexComponent";
import { CollapsibleSectionComponent } from "../../../CollapsiblePanel/CollapsibleSectionComponent";
import { AuthType } from "../../../../../AuthType";
import { IndexingPolicyRefreshComponent } from "../IndexingPolicyRefresh/IndexingPolicyRefreshComponent";
export interface MongoIndexingPolicyComponentProps {
@ -321,7 +319,7 @@ export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingP
</Stack>
);
} else {
return window.authType !== AuthType.AAD ? mongoIndexingPolicyAADError : <Spinner size={SpinnerSize.large} />;
return <Spinner size={SpinnerSize.large} />;
}
}
}

View File

@ -956,7 +956,6 @@ exports[`SettingsComponent renders 1`] = `
"isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isLinkInjectionEnabled": [Function],
"isMongoIndexEditorEnabled": [Function],
"isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function],
"isNotificationConsoleExpanded": [Function],
@ -973,7 +972,6 @@ exports[`SettingsComponent renders 1`] = `
"isRightPanelV2Enabled": [Function],
"isSchemaEnabled": [Function],
"isServerlessEnabled": [Function],
"isSettingsV2Enabled": [Function],
"isSparkEnabled": [Function],
"isSparkEnabledForAccount": [Function],
"isSynapseLinkUpdating": [Function],
@ -2237,7 +2235,6 @@ exports[`SettingsComponent renders 1`] = `
"isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isLinkInjectionEnabled": [Function],
"isMongoIndexEditorEnabled": [Function],
"isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function],
"isNotificationConsoleExpanded": [Function],
@ -2254,7 +2251,6 @@ exports[`SettingsComponent renders 1`] = `
"isRightPanelV2Enabled": [Function],
"isSchemaEnabled": [Function],
"isServerlessEnabled": [Function],
"isSettingsV2Enabled": [Function],
"isSparkEnabled": [Function],
"isSparkEnabledForAccount": [Function],
"isSynapseLinkUpdating": [Function],
@ -3531,7 +3527,6 @@ exports[`SettingsComponent renders 1`] = `
"isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isLinkInjectionEnabled": [Function],
"isMongoIndexEditorEnabled": [Function],
"isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function],
"isNotificationConsoleExpanded": [Function],
@ -3548,7 +3543,6 @@ exports[`SettingsComponent renders 1`] = `
"isRightPanelV2Enabled": [Function],
"isSchemaEnabled": [Function],
"isServerlessEnabled": [Function],
"isSettingsV2Enabled": [Function],
"isSparkEnabled": [Function],
"isSparkEnabledForAccount": [Function],
"isSynapseLinkUpdating": [Function],
@ -4812,7 +4806,6 @@ exports[`SettingsComponent renders 1`] = `
"isHostedDataExplorerEnabled": [Function],
"isLeftPaneExpanded": [Function],
"isLinkInjectionEnabled": [Function],
"isMongoIndexEditorEnabled": [Function],
"isNotebookEnabled": [Function],
"isNotebooksEnabledForAccount": [Function],
"isNotificationConsoleExpanded": [Function],
@ -4829,7 +4822,6 @@ exports[`SettingsComponent renders 1`] = `
"isRightPanelV2Enabled": [Function],
"isSchemaEnabled": [Function],
"isServerlessEnabled": [Function],
"isSettingsV2Enabled": [Function],
"isSparkEnabled": [Function],
"isSparkEnabledForAccount": [Function],
"isSynapseLinkUpdating": [Function],

View File

@ -206,8 +206,6 @@ export default class Explorer {
public isGalleryPublishEnabled: ko.Computed<boolean>;
public isCodeOfConductEnabled: ko.Computed<boolean>;
public isLinkInjectionEnabled: ko.Computed<boolean>;
public isSettingsV2Enabled: ko.Observable<boolean>;
public isMongoIndexEditorEnabled: ko.Observable<boolean>;
public isGitHubPaneEnabled: ko.Observable<boolean>;
public isPublishNotebookPaneEnabled: ko.Observable<boolean>;
public isCopyNotebookPaneEnabled: ko.Observable<boolean>;
@ -412,8 +410,6 @@ export default class Explorer {
this.isLinkInjectionEnabled = ko.computed<boolean>(() =>
this.isFeatureEnabled(Constants.Features.enableLinkInjection)
);
this.isSettingsV2Enabled = ko.observable(false);
this.isMongoIndexEditorEnabled = ko.observable(false);
this.isGitHubPaneEnabled = ko.observable<boolean>(false);
this.isPublishNotebookPaneEnabled = ko.observable<boolean>(false);
this.isCopyNotebookPaneEnabled = ko.observable<boolean>(false);
@ -1913,14 +1909,6 @@ export default class Explorer {
if (!flights) {
return;
}
if (flights.indexOf(Constants.Flights.SettingsV2) !== -1) {
this.isSettingsV2Enabled(true);
}
if (flights.indexOf(Constants.Flights.MongoIndexEditor) !== -1) {
this.isMongoIndexEditorEnabled(true);
}
}
public findSelectedCollection(): ViewModels.Collection {

View File

@ -1,723 +0,0 @@
<div
class="tab-pane flexContainer"
data-bind="
attr:{
id: tabId
},
visible: isActive"
role="tabpanel"
>
<div class="warningErrorContainer scaleWarningContainer" data-bind="visible: shouldShowStatusBar">
<div>
<div class="warningErrorContent" data-bind="visible: shouldShowNotificationStatusPrompt">
<span><img src="/info_color.svg" alt="Info"/></span>
<span class="warningErrorDetailsLinkContainer" data-bind="html: notificationStatusInfo"></span>
</div>
<div class="warningErrorContent" data-bind="visible: !shouldShowNotificationStatusPrompt()">
<span><img src="/warning.svg" alt="Warning"/></span>
<span class="warningErrorDetailsLinkContainer" data-bind="html: warningMessage"></span>
</div>
</div>
</div>
<div class="tabForm scaleSettingScrollable">
<!-- ko if: shouldShowKeyspaceSharedThroughputMessage -->
<div>This table shared throughput is configured at the keyspace</div>
<!-- /ko -->
<!-- ko ifnot: hasDatabaseSharedThroughput -->
<div>
<div
class="scaleDivison"
data-bind="click:toggleScale, event: { keypress: onScaleKeyPress }, attr:{ 'aria-expanded': scaleExpanded() ? 'true' : 'false' }"
role="button"
tabindex="0"
aria-label="Scale"
aria-controls="scaleRegion"
>
<span class="themed-images" type="text/html" id="ExpandChevronRightScale" data-bind="visible: !scaleExpanded()">
<img
class="imgiconwidth ssExpandCollapseIcon ssCollapseIcon "
src="/Triangle-right.svg"
alt="Show scale properties"
/>
</span>
<span class="themed-images" type="text/html" id="ExpandChevronDownScale" data-bind="visible: scaleExpanded">
<img class="imgiconwidth ssExpandCollapseIcon " src="/Triangle-down.svg" alt="Hide scale properties" />
</span>
<span class="scaleSettingTitle">Scale</span>
</div>
<div class="ssTextAllignment" data-bind="visible: scaleExpanded" id="scaleRegion">
<!-- ko ifnot: isAutoScaleEnabled -->
<throughput-input-autopilot-v3
params="{
testId: testId,
class: 'scaleForm dirty',
value: throughput,
minimum: minRUs,
maximum: maxRUThroughputInputLimit,
isEnabled: !hasDatabaseSharedThroughput(),
canExceedMaximumValue: canThroughputExceedMaximumValue,
label: throughputTitle,
ariaLabel: throughputAriaLabel,
costsVisible: costsVisible,
requestUnitsUsageCost: requestUnitsUsageCost,
throughputAutoPilotRadioId: throughputAutoPilotRadioId,
throughputProvisionedRadioId: throughputProvisionedRadioId,
throughputModeRadioName: throughputModeRadioName,
showAutoPilot: userCanChangeProvisioningTypes,
isAutoPilotSelected: isAutoPilotSelected,
maxAutoPilotThroughputSet: autoPilotThroughput,
autoPilotUsageCost: autoPilotUsageCost,
overrideWithAutoPilotSettings: overrideWithAutoPilotSettings,
overrideWithProvisionedThroughputSettings: overrideWithProvisionedThroughputSettings
}"
>
</throughput-input-autopilot-v3>
<div class="storageCapacityTitle throughputStorageValue" data-bind="html: storageCapacityTitle"></div>
<!-- /ko -->
<div data-bind="visible: rupmVisible">
<div class="formTitle">RU/m</div>
<div class="tabs" aria-label="RU/m">
<div class="tab">
<label
data-bind="
attr:{
for: rupmOnId
},
css: {
dirty: rupm.editableIsDirty,
selectedRadio: rupm() === 'on',
unselectedRadio: rupm() !== 'on'
}"
>On</label
>
<input
type="radio"
name="rupm"
value="on"
class="radio"
data-bind="
attr:{
id: rupmOnId
},
checked: rupm"
/>
</div>
<div class="tab">
<label
data-bind="
attr:{
for: rupmOffId
},
css: {
dirty: rupm.editableIsDirty,
selectedRadio: rupm() === 'off',
unselectedRadio: rupm() !== 'off'
}"
>Off</label
>
<input
type="radio"
name="rupm"
value="off"
class="radio"
data-bind="
attr:{
id: rupmOffId
},
checked: rupm"
/>
</div>
</div>
</div>
<!-- TODO: Replace link with call to the Azure Support blade -->
<div data-bind="visible: isAutoScaleEnabled">
<div class="autoScaleThroughputTitle">Throughput (RU/s)</div>
<input
class="formReadOnly collid-white"
readonly
aria-label="Throughput input"
data-bind="textInput: throughput"
/>
<div class="autoScaleDescription">
Your account has custom settings that prevents setting throughput at the container level. Please work with
your Cosmos DB engineering team point of contact to make changes.
</div>
</div>
</div>
</div>
<!-- /ko -->
<div data-bind="visible: hasConflictResolution">
<div
class="formTitle"
data-bind="click:toggleConflictResolution, event: { keypress: onConflictResolutionKeyPress }, attr:{ 'aria-expanded': conflictResolutionExpanded() ? 'true' : 'false' }"
role="button"
tabindex="0"
aria-label="Conflict Resolution"
aria-controls="conflictResolutionRegion"
>
<span
class="themed-images"
type="text/html"
id="ExpandChevronRightConflictResolution"
data-bind="visible: !conflictResolutionExpanded()"
>
<img
class="imgiconwidth ssExpandCollapseIcon ssCollapseIcon"
src="/Triangle-right.svg"
alt="Show conflict resolution"
/>
</span>
<span
class="themed-images"
type="text/html"
id="ExpandChevronDownConflictResolution"
data-bind="visible: conflictResolutionExpanded"
>
<img class="imgiconwidth ssExpandCollapseIcon" src="/Triangle-down.svg" alt="Show conflict resolution" />
</span>
<span class="scaleSettingTitle">Conflict resolution</span>
</div>
<div id="conflictResolutionRegion" class="ssTextAllignment" data-bind="visible: conflictResolutionExpanded">
<div class="formTitle">Mode</div>
<div class="tabs" aria-label="Mode" role="radiogroup">
<div class="tab">
<label
tabindex="0"
role="radio"
data-bind="
attr:{
for: conflictResolutionPolicyModeLWW,
'aria-checked': conflictResolutionPolicyMode() !== 'Custom' ? 'true' : 'false'
},
css: {
dirty: conflictResolutionPolicyMode.editableIsDirty,
selectedRadio: conflictResolutionPolicyMode() === 'LastWriterWins',
unselectedRadio: conflictResolutionPolicyMode() !== 'LastWriterWins'
},
event: {
keypress: onConflictResolutionLWWKeyPress
}"
>Last Write Wins (default)</label
>
<input
type="radio"
name="conflictresolution"
value="LastWriterWins"
class="radio"
data-bind="
attr:{
id: conflictResolutionPolicyModeLWW
},
checked: conflictResolutionPolicyMode"
/>
</div>
<div class="tab">
<label
tabindex="0"
role="radio"
data-bind="
attr:{
for: conflictResolutionPolicyModeCustom,
'aria-checked': conflictResolutionPolicyMode() === 'Custom' ? 'true' : 'false'
},
css: {
dirty: conflictResolutionPolicyMode.editableIsDirty,
selectedRadio: conflictResolutionPolicyMode() === 'Custom',
unselectedRadio: conflictResolutionPolicyMode() !== 'Custom'
},
event: {
keypress: onConflictResolutionCustomKeyPress
}"
>Merge Procedure (custom)</label
>
<input
type="radio"
name="conflictresolution"
value="Custom"
class="radio"
data-bind="
attr:{
id: conflictResolutionPolicyModeCustom
},
checked: conflictResolutionPolicyMode"
/>
</div>
</div>
<div data-bind="visible: conflictResolutionPolicyMode() === 'LastWriterWins'">
<p class="formTitle">
Conflict Resolver Property
<span class="infoTooltip" role="tooltip" tabindex="0">
<img class="infoImg" src="/info-bubble.svg" alt="More information" />
<span class="tooltiptext infoTooltipWidth"
>Gets or sets the name of a integer property in your documents which is used for the Last Write Wins
(LWW) based conflict resolution scheme. By default, the system uses the system defined timestamp
property, _ts to decide the winner for the conflicting versions of the document. Specify your own
integer property if you want to override the default timestamp based conflict resolution.</span
>
</span>
</p>
<p>
<input
type="text"
aria-label="Document path for conflict resolution"
data-bind="
css: {
dirty: conflictResolutionPolicyPath.editableIsDirty
},
textInput: conflictResolutionPolicyPath,
enable: conflictResolutionPolicyMode() === 'LastWriterWins'"
/>
</p>
</div>
<div data-bind="visible: conflictResolutionPolicyMode() === 'Custom'">
<p class="formTitle">
Stored procedure
<span class="infoTooltip" role="tooltip" tabindex="0">
<img class="infoImg" src="/info-bubble.svg" alt="More information" />
<span class="tooltiptext infoTooltipWidth"
>Gets or sets the name of a stored procedure (aka merge procedure) for resolving the conflicts. You can
write application defined logic to determine the winner of the conflicting versions of a document. The
stored procedure will get executed transactionally, exactly once, on the server side. If you do not
provide a stored procedure, the conflicts will be populated in the
<a class="linkDarkBackground" href="https://aka.ms/dataexplorerconflics" target="_blank"
>conflicts feed</a
>. You can update/re-register the stored procedure at any time.</span
>
</span>
</p>
<p>
<input
type="text"
aria-label="Stored procedure name for conflict resolution"
data-bind="
css: {
dirty: conflictResolutionPolicyProcedure.editableIsDirty
},
textInput: conflictResolutionPolicyProcedure,
enable: conflictResolutionPolicyMode() === 'Custom'"
/>
</p>
</div>
</div>
</div>
<div
class="formTitle"
data-bind="click:toggleSettings, event: { keypress: onSettingsKeyPress }, attr:{ 'aria-expanded': settingsExpanded() ? 'true' : 'false' }, visible: shouldShowIndexingPolicyEditor() || ttlVisible()"
role="button"
tabindex="0"
aria-label="Settings"
aria-controls="settingsRegion"
>
<span
class="themed-images"
type="text/html"
id="ExpandChevronRightSettings"
data-bind="visible: !settingsExpanded() && !hasDatabaseSharedThroughput()"
>
<img class="imgiconwidth ssExpandCollapseIcon ssCollapseIcon" src="/Triangle-right.svg" alt="Show settings" />
</span>
<span
class="themed-images"
type="text/html"
id="ExpandChevronDownSettings"
data-bind="visible: settingsExpanded() && !hasDatabaseSharedThroughput()"
>
<img class="imgiconwidth ssExpandCollapseIcon" src="/Triangle-down.svg" alt="Show settings" />
</span>
<span class="scaleSettingTitle">Settings</span>
</div>
<div class="ssTextAllignment" data-bind="visible: settingsExpanded" id="settingsRegion">
<div data-bind="visible: ttlVisible">
<div class="formTitle">Time to Live</div>
<div class="tabs disableFocusDefaults" aria-label="Time to Live" role="radiogroup">
<div class="tab">
<label
class="ttlIndexingPolicyFocusElement"
tabindex="0"
role="radio"
data-bind="
attr:{
for: ttlOffId,
'aria-checked': timeToLive() === 'off' ? 'true' : 'false'
},
css: {
dirty: timeToLive.editableIsDirty,
selectedRadio: timeToLive() === 'off',
unselectedRadio: timeToLive() !== 'off'
},
event: {
keypress: onTtlOffKeyPress
},
hasFocus: ttlOffFocused"
>Off</label
>
<input
type="radio"
name="ttl"
value="off"
class="radio"
data-bind="
attr:{
id: ttlOffId
},
checked: timeToLive"
/>
</div>
<div class="tab">
<label
class="ttlIndexingPolicyFocusElement"
tabindex="0"
role="radio"
data-bind="
attr:{
for: ttlOnNoDefaultId,
'aria-checked': timeToLive() === 'on-nodefault' ? 'true' : 'false'
},
css: {
dirty: timeToLive.editableIsDirty,
selectedRadio: timeToLive() === 'on-nodefault',
unselectedRadio: timeToLive() !== 'on-nodefault'
},
event: {
keypress: onTtlOnNoDefaultKeyPress
},
hasFocus: ttlOnDefaultFocused"
>On (no default)</label
>
<input
type="radio"
name="ttl"
value="on-nodefault"
class="radio"
data-bind="
attr:{
id: ttlOnNoDefaultId
},
checked: timeToLive"
/>
</div>
<div class="tab">
<label
class="ttlIndexingPolicyFocusElement"
tabindex="0"
role="radio"
for="ttl3"
data-bind="
attr:{
for: ttlOnId,
'aria-checked': timeToLive() === 'on' ? 'true' : 'false'
},
css: {
dirty: timeToLive.editableIsDirty,
selectedRadio: timeToLive() === 'on',
unselectedRadio: timeToLive() !== 'on'
},
event: {
keypress: onTtlOnKeyPress
},
hasFocus: ttlOnFocused"
>On</label
>
<input
type="radio"
name="ttl"
value="on"
class="radio"
data-bind="
attr:{
id: ttlOnId
},
checked: timeToLive"
/>
</div>
</div>
<div data-bind="visible: timeToLive() === 'on'">
<input
class="dirtyTextbox"
type="number"
required
min="1"
max="2147483647"
aria-label="Time to live in seconds"
data-bind="
css: {
dirty: timeToLive.editableIsDirty
},
textInput: timeToLiveSeconds,
enable: timeToLive() === 'on'"
/>
second(s)
</div>
</div>
<!-- Geospatial - start -->
<div data-bind="visible: geospatialVisible">
<div class="formTitle">Geospatial Configuration</div>
<div class="tabs disableFocusDefaults" aria-label="Geospatial Configuration" role="radiogroup">
<div class="tab">
<label
for="geography"
tabindex="0"
role="radio"
data-bind="
attr:{
'aria-checked': geospatialConfigType().toLowerCase() !== GEOMETRY.toLowerCase() ? 'true' : 'false'
},
css: {
dirty: geospatialConfigType.editableIsDirty,
selectedRadio: geospatialConfigType().toLowerCase() !== GEOMETRY.toLowerCase(),
unselectedRadio: geospatialConfigType().toLowerCase() === GEOMETRY.toLowerCase()
},
event: {
keypress: onGeographyKeyPress
}"
>Geography</label
>
<input
type="radio"
name="geospatial"
id="geography"
class="radio"
data-bind="
attr: {
value: GEOGRAPHY
},
checked: geospatialConfigType"
/>
</div>
<div class="tab">
<label
for="geometry"
tabindex="0"
role="radio"
data-bind="
attr:{
'aria-checked': geospatialConfigType().toLowerCase() === GEOMETRY.toLowerCase() ? 'true' : 'false'
},
css: {
dirty: geospatialConfigType.editableIsDirty,
selectedRadio: geospatialConfigType().toLowerCase() === GEOMETRY.toLowerCase(),
unselectedRadio: geospatialConfigType().toLowerCase() !== GEOMETRY.toLowerCase()
},
event: {
keypress: onGeometryKeyPress
}"
>Geometry</label
>
<input
type="radio"
name="geospatial"
id="geometry"
class="radio"
data-bind="
attr: {
value: GEOMETRY
},
checked: geospatialConfigType"
/>
</div>
</div>
</div>
<!-- Geospatial - end -->
<div data-bind="visible: isAnalyticalStorageEnabled">
<div class="formTitle">Analytical Storage Time to Live</div>
<div class="tabs disableFocusDefaults" aria-label="Analytical Storage Time to Live" role="radiogroup">
<div class="tab">
<label tabindex="0" role="radio" class="disabledRadio">Off </label>
</div>
<div class="tab">
<label
tabindex="0"
role="radio"
data-bind="
attr:{
for: 'analyticalStorageTtlOnNoDefaultId',
'aria-checked': analyticalStorageTtlSelection() === 'on-nodefault' ? 'true' : 'false'
},
css: {
dirty: analyticalStorageTtlSelection.editableIsDirty,
selectedRadio: analyticalStorageTtlSelection() === 'on-nodefault',
unselectedRadio: analyticalStorageTtlSelection() !== 'on-nodefault'
},
event: {
keypress: onAnalyticalStorageTtlOnNoDefaultKeyPress
}"
>On (no default)
</label>
<input
type="radio"
name="analyticalStorageTtl"
value="on-nodefault"
class="radio"
data-bind="
attr:{
id: 'analyticalStorageTtlOnNoDefaultId'
},
checked: analyticalStorageTtlSelection"
/>
</div>
<div class="tab">
<label
tabindex="0"
role="radio"
for="ttl3"
data-bind="
attr:{
for: 'analyticalStorageTtlOnId',
'aria-checked': analyticalStorageTtlSelection() === 'on' ? 'true' : 'false'
},
css: {
dirty: analyticalStorageTtlSelection.editableIsDirty,
selectedRadio: analyticalStorageTtlSelection() === 'on',
unselectedRadio: analyticalStorageTtlSelection() !== 'on'
},
event: {
keypress: onAnalyticalStorageTtlOnKeyPress
}"
>On</label
>
<input
type="radio"
name="analyticalStorageTtl"
value="on"
class="radio"
data-bind="
attr:{
id: 'analyticalStorageTtlOnId'
},
checked: analyticalStorageTtlSelection"
/>
</div>
</div>
<div data-bind="visible: analyticalStorageTtlSelection() === 'on'">
<input
class="dirtyTextbox"
type="number"
required
min="1"
max="2147483647"
aria-label="Time to live in seconds"
data-bind="
css: {
dirty: analyticalStorageTtlSelection.editableIsDirty
},
textInput: analyticalStorageTtlSeconds,
enable: analyticalStorageTtlSelection() === 'on'"
/>
second(s)
</div>
</div>
<div data-bind="visible: changeFeedPolicyVisible">
<div class="formTitle">
<span>Change feed log retention policy</span>
<span class="infoTooltip" role="tooltip" tabindex="0">
<img class="infoImg" src="/info-bubble.svg" alt="More information" />
<span class="tooltiptext infoTooltipWidth"
>Enable change feed log retention policy to retain last 10 minutes of history for items in the container
by default. To support this, the request unit (RU) charge for this container will be multiplied by a
factor of two for writes. Reads are unaffected.</span
>
</span>
</div>
<div class="tabs disableFocusDefaults" aria-label="Change feed selection tabs">
<div class="tab">
<label
tabindex="0"
data-bind="
attr:{
for: changeFeedPolicyOffId
},
css: {
dirty: changeFeedPolicyToggled.editableIsDirty,
selectedRadio: changeFeedPolicyToggled() === 'Off',
unselectedRadio: changeFeedPolicyToggled() === 'On'
},
event: {
keypress: onChangeFeedPolicyOffKeyPress
}"
>Off</label
>
<input
type="radio"
name="changeFeedPolicy"
value="Off"
class="radio"
data-bind="
attr:{
id: changeFeedPolicyOffId
},
checked: changeFeedPolicyToggled"
/>
</div>
<div class="tab">
<label
tabindex="0"
data-bind="
attr:{
for: changeFeedPolicyOnId
},
css: {
dirty: changeFeedPolicyToggled.editableIsDirty,
selectedRadio: changeFeedPolicyToggled() === 'On',
unselectedRadio: changeFeedPolicyToggled() === 'Off'
},
event: {
keypress: onChangeFeedPolicyOnKeyPress
}"
>On</label
>
<input
type="radio"
name="changeFeedPolicy"
value="On"
class="radio"
data-bind="
attr:{
id: changeFeedPolicyOnId
},
checked: changeFeedPolicyToggled"
/>
</div>
</div>
</div>
<div data-bind="visible: partitionKeyVisible">
<div class="formTitle" data-bind="text: partitionKeyName">Partition Key</div>
<input
class="formReadOnly collid-white"
data-bind="textInput: partitionKeyValue, attr: { 'aria-label':partitionKeyName }"
readonly
/>
</div>
<div class="largePartitionKeyEnabled" data-bind="visible: isLargePartitionKeyEnabled">
<p data-bind="visible: isLargePartitionKeyEnabled">
Large <span data-bind="text:lowerCasePartitionKeyName"></span> has been enabled
</p>
</div>
<div data-bind="visible: shouldShowIndexingPolicyEditor">
<div class="formTitle">Indexing Policy</div>
<div
class="indexingPolicyEditor ttlIndexingPolicyFocusElement"
tabindex="0"
data-bind="setTemplateReady: true, attr:{ id: indexingPolicyEditorId }"
></div>
</div>
</div>
</div>
</div>

View File

@ -1,449 +0,0 @@
import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
import Collection from "../Tree/Collection";
import Database from "../Tree/Database";
import Explorer from "../Explorer";
import SettingsTab from "./SettingsTab";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import { IndexingPolicies } from "../../Shared/Constants";
describe("Settings tab", () => {
const baseCollection: DataModels.Collection = {
defaultTtl: 200,
partitionKey: null,
conflictResolutionPolicy: {
mode: DataModels.ConflictResolutionMode.LastWriterWins,
conflictResolutionPath: "/_ts"
},
indexingPolicy: IndexingPolicies.SharedDatabaseDefault,
_rid: "",
_self: "",
_etag: "",
_ts: 0,
id: "mycoll"
};
const baseDatabase: DataModels.Database = {
_rid: "",
_self: "",
_etag: "",
_ts: 0,
id: "mydb",
collections: [baseCollection]
};
const quotaInfo: DataModels.CollectionQuotaInfo = {
storedProcedures: 0,
triggers: 0,
functions: 0,
documentsSize: 0,
documentsCount: 0,
collectionSize: 0,
usageSizeInKB: 0,
numPartitions: 0
};
describe("Conflict Resolution", () => {
describe("should show conflict resolution", () => {
let explorer: Explorer;
const baseCollectionWithoutConflict: DataModels.Collection = {
defaultTtl: 200,
partitionKey: null,
conflictResolutionPolicy: null,
indexingPolicy: IndexingPolicies.SharedDatabaseDefault,
_rid: "",
_self: "",
_etag: "",
_ts: 0,
id: "mycoll"
};
const getSettingsTab = (conflictResolution: boolean = true) => {
return new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(
explorer,
"mydb",
conflictResolution ? baseCollection : baseCollectionWithoutConflict,
quotaInfo,
null
),
onUpdateTabsButtons: undefined
});
};
beforeEach(() => {
explorer = new Explorer();
});
it("single master, should not show conflict resolution", () => {
const settingsTab = getSettingsTab();
expect(settingsTab.hasConflictResolution()).toBe(false);
});
it("multi master with resolution conflict, show conflict resolution", () => {
explorer.databaseAccount({
id: "test",
kind: "",
location: "",
name: "",
tags: "",
type: "",
properties: {
enableMultipleWriteLocations: true,
documentEndpoint: "",
cassandraEndpoint: "",
gremlinEndpoint: "",
tableEndpoint: ""
}
});
const settingsTab = getSettingsTab();
expect(settingsTab.hasConflictResolution()).toBe(true);
});
it("multi master without resolution conflict, show conflict resolution", () => {
explorer.databaseAccount({
id: "test",
kind: "",
location: "",
name: "",
tags: "",
type: "",
properties: {
enableMultipleWriteLocations: true,
documentEndpoint: "",
cassandraEndpoint: "",
gremlinEndpoint: "",
tableEndpoint: ""
}
});
const settingsTab = getSettingsTab(false /* no resolution conflict*/);
expect(settingsTab.hasConflictResolution()).toBe(false);
});
});
describe("Parse Conflict Resolution Mode from backend", () => {
it("should parse any casing", () => {
expect(SettingsTab.parseConflictResolutionMode("custom")).toBe(DataModels.ConflictResolutionMode.Custom);
expect(SettingsTab.parseConflictResolutionMode("Custom")).toBe(DataModels.ConflictResolutionMode.Custom);
expect(SettingsTab.parseConflictResolutionMode("lastWriterWins")).toBe(
DataModels.ConflictResolutionMode.LastWriterWins
);
expect(SettingsTab.parseConflictResolutionMode("LastWriterWins")).toBe(
DataModels.ConflictResolutionMode.LastWriterWins
);
});
it("should parse empty as null", () => {
expect(SettingsTab.parseConflictResolutionMode("")).toBe(null);
});
it("should parse null as null", () => {
expect(SettingsTab.parseConflictResolutionMode(null)).toBe(null);
});
});
describe("Parse Conflict Resolution procedure from backend", () => {
it("should parse path as name", () => {
expect(SettingsTab.parseConflictResolutionProcedure("/dbs/xxxx/colls/xxxx/sprocs/validsproc")).toBe(
"validsproc"
);
});
it("should parse name as name", () => {
expect(SettingsTab.parseConflictResolutionProcedure("validsproc")).toBe("validsproc");
});
it("should parse invalid path as null", () => {
expect(SettingsTab.parseConflictResolutionProcedure("/not/a/valid/path")).toBe(null);
});
it("should parse empty or null as null", () => {
expect(SettingsTab.parseConflictResolutionProcedure("")).toBe(null);
expect(SettingsTab.parseConflictResolutionProcedure(null)).toBe(null);
});
});
});
describe("Should update collection", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer();
});
it("On TTL changed", () => {
const settingsTab = new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
expect(settingsTab.shouldUpdateCollection()).toBe(false);
settingsTab.timeToLive("off");
expect(settingsTab.shouldUpdateCollection()).toBe(true);
settingsTab.onRevertClick();
expect(settingsTab.shouldUpdateCollection()).toBe(false);
settingsTab.timeToLiveSeconds(100);
expect(settingsTab.shouldUpdateCollection()).toBe(true);
});
it("On Index Policy changed", () => {
const settingsTab = new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
expect(settingsTab.shouldUpdateCollection()).toBe(false);
settingsTab.indexingPolicyContent({ somethingDifferent: "" });
expect(settingsTab.shouldUpdateCollection()).toBe(true);
});
it("On Conflict Resolution Mode changed", () => {
const settingsTab = new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
expect(settingsTab.shouldUpdateCollection()).toBe(false);
settingsTab.conflictResolutionPolicyMode(DataModels.ConflictResolutionMode.Custom);
expect(settingsTab.shouldUpdateCollection()).toBe(true);
settingsTab.onRevertClick();
expect(settingsTab.shouldUpdateCollection()).toBe(false);
settingsTab.conflictResolutionPolicyPath("/somethingElse");
expect(settingsTab.shouldUpdateCollection()).toBe(true);
settingsTab.onRevertClick();
expect(settingsTab.shouldUpdateCollection()).toBe(false);
settingsTab.conflictResolutionPolicyMode(DataModels.ConflictResolutionMode.Custom);
settingsTab.conflictResolutionPolicyProcedure("resolver");
expect(settingsTab.shouldUpdateCollection()).toBe(true);
});
});
describe("Get Conflict Resolution configuration from user", () => {
let explorer: Explorer;
beforeEach(() => {
explorer = new Explorer();
});
it("null if it didnt change", () => {
const settingsTab = new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
});
it("Custom contains valid backend path", () => {
const settingsTab = new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
settingsTab.conflictResolutionPolicyMode(DataModels.ConflictResolutionMode.Custom);
settingsTab.conflictResolutionPolicyProcedure("resolver");
let updatedPolicy = settingsTab.getUpdatedConflictResolutionPolicy();
expect(updatedPolicy.mode).toBe(DataModels.ConflictResolutionMode.Custom);
expect(updatedPolicy.conflictResolutionProcedure).toBe("/dbs/mydb/colls/mycoll/sprocs/resolver");
settingsTab.conflictResolutionPolicyProcedure("");
updatedPolicy = settingsTab.getUpdatedConflictResolutionPolicy();
expect(updatedPolicy.conflictResolutionProcedure).toBe(undefined);
});
it("LWW contains valid property path", () => {
const settingsTab = new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: new Collection(explorer, "mydb", baseCollection, quotaInfo, null),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
expect(settingsTab.getUpdatedConflictResolutionPolicy()).toBe(null);
settingsTab.conflictResolutionPolicyPath("someAttr");
let updatedPolicy = settingsTab.getUpdatedConflictResolutionPolicy();
expect(updatedPolicy.conflictResolutionPath).toBe("/someAttr");
settingsTab.conflictResolutionPolicyPath("/someAttr");
updatedPolicy = settingsTab.getUpdatedConflictResolutionPolicy();
expect(updatedPolicy.conflictResolutionPath).toBe("/someAttr");
settingsTab.conflictResolutionPolicyPath("");
updatedPolicy = settingsTab.getUpdatedConflictResolutionPolicy();
expect(updatedPolicy.conflictResolutionPath).toBe("");
});
});
describe("partitionKeyVisible", () => {
enum PartitionKeyOption {
None,
System,
NonSystem
}
function getCollection(defaultApi: string, partitionKeyOption: PartitionKeyOption) {
const explorer = new Explorer();
explorer.defaultExperience(defaultApi);
const offer: DataModels.Offer = null;
const defaultTtl = 200;
const conflictResolutionPolicy = {
mode: DataModels.ConflictResolutionMode.LastWriterWins,
conflictResolutionPath: "/_ts"
};
return new Collection(
explorer,
"mydb",
{
defaultTtl: defaultTtl,
partitionKey:
partitionKeyOption != PartitionKeyOption.None
? {
paths: ["/foo"],
kind: "Hash",
version: 2,
systemKey: partitionKeyOption === PartitionKeyOption.System
}
: null,
conflictResolutionPolicy: conflictResolutionPolicy,
indexingPolicy: IndexingPolicies.SharedDatabaseDefault,
_rid: "",
_self: "",
_etag: "",
_ts: 0,
id: "mycoll"
},
quotaInfo,
offer
);
}
function getSettingsTab(defaultApi: string, partitionKeyOption: PartitionKeyOption): SettingsTab {
return new SettingsTab({
tabKind: ViewModels.CollectionTabKind.Settings,
title: "Scale & Settings",
tabPath: "",
hashLocation: "",
isActive: ko.observable(false),
collection: getCollection(defaultApi, partitionKeyOption),
onUpdateTabsButtons: (buttons: CommandButtonComponentProps[]): void => {}
});
}
it("on SQL container with no partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.DocumentDB, PartitionKeyOption.None);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Mongo container with no partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.MongoDB, PartitionKeyOption.None);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Gremlin container with no partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Graph, PartitionKeyOption.None);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Cassandra container with no partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Cassandra, PartitionKeyOption.None);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Table container with no partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Table, PartitionKeyOption.None);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on SQL container with system partition key should be true", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.DocumentDB, PartitionKeyOption.System);
expect(settingsTab.partitionKeyVisible()).toBe(true);
});
it("on Mongo container with system partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.MongoDB, PartitionKeyOption.System);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Gremlin container with system partition key should be true", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Graph, PartitionKeyOption.System);
expect(settingsTab.partitionKeyVisible()).toBe(true);
});
it("on Cassandra container with system partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Cassandra, PartitionKeyOption.System);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Table container with system partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Table, PartitionKeyOption.System);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on SQL container with non-system partition key should be true", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.DocumentDB, PartitionKeyOption.NonSystem);
expect(settingsTab.partitionKeyVisible()).toBe(true);
});
it("on Mongo container with non-system partition key should be true", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.MongoDB, PartitionKeyOption.NonSystem);
expect(settingsTab.partitionKeyVisible()).toBe(true);
});
it("on Gremlin container with non-system partition key should be true", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Graph, PartitionKeyOption.NonSystem);
expect(settingsTab.partitionKeyVisible()).toBe(true);
});
it("on Cassandra container with non-system partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Cassandra, PartitionKeyOption.NonSystem);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
it("on Table container with non-system partition key should be false", () => {
const settingsTab = getSettingsTab(Constants.DefaultAccountExperience.Table, PartitionKeyOption.NonSystem);
expect(settingsTab.partitionKeyVisible()).toBe(false);
});
});
});

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,7 @@ export default class SettingsTabV2 extends TabsBase {
this.currentCollection.loadOffer().then(
() => {
// passed in options and set by parent as "Settings" by default
this.tabTitle("Scale & Settings");
this.tabTitle(this.currentCollection.offer() ? "Settings" : "Scale & Settings");
this.offerRead(true);
this.options.getPendingNotification.then(
(data: DataModels.Notification) => {

View File

@ -9,7 +9,6 @@ import MongoQueryTabTemplate from "./MongoQueryTab.html";
import MongoShellTabTemplate from "./MongoShellTab.html";
import QueryTabTemplate from "./QueryTab.html";
import QueryTablesTabTemplate from "./QueryTablesTab.html";
import SettingsTabTemplate from "./SettingsTab.html";
import SettingsTabV2Template from "./SettingsTabV2.html";
import DatabaseSettingsTabTemplate from "./DatabaseSettingsTab.html";
import StoredProcedureTabTemplate from "./StoredProcedureTab.html";
@ -133,15 +132,6 @@ export class QueryTablesTab {
}
}
export class SettingsTab {
constructor() {
return {
viewModel: TabComponent,
template: SettingsTabTemplate
};
}
}
export class SettingsTabV2 {
constructor() {
return {

View File

@ -29,7 +29,6 @@ import MongoShellTab from "../Tabs/MongoShellTab";
import QueryTab from "../Tabs/QueryTab";
import QueryTablesTab from "../Tabs/QueryTablesTab";
import SettingsTabV2 from "../Tabs/SettingsTabV2";
import SettingsTab from "../Tabs/SettingsTab";
import ConflictId from "./ConflictId";
import DocumentId from "./DocumentId";
import StoredProcedure from "./StoredProcedure";
@ -556,11 +555,6 @@ export default class Collection implements ViewModels.Collection {
dataExplorerArea: Constants.Areas.ResourceTree
});
const isSettingsV2Enabled = this.container.isSettingsV2Enabled();
if (!isSettingsV2Enabled) {
await this.loadOffer();
}
const tabTitle = !this.offer() ? "Settings" : "Scale & Settings";
const pendingNotificationsPromise: Q.Promise<DataModels.Notification> = this._getPendingThroughputSplitNotification();
const matchingTabs = this.container.tabsManager.getTabs(ViewModels.CollectionTabKind.Settings, tab => {
@ -587,68 +581,8 @@ export default class Collection implements ViewModels.Collection {
onUpdateTabsButtons: this.container.onUpdateTabsButtons
};
if (isSettingsV2Enabled) {
let settingsTabV2 = matchingTabs && (matchingTabs[0] as SettingsTabV2);
this.launchSettingsTabV2(settingsTabV2, traceStartData, settingsTabOptions, pendingNotificationsPromise);
} else {
let settingsTab = matchingTabs && (matchingTabs[0] as SettingsTab);
this.launchSettingsTabV1(settingsTab, traceStartData, settingsTabOptions, pendingNotificationsPromise);
}
};
private launchSettingsTabV1 = (
settingsTab: SettingsTab,
traceStartData: any,
settingsTabOptions: ViewModels.TabOptions,
getPendingNotification: Q.Promise<DataModels.Notification>
): void => {
if (!settingsTab) {
const startKey: number = TelemetryProcessor.traceStart(Action.Tab, traceStartData);
settingsTabOptions.onLoadStartKey = startKey;
getPendingNotification.then(
(data: any) => {
const pendingNotification: DataModels.Notification = data && data[0];
settingsTabOptions.tabKind = ViewModels.CollectionTabKind.Settings;
settingsTab = new SettingsTab(settingsTabOptions);
this.container.tabsManager.activateNewTab(settingsTab);
settingsTab.pendingNotification(pendingNotification);
},
(error: any) => {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure(
Action.Tab,
{
databaseAccountName: this.container.databaseAccount().name,
databaseName: this.databaseId,
collectionName: this.id(),
defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: settingsTabOptions.title,
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while fetching container settings for container ${this.id()}: ${errorMessage}`
);
throw error;
}
);
} else {
getPendingNotification.then(
(pendingNotification: DataModels.Notification) => {
settingsTab.pendingNotification(pendingNotification);
this.container.tabsManager.activateTab(settingsTab);
},
(error: any) => {
settingsTab.pendingNotification(undefined);
this.container.tabsManager.activateTab(settingsTab);
}
);
}
};
private launchSettingsTabV2 = (