mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-21 18:01:39 +00:00
Migrate DocumentsTab to React and add bulk delete and column resize (#1770)
* Document page now loads list of docs and displays selection * DocumentsTabV2 now properly loads documents, show partition keys and display first doc with proper selection behavior. Move it to its own folder. * Extract table in a separate component * Resizable columns on the document table * Fix selection behavior and some layout issue * Adding table scrolling * Fix NaN height issue * Fix NaN height issue * Fix column sizing + cell selection * Improvement in width size. Add Load More * Add react editor and pass column headers * Dynamic columns for pk * Fix initial columns size * Add nav buttons * Editing content updates buttons state * Discard and save buttons working * Fix save new document. Implement delete. * Remove debug display * Fix unexpand filter and reformat * Fix compil issues * Add refresh button * Update column header placeholder style * Implement delete multiple docs * Fix multi delete * Fix show/hide delete button * Fix selection behavior * Fix UX with buttons behavior and editor display * Fix UX issue with not discarding edit changes * Add some TODO's * Remove debugging info and reformat * Add mongo support * Fix build issues * Fix table header. Remove debug statement * Restore broken nosql * Fix mongo save new document/update document * Fix bugs with clicking on newly created documents * Fix comment * Fix double fetch issue when clicking on an item * Auto-select last document when saving new document * Fix resourceTokenPartitionKey code * Fix format * Fix isQueryCopilotSampleContainer flag * Fix unused code * Call tab when updating error flag * Destructure props to make useEffect dependencies work * Fix loadStartKey * minor update * Fix format * Add title to table * Fix table coming off its container with unwanted horizontal scrollbar * Increase table width. Fix eslint issue. * Move refresh documents button from table back to DocumentsTabV2 * Fix load more text centering * Don't show Load More if nothing to show * Fix columns min width * Add keyboard shortcuts * Add keyboard handlers to load more and refresh button * Add keyboard support to select table row * Disable eslint issue from fluent library * Connect cancel query button * Add Fluent V9 theme for Fabric (#1821) * Clean up dependencies and memoize internal functions and object. Move methods and object that don't depend on state outside of component. * Fix filter disappearing when clicking Apply Filter * Fix typo and format * Implement bulk delete for nosql * Replace filter ui components with fluent ui * Remove jquery calls * Migrate unit test to DocumentsTabV2 * Remove DocumentsTab and MongoDocumentsTab. Fix build issues. * Properly handle activetab * Remove comments and unused code * Port keyboard shortcuts from commitId1f4d0f2* Port item editor shortcuts to improved Items tab branch (#1831) * set filter focus on Ctrl+Shift+F * implement filter enter/esc keybinds * remove debugging * Collapse filter when query is executed * Fix monaco editor not happy when parent is null * Fix how bulk delete operation gets called when no partition key * Fix update id list after delete * Fix deleteDocuments * Fix build issue * Fix bug in mongo delete * Fix mongo delete flow * Proper error handling in mongo * Handle >100 bulk delete operations * Add unit tests for DocumentsTableComponent * More improvements to table unit tests * Fix import. Disable selection test for now * Add more DocumentsTab unit react tests * Remove selection test * Add more unit tests. Add lcov coverage report to display in vscode * Move unit tests to correct file * Add unit test on command bar * Fix build issues * Add more unit tests * Remove unneeded call * Add DocumentsTab for Mongo API * Fix linting errors * Update fluent ui v9 dependency. Color columns separation. Fix refresh button placement to not interfere with header cell width. * Revert @fluentui/react-components to a safe version that compiles * Add confirmation window when documents have been deleted * Fix mongo unit tests * Fix format * Update src/Common/dataAccess/deleteDocument.ts Co-authored-by: Ashley Stanton-Nurse <ashleyst@microsoft.com> * Update src/Common/dataAccess/deleteDocument.ts Co-authored-by: Ashley Stanton-Nurse <ashleyst@microsoft.com> * Update src/Common/dataAccess/deleteDocument.ts Co-authored-by: Ashley Stanton-Nurse <ashleyst@microsoft.com> * Fix bug with markup. Simplify code. * Protect against creating React editor without parent node * Replace rendering tests with snapshot match * Add test screenshot to troubleshoot e2e test * Revert "Add test screenshot to troubleshoot e2e test" This reverts commit1b8138ade0. * Attempt 2 at troubleshooting failing test * Revert "Attempt 2 at troubleshooting failing test" This reverts commit3e51a593bf. * Delete button now shows if one or more rows are selected --------- Co-authored-by: Vsevolod Kukol <sevoku@microsoft.com> Co-authored-by: Ashley Stanton-Nurse <ashleyst@microsoft.com>
This commit is contained in:
476
src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.test.tsx
Normal file
476
src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.test.tsx
Normal file
@@ -0,0 +1,476 @@
|
||||
import { FeedResponse, ItemDefinition, Resource } from "@azure/cosmos";
|
||||
import { deleteDocuments } from "Common/dataAccess/deleteDocument";
|
||||
import { Platform, updateConfigContext } from "ConfigContext";
|
||||
import { EditorReactProps } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import {
|
||||
ButtonsDependencies,
|
||||
DELETE_BUTTON_ID,
|
||||
DISCARD_BUTTON_ID,
|
||||
DocumentsTabComponent,
|
||||
IDocumentsTabComponentProps,
|
||||
NEW_DOCUMENT_BUTTON_ID,
|
||||
SAVE_BUTTON_ID,
|
||||
UPDATE_BUTTON_ID,
|
||||
UPLOAD_BUTTON_ID,
|
||||
buildQuery,
|
||||
getDiscardExistingDocumentChangesButtonState,
|
||||
getDiscardNewDocumentChangesButtonState,
|
||||
getSaveExistingDocumentButtonState,
|
||||
getSaveNewDocumentButtonState,
|
||||
getTabsButtons,
|
||||
showPartitionKey,
|
||||
} from "Explorer/Tabs/DocumentsTabV2/DocumentsTabV2";
|
||||
import { ReactWrapper, ShallowWrapper, mount, shallow } from "enzyme";
|
||||
import * as ko from "knockout";
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import { DatabaseAccount, DocumentId } from "../../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { updateUserContext } from "../../../UserContext";
|
||||
import Explorer from "../../Explorer";
|
||||
|
||||
jest.mock("Common/dataAccess/queryDocuments", () => ({
|
||||
queryDocuments: jest.fn(() => ({
|
||||
// Omit headers, because we can't mock a private field and we don't need to test it
|
||||
fetchNext: (): Promise<Omit<FeedResponse<ItemDefinition & Resource>, "headers">> =>
|
||||
Promise.resolve({
|
||||
resources: [{ id: "id", _rid: "rid", _self: "self", _etag: "etag", _ts: 123 }],
|
||||
hasMoreResults: false,
|
||||
diagnostics: undefined,
|
||||
|
||||
continuation: undefined,
|
||||
continuationToken: undefined,
|
||||
queryMetrics: "queryMetrics",
|
||||
requestCharge: 1,
|
||||
activityId: "activityId",
|
||||
indexMetrics: "indexMetrics",
|
||||
}),
|
||||
})),
|
||||
}));
|
||||
|
||||
const PROPERTY_VALUE = "__SOME_PROPERTY_VALUE__";
|
||||
jest.mock("Common/dataAccess/readDocument", () => ({
|
||||
readDocument: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
container: undefined,
|
||||
id: "id",
|
||||
property: PROPERTY_VALUE,
|
||||
}),
|
||||
),
|
||||
}));
|
||||
|
||||
jest.mock("Explorer/Controls/Editor/EditorReact", () => ({
|
||||
EditorReact: (props: EditorReactProps) => <>{props.content}</>,
|
||||
}));
|
||||
|
||||
jest.mock("Explorer/Controls/Dialog", () => ({
|
||||
useDialog: {
|
||||
getState: jest.fn(() => ({
|
||||
showOkCancelModalDialog: (title: string, subText: string, okLabel: string, onOk: () => void) => onOk(),
|
||||
showOkModalDialog: () => {},
|
||||
})),
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("Common/dataAccess/deleteDocument", () => ({
|
||||
deleteDocuments: jest.fn((collection: ViewModels.CollectionBase, documentIds: DocumentId[]) =>
|
||||
Promise.resolve(documentIds),
|
||||
),
|
||||
}));
|
||||
|
||||
async function waitForComponentToPaint<P = unknown>(wrapper: ReactWrapper<P> | ShallowWrapper<P>, amount = 0) {
|
||||
let newWrapper;
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, amount));
|
||||
newWrapper = wrapper.update();
|
||||
});
|
||||
return newWrapper;
|
||||
}
|
||||
|
||||
describe("Documents tab (noSql API)", () => {
|
||||
describe("buildQuery", () => {
|
||||
it("should generate the right select query for SQL API", () => {
|
||||
expect(buildQuery(false, "")).toContain("select");
|
||||
});
|
||||
});
|
||||
|
||||
describe("showPartitionKey", () => {
|
||||
const explorer = new Explorer();
|
||||
const mongoExplorer = new Explorer();
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
properties: {
|
||||
capabilities: [{ name: "EnableGremlin" }],
|
||||
},
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
const collectionWithoutPartitionKey: ViewModels.Collection = {
|
||||
id: ko.observable<string>("foo"),
|
||||
databaseId: "foo",
|
||||
container: explorer,
|
||||
} as ViewModels.Collection;
|
||||
|
||||
const collectionWithSystemPartitionKey: ViewModels.Collection = {
|
||||
id: ko.observable<string>("foo"),
|
||||
databaseId: "foo",
|
||||
partitionKey: {
|
||||
paths: ["/foo"],
|
||||
kind: "Hash",
|
||||
version: 2,
|
||||
systemKey: true,
|
||||
},
|
||||
container: explorer,
|
||||
} as ViewModels.Collection;
|
||||
|
||||
const collectionWithNonSystemPartitionKey: ViewModels.Collection = {
|
||||
id: ko.observable<string>("foo"),
|
||||
databaseId: "foo",
|
||||
partitionKey: {
|
||||
paths: ["/foo"],
|
||||
kind: "Hash",
|
||||
version: 2,
|
||||
systemKey: false,
|
||||
},
|
||||
container: explorer,
|
||||
} as ViewModels.Collection;
|
||||
|
||||
const mongoCollectionWithSystemPartitionKey: ViewModels.Collection = {
|
||||
id: ko.observable<string>("foo"),
|
||||
databaseId: "foo",
|
||||
partitionKey: {
|
||||
paths: ["/foo"],
|
||||
kind: "Hash",
|
||||
version: 2,
|
||||
systemKey: true,
|
||||
},
|
||||
container: mongoExplorer,
|
||||
} as ViewModels.Collection;
|
||||
|
||||
it("should be false for null or undefined collection", () => {
|
||||
expect(showPartitionKey(undefined, false)).toBe(false);
|
||||
expect(showPartitionKey(null, false)).toBe(false);
|
||||
expect(showPartitionKey(undefined, true)).toBe(false);
|
||||
expect(showPartitionKey(null, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("should be false for null or undefined partitionKey", () => {
|
||||
expect(showPartitionKey(collectionWithoutPartitionKey, false)).toBe(false);
|
||||
});
|
||||
|
||||
it("should be true for non-Mongo accounts with system partitionKey", () => {
|
||||
expect(showPartitionKey(collectionWithSystemPartitionKey, false)).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false for Mongo accounts with system partitionKey", () => {
|
||||
expect(showPartitionKey(mongoCollectionWithSystemPartitionKey, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("should be true for non-system partitionKey", () => {
|
||||
expect(showPartitionKey(collectionWithNonSystemPartitionKey, false)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when getting command bar button state", () => {
|
||||
describe("should set Save New Document state", () => {
|
||||
const testCases = new Set<{ state: ViewModels.DocumentExplorerState; enabled: boolean; visible: boolean }>();
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.noDocumentSelected, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentValid, enabled: true, visible: true });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentInvalid, enabled: false, visible: true });
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentNoEdits,
|
||||
enabled: false,
|
||||
visible: false,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid,
|
||||
enabled: false,
|
||||
visible: false,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid,
|
||||
enabled: false,
|
||||
visible: false,
|
||||
});
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
const state = getSaveNewDocumentButtonState(testCase.state);
|
||||
it(`enable for ${testCase.state}`, () => {
|
||||
expect(state.enabled).toBe(testCase.enabled);
|
||||
});
|
||||
it(`visible for ${testCase.state}`, () => {
|
||||
expect(state.visible).toBe(testCase.visible);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("should set Discard New Document state", () => {
|
||||
const testCases = new Set<{ state: ViewModels.DocumentExplorerState; enabled: boolean; visible: boolean }>();
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.noDocumentSelected, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentValid, enabled: true, visible: true });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentInvalid, enabled: true, visible: true });
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentNoEdits,
|
||||
enabled: false,
|
||||
visible: false,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid,
|
||||
enabled: false,
|
||||
visible: false,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid,
|
||||
enabled: false,
|
||||
visible: false,
|
||||
});
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
const state = getDiscardNewDocumentChangesButtonState(testCase.state);
|
||||
it(`enable for ${testCase.state}`, () => {
|
||||
expect(state.enabled).toBe(testCase.enabled);
|
||||
});
|
||||
it(`visible for ${testCase.state}`, () => {
|
||||
expect(state.visible).toBe(testCase.visible);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("should set Save Existing Document state", () => {
|
||||
const testCases = new Set<{ state: ViewModels.DocumentExplorerState; enabled: boolean; visible: boolean }>();
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.noDocumentSelected, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentValid, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentInvalid, enabled: false, visible: false });
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentNoEdits,
|
||||
enabled: false,
|
||||
visible: true,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid,
|
||||
enabled: true,
|
||||
visible: true,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid,
|
||||
enabled: false,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
const state = getSaveExistingDocumentButtonState(testCase.state);
|
||||
it(`enable for ${testCase.state}`, () => {
|
||||
expect(state.enabled).toBe(testCase.enabled);
|
||||
});
|
||||
it(`visible for ${testCase.state}`, () => {
|
||||
expect(state.visible).toBe(testCase.visible);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("should set Discard Existing Document state", () => {
|
||||
const testCases = new Set<{ state: ViewModels.DocumentExplorerState; enabled: boolean; visible: boolean }>();
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.noDocumentSelected, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentValid, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentInvalid, enabled: false, visible: false });
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentNoEdits,
|
||||
enabled: false,
|
||||
visible: true,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid,
|
||||
enabled: true,
|
||||
visible: true,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid,
|
||||
enabled: true,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
testCases.forEach((testCase) => {
|
||||
const state = getDiscardExistingDocumentChangesButtonState(testCase.state);
|
||||
it(`enable for ${testCase.state}`, () => {
|
||||
expect(state.enabled).toBe(testCase.enabled);
|
||||
});
|
||||
it(`visible for ${testCase.state}`, () => {
|
||||
expect(state.visible).toBe(testCase.visible);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("should set Delete Existing Document state", () => {
|
||||
const testCases = new Set<{ state: ViewModels.DocumentExplorerState; enabled: boolean; visible: boolean }>();
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.noDocumentSelected, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentValid, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.newDocumentInvalid, enabled: false, visible: false });
|
||||
testCases.add({ state: ViewModels.DocumentExplorerState.exisitingDocumentNoEdits, enabled: true, visible: true });
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyValid,
|
||||
enabled: true,
|
||||
visible: true,
|
||||
});
|
||||
testCases.add({
|
||||
state: ViewModels.DocumentExplorerState.exisitingDocumentDirtyInvalid,
|
||||
enabled: true,
|
||||
visible: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Do not get tabs button for Fabric readonly", () => {
|
||||
updateConfigContext({ platform: Platform.Fabric });
|
||||
updateUserContext({
|
||||
fabricContext: {
|
||||
connectionId: "test",
|
||||
databaseConnectionInfo: undefined,
|
||||
isReadOnly: true,
|
||||
isVisible: true,
|
||||
},
|
||||
});
|
||||
|
||||
const buttons = getTabsButtons({} as ButtonsDependencies);
|
||||
expect(buttons.length).toBe(0);
|
||||
});
|
||||
|
||||
describe("when rendered", () => {
|
||||
const createMockProps = (): IDocumentsTabComponentProps => ({
|
||||
isPreferredApiMongoDB: false,
|
||||
documentIds: [],
|
||||
collection: undefined,
|
||||
partitionKey: undefined,
|
||||
onLoadStartKey: 0,
|
||||
tabTitle: "",
|
||||
onExecutionErrorChange: (isExecutionError: boolean): void => {
|
||||
isExecutionError;
|
||||
},
|
||||
onIsExecutingChange: (isExecuting: boolean): void => {
|
||||
isExecuting;
|
||||
},
|
||||
isTabActive: true,
|
||||
});
|
||||
|
||||
let wrapper: ShallowWrapper;
|
||||
|
||||
beforeEach(async () => {
|
||||
const props: IDocumentsTabComponentProps = createMockProps();
|
||||
wrapper = shallow(<DocumentsTabComponent {...props} />);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it("should render the page", () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("clicking on Edit filter should render the Apply Filter button", () => {
|
||||
wrapper
|
||||
.findWhere((node) => node.text() === "Edit Filter")
|
||||
.at(0)
|
||||
.simulate("click");
|
||||
expect(wrapper.findWhere((node) => node.text() === "Apply Filter").exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it("clicking on Edit filter should render input for filter", () => {
|
||||
wrapper
|
||||
.findWhere((node) => node.text() === "Edit Filter")
|
||||
.at(0)
|
||||
.simulate("click");
|
||||
expect(wrapper.find("#filterInput").exists()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Command bar buttons", () => {
|
||||
const createMockProps = (): IDocumentsTabComponentProps => ({
|
||||
isPreferredApiMongoDB: false,
|
||||
documentIds: [],
|
||||
collection: {
|
||||
id: ko.observable<string>("foo"),
|
||||
container: new Explorer(),
|
||||
partitionKey: {
|
||||
kind: "MultiHash",
|
||||
paths: ["/pkey1", "/pkey2", "/pkey3"],
|
||||
version: 2,
|
||||
},
|
||||
partitionKeyProperties: ["pkey1", "pkey2", "pkey3"],
|
||||
partitionKeyPropertyHeaders: ["/pkey1", "/pkey2", "/pkey3"],
|
||||
} as ViewModels.CollectionBase,
|
||||
partitionKey: undefined,
|
||||
onLoadStartKey: 0,
|
||||
tabTitle: "",
|
||||
onExecutionErrorChange: (isExecutionError: boolean): void => {
|
||||
isExecutionError;
|
||||
},
|
||||
onIsExecutingChange: (isExecuting: boolean): void => {
|
||||
isExecuting;
|
||||
},
|
||||
isTabActive: true,
|
||||
});
|
||||
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
beforeEach(async () => {
|
||||
updateConfigContext({ platform: Platform.Hosted });
|
||||
|
||||
const props: IDocumentsTabComponentProps = createMockProps();
|
||||
|
||||
wrapper = mount(<DocumentsTabComponent {...props} />);
|
||||
wrapper = await waitForComponentToPaint(wrapper);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it("renders by default the first document", async () => {
|
||||
expect(wrapper.findWhere((node) => node.text().includes(PROPERTY_VALUE)).exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it("default buttons", async () => {
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === UPDATE_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === DISCARD_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === DELETE_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === UPLOAD_BUTTON_ID)).toBeDefined();
|
||||
});
|
||||
|
||||
it("clicking on New Document should show editor with new document", () => {
|
||||
act(() => {
|
||||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
});
|
||||
expect(wrapper.findWhere((node) => node.text().includes("replace_with_new_document_id")).exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it("clicking on New Document should show Save and Discard buttons", () => {
|
||||
act(() => {
|
||||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
});
|
||||
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === SAVE_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === DISCARD_BUTTON_ID)).toBeDefined();
|
||||
});
|
||||
|
||||
it("clicking Delete Document asks for confirmation", () => {
|
||||
const mockDeleteDocuments = deleteDocuments as jest.Mock;
|
||||
mockDeleteDocuments.mockClear();
|
||||
|
||||
act(() => {
|
||||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === DELETE_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
});
|
||||
|
||||
expect(mockDeleteDocuments).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
1816
src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.tsx
Normal file
1816
src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2.tsx
Normal file
File diff suppressed because it is too large
Load Diff
195
src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2Mongo.test.tsx
Normal file
195
src/Explorer/Tabs/DocumentsTabV2/DocumentsTabV2Mongo.test.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import { deleteDocument } from "Common/MongoProxyClient";
|
||||
import { Platform, updateConfigContext } from "ConfigContext";
|
||||
import { EditorReactProps } from "Explorer/Controls/Editor/EditorReact";
|
||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||
import {
|
||||
DELETE_BUTTON_ID,
|
||||
DISCARD_BUTTON_ID,
|
||||
DocumentsTabComponent,
|
||||
IDocumentsTabComponentProps,
|
||||
NEW_DOCUMENT_BUTTON_ID,
|
||||
SAVE_BUTTON_ID,
|
||||
UPDATE_BUTTON_ID,
|
||||
buildQuery,
|
||||
} from "Explorer/Tabs/DocumentsTabV2/DocumentsTabV2";
|
||||
import { ReactWrapper, ShallowWrapper, mount } from "enzyme";
|
||||
import * as ko from "knockout";
|
||||
import React from "react";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import Explorer from "../../Explorer";
|
||||
|
||||
jest.requireActual("Explorer/Controls/Editor/EditorReact");
|
||||
|
||||
const PROPERTY_VALUE = "__SOME_PROPERTY_VALUE__";
|
||||
|
||||
jest.mock("Common/MongoProxyClient", () => ({
|
||||
queryDocuments: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
continuationToken: "",
|
||||
documents: [
|
||||
{
|
||||
_rid: "_rid",
|
||||
_self: "_self",
|
||||
_etag: "etag",
|
||||
_ts: 1234,
|
||||
id: "id",
|
||||
},
|
||||
],
|
||||
headers: {},
|
||||
}),
|
||||
),
|
||||
readDocument: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
_rid: "_rid1",
|
||||
_self: "_self1",
|
||||
_etag: "etag1",
|
||||
property: PROPERTY_VALUE,
|
||||
_ts: 5678,
|
||||
id: "id1",
|
||||
}),
|
||||
),
|
||||
deleteDocument: jest.fn(() => Promise.resolve()),
|
||||
}));
|
||||
|
||||
jest.mock("Explorer/Controls/Editor/EditorReact", () => ({
|
||||
EditorReact: (props: EditorReactProps) => <>{props.content}</>,
|
||||
}));
|
||||
|
||||
jest.mock("Explorer/Controls/Dialog", () => ({
|
||||
useDialog: {
|
||||
getState: jest.fn(() => ({
|
||||
showOkCancelModalDialog: (title: string, subText: string, okLabel: string, onOk: () => void) => onOk(),
|
||||
showOkModalDialog: () => {},
|
||||
})),
|
||||
},
|
||||
}));
|
||||
|
||||
async function waitForComponentToPaint<P = unknown>(wrapper: ReactWrapper<P> | ShallowWrapper<P>, amount = 0) {
|
||||
let newWrapper;
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, amount));
|
||||
newWrapper = wrapper.update();
|
||||
});
|
||||
return newWrapper;
|
||||
}
|
||||
|
||||
describe("Documents tab (Mongo API)", () => {
|
||||
describe("buildQuery", () => {
|
||||
it("should generate the right select query for SQL API", () => {
|
||||
expect(buildQuery(true, "")).toContain("{}");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Command bar buttons", () => {
|
||||
const createMockProps = (): IDocumentsTabComponentProps => ({
|
||||
isPreferredApiMongoDB: true,
|
||||
documentIds: [],
|
||||
collection: {
|
||||
id: ko.observable<string>("foo"),
|
||||
container: new Explorer(),
|
||||
partitionKey: {
|
||||
kind: "Hash",
|
||||
paths: ["/pkey"],
|
||||
version: 2,
|
||||
},
|
||||
partitionKeyProperties: ["pkey"],
|
||||
partitionKeyPropertyHeaders: ["/pkey"],
|
||||
databaseId: "databaseId",
|
||||
self: "self",
|
||||
rawDataModel: undefined,
|
||||
selectedSubnodeKind: undefined,
|
||||
children: undefined,
|
||||
isCollectionExpanded: undefined,
|
||||
onDocumentDBDocumentsClick: (): void => {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
onNewQueryClick: (): void => {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
expandCollection: (): void => {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
collapseCollection: (): void => {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
getDatabase: (): ViewModels.Database => {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
nodeKind: "nodeKind",
|
||||
rid: "rid",
|
||||
},
|
||||
partitionKey: undefined,
|
||||
onLoadStartKey: 0,
|
||||
tabTitle: "",
|
||||
onExecutionErrorChange: (isExecutionError: boolean): void => {
|
||||
isExecutionError;
|
||||
},
|
||||
onIsExecutingChange: (isExecuting: boolean): void => {
|
||||
isExecuting;
|
||||
},
|
||||
isTabActive: true,
|
||||
});
|
||||
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
beforeEach(async () => {
|
||||
updateConfigContext({ platform: Platform.Hosted });
|
||||
|
||||
const props: IDocumentsTabComponentProps = createMockProps();
|
||||
|
||||
wrapper = mount(<DocumentsTabComponent {...props} />);
|
||||
wrapper = await waitForComponentToPaint(wrapper);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it("renders by default the first document", async () => {
|
||||
expect(wrapper.findWhere((node) => node.text().includes(PROPERTY_VALUE)).exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it("default buttons", async () => {
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === UPDATE_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === DISCARD_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === DELETE_BUTTON_ID)).toBeDefined();
|
||||
});
|
||||
|
||||
it("clicking on New Document should show editor with new document", () => {
|
||||
act(() => {
|
||||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
});
|
||||
expect(wrapper.findWhere((node) => node.text().includes("replace_with_new_document_id")).exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it("clicking on New Document should show Save and Discard buttons", () => {
|
||||
act(() => {
|
||||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === NEW_DOCUMENT_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
});
|
||||
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === SAVE_BUTTON_ID)).toBeDefined();
|
||||
expect(useCommandBar.getState().contextButtons.find((button) => button.id === DISCARD_BUTTON_ID)).toBeDefined();
|
||||
});
|
||||
|
||||
it("clicking Delete Document asks for confirmation", () => {
|
||||
const mockDeleteDocument = deleteDocument as jest.Mock;
|
||||
mockDeleteDocument.mockClear();
|
||||
|
||||
act(() => {
|
||||
useCommandBar
|
||||
.getState()
|
||||
.contextButtons.find((button) => button.id === DELETE_BUTTON_ID)
|
||||
.onCommandClick(undefined);
|
||||
});
|
||||
|
||||
expect(mockDeleteDocument).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
import { TableRowId } from "@fluentui/react-components";
|
||||
import { mount } from "enzyme";
|
||||
import React from "react";
|
||||
import { DocumentsTableComponent, IDocumentsTableComponentProps } from "./DocumentsTableComponent";
|
||||
|
||||
const PARTITION_KEY_HEADER = "partitionKey";
|
||||
const ID_HEADER = "id";
|
||||
|
||||
describe("DocumentsTableComponent", () => {
|
||||
const createMockProps = (): IDocumentsTableComponentProps => ({
|
||||
items: [
|
||||
{ [ID_HEADER]: "1", [PARTITION_KEY_HEADER]: "pk1" },
|
||||
{ [ID_HEADER]: "2", [PARTITION_KEY_HEADER]: "pk2" },
|
||||
{ [ID_HEADER]: "3", [PARTITION_KEY_HEADER]: "pk3" },
|
||||
],
|
||||
onItemClicked: (): void => {},
|
||||
onSelectedRowsChange: (): void => {},
|
||||
selectedRows: new Set<TableRowId>(),
|
||||
size: {
|
||||
height: 0,
|
||||
width: 0,
|
||||
},
|
||||
columnHeaders: {
|
||||
idHeader: ID_HEADER,
|
||||
partitionKeyHeaders: [PARTITION_KEY_HEADER],
|
||||
},
|
||||
});
|
||||
|
||||
it("should render documents and partition keys in header", () => {
|
||||
const props: IDocumentsTableComponentProps = createMockProps();
|
||||
const wrapper = mount(<DocumentsTableComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
271
src/Explorer/Tabs/DocumentsTabV2/DocumentsTableComponent.tsx
Normal file
271
src/Explorer/Tabs/DocumentsTabV2/DocumentsTableComponent.tsx
Normal file
@@ -0,0 +1,271 @@
|
||||
import {
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
MenuPopover,
|
||||
MenuTrigger,
|
||||
TableRowData as RowStateBase,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableCellLayout,
|
||||
TableColumnDefinition,
|
||||
TableColumnSizingOptions,
|
||||
TableHeader,
|
||||
TableHeaderCell,
|
||||
TableRow,
|
||||
TableRowId,
|
||||
TableSelectionCell,
|
||||
createTableColumn,
|
||||
useArrowNavigationGroup,
|
||||
useTableColumnSizing_unstable,
|
||||
useTableFeatures,
|
||||
useTableSelection,
|
||||
} from "@fluentui/react-components";
|
||||
import React, { useCallback, useEffect, useMemo } from "react";
|
||||
import { FixedSizeList as List, ListChildComponentProps } from "react-window";
|
||||
|
||||
export type DocumentsTableComponentItem = {
|
||||
id: string;
|
||||
} & Record<string, string>;
|
||||
|
||||
export type ColumnHeaders = {
|
||||
idHeader: string;
|
||||
partitionKeyHeaders: string[];
|
||||
};
|
||||
export interface IDocumentsTableComponentProps {
|
||||
items: DocumentsTableComponentItem[];
|
||||
onItemClicked: (index: number) => void;
|
||||
onSelectedRowsChange: (selectedItemsIndices: Set<TableRowId>) => void;
|
||||
selectedRows: Set<TableRowId>;
|
||||
size: { height: number; width: number };
|
||||
columnHeaders: ColumnHeaders;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
interface TableRowData extends RowStateBase<DocumentsTableComponentItem> {
|
||||
onClick: (e: React.MouseEvent) => void;
|
||||
onKeyDown: (e: React.KeyboardEvent) => void;
|
||||
selected: boolean;
|
||||
appearance: "brand" | "none";
|
||||
}
|
||||
interface ReactWindowRenderFnProps extends ListChildComponentProps {
|
||||
data: TableRowData[];
|
||||
}
|
||||
|
||||
export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> = ({
|
||||
items,
|
||||
onItemClicked,
|
||||
onSelectedRowsChange,
|
||||
selectedRows,
|
||||
style,
|
||||
size,
|
||||
columnHeaders,
|
||||
}: IDocumentsTableComponentProps) => {
|
||||
const [activeItemIndex, setActiveItemIndex] = React.useState<number>(undefined);
|
||||
|
||||
const initialSizingOptions: TableColumnSizingOptions = {
|
||||
id: {
|
||||
idealWidth: 280,
|
||||
minWidth: 50,
|
||||
},
|
||||
};
|
||||
columnHeaders.partitionKeyHeaders.forEach((pkHeader) => {
|
||||
initialSizingOptions[pkHeader] = {
|
||||
idealWidth: 200,
|
||||
minWidth: 50,
|
||||
};
|
||||
});
|
||||
|
||||
const [columnSizingOptions, setColumnSizingOptions] = React.useState<TableColumnSizingOptions>(initialSizingOptions);
|
||||
|
||||
const onColumnResize = React.useCallback((_, { columnId, width }) => {
|
||||
setColumnSizingOptions((state) => ({
|
||||
...state,
|
||||
[columnId]: {
|
||||
...state[columnId],
|
||||
idealWidth: width,
|
||||
},
|
||||
}));
|
||||
}, []);
|
||||
|
||||
// Columns must be a static object and cannot change on re-renders otherwise React will complain about too many refreshes
|
||||
const columns: TableColumnDefinition<DocumentsTableComponentItem>[] = useMemo(
|
||||
() =>
|
||||
[
|
||||
createTableColumn<DocumentsTableComponentItem>({
|
||||
columnId: "id",
|
||||
compare: (a, b) => a.id.localeCompare(b.id),
|
||||
renderHeaderCell: () => columnHeaders.idHeader,
|
||||
renderCell: (item) => (
|
||||
<TableCellLayout truncate title={item.id}>
|
||||
{item.id}
|
||||
</TableCellLayout>
|
||||
),
|
||||
}),
|
||||
].concat(
|
||||
columnHeaders.partitionKeyHeaders.map((pkHeader) =>
|
||||
createTableColumn<DocumentsTableComponentItem>({
|
||||
columnId: pkHeader,
|
||||
compare: (a, b) => a[pkHeader].localeCompare(b[pkHeader]),
|
||||
// Show Refresh button on last column
|
||||
renderHeaderCell: () => <span title={pkHeader}>{pkHeader}</span>,
|
||||
renderCell: (item) => (
|
||||
<TableCellLayout truncate title={item[pkHeader]}>
|
||||
{item[pkHeader]}
|
||||
</TableCellLayout>
|
||||
),
|
||||
}),
|
||||
),
|
||||
),
|
||||
[columnHeaders],
|
||||
);
|
||||
|
||||
const onIdClicked = useCallback((index: number) => onSelectedRowsChange(new Set([index])), [onSelectedRowsChange]);
|
||||
|
||||
const RenderRow = ({ index, style, data }: ReactWindowRenderFnProps) => {
|
||||
const { item, selected, appearance, onClick, onKeyDown } = data[index];
|
||||
return (
|
||||
<TableRow aria-rowindex={index + 2} style={style} key={item.id} aria-selected={selected} appearance={appearance}>
|
||||
<TableSelectionCell
|
||||
checked={selected}
|
||||
checkboxIndicator={{ "aria-label": "Select row" }}
|
||||
onClick={onClick}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
{columns.map((column) => (
|
||||
<TableCell
|
||||
key={column.columnId}
|
||||
className="documentsTableCell"
|
||||
onClick={(/* e */) => onSelectedRowsChange(new Set<TableRowId>([index]))}
|
||||
onKeyDown={() => onIdClicked(index)}
|
||||
{...columnSizing.getTableCellProps(column.columnId)}
|
||||
tabIndex={column.columnId === "id" ? 0 : -1}
|
||||
>
|
||||
{column.renderCell(item)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
);
|
||||
};
|
||||
|
||||
const {
|
||||
getRows,
|
||||
columnSizing_unstable: columnSizing,
|
||||
tableRef,
|
||||
selection: { allRowsSelected, someRowsSelected, toggleAllRows, toggleRow, isRowSelected },
|
||||
} = useTableFeatures(
|
||||
{
|
||||
columns,
|
||||
items,
|
||||
},
|
||||
[
|
||||
useTableColumnSizing_unstable({ columnSizingOptions, onColumnResize }),
|
||||
useTableSelection({
|
||||
selectionMode: "multiselect",
|
||||
selectedItems: selectedRows,
|
||||
// eslint-disable-next-line react/prop-types
|
||||
onSelectionChange: (e, data) => onSelectedRowsChange(data.selectedItems),
|
||||
}),
|
||||
],
|
||||
);
|
||||
|
||||
const rows: TableRowData[] = getRows((row) => {
|
||||
const selected = isRowSelected(row.rowId);
|
||||
return {
|
||||
...row,
|
||||
onClick: (e: React.MouseEvent) => toggleRow(e, row.rowId),
|
||||
onKeyDown: (e: React.KeyboardEvent) => {
|
||||
if (e.key === " ") {
|
||||
e.preventDefault();
|
||||
toggleRow(e, row.rowId);
|
||||
}
|
||||
},
|
||||
selected,
|
||||
appearance: selected ? ("brand" as const) : ("none" as const),
|
||||
};
|
||||
});
|
||||
|
||||
const toggleAllKeydown = React.useCallback(
|
||||
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
if (e.key === " ") {
|
||||
toggleAllRows(e);
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
[toggleAllRows],
|
||||
);
|
||||
|
||||
// Load document depending on selection
|
||||
useEffect(() => {
|
||||
if (selectedRows.size === 1 && items.length > 0) {
|
||||
const newActiveItemIndex = selectedRows.values().next().value;
|
||||
if (newActiveItemIndex !== activeItemIndex) {
|
||||
onItemClicked(newActiveItemIndex);
|
||||
setActiveItemIndex(newActiveItemIndex);
|
||||
}
|
||||
}
|
||||
}, [selectedRows, items]);
|
||||
|
||||
// Cell keyboard navigation
|
||||
const keyboardNavAttr = useArrowNavigationGroup({ axis: "grid" });
|
||||
|
||||
// TODO: Bug in fluent UI typings that requires any here
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const tableProps: any = {
|
||||
"aria-label": "Filtered documents table",
|
||||
role: "grid",
|
||||
...columnSizing.getTableProps(),
|
||||
...keyboardNavAttr,
|
||||
size: "extra-small",
|
||||
ref: tableRef,
|
||||
...style,
|
||||
};
|
||||
|
||||
return (
|
||||
<Table className="documentsTable" noNativeElements {...tableProps}>
|
||||
<TableHeader className="documentsTableHeader">
|
||||
<TableRow style={{ width: size ? size.width - 15 : "100%" }}>
|
||||
<TableSelectionCell
|
||||
checked={allRowsSelected ? true : someRowsSelected ? "mixed" : false}
|
||||
onClick={toggleAllRows}
|
||||
onKeyDown={toggleAllKeydown}
|
||||
checkboxIndicator={{ "aria-label": "Select all rows " }}
|
||||
/>
|
||||
{columns.map((column /* index */) => (
|
||||
<Menu openOnContext key={column.columnId}>
|
||||
<MenuTrigger>
|
||||
<TableHeaderCell
|
||||
className="documentsTableCell"
|
||||
key={column.columnId}
|
||||
{...columnSizing.getTableHeaderCellProps(column.columnId)}
|
||||
>
|
||||
{column.renderHeaderCell()}
|
||||
</TableHeaderCell>
|
||||
</MenuTrigger>
|
||||
<MenuPopover>
|
||||
<MenuList>
|
||||
<MenuItem onClick={columnSizing.enableKeyboardMode(column.columnId)}>
|
||||
Keyboard Column Resizing
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<List
|
||||
height={size !== undefined ? size.height - 32 /* table header */ - 21 /* load more */ : 0}
|
||||
itemCount={items.length}
|
||||
itemSize={30}
|
||||
width={size ? size.width : 0}
|
||||
itemData={rows}
|
||||
style={{ overflowY: "scroll" }}
|
||||
>
|
||||
{RenderRow}
|
||||
</List>
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,558 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Documents tab (noSql API) when rendered should render the page 1`] = `
|
||||
<FluentProvider
|
||||
style={
|
||||
Object {
|
||||
"height": "100%",
|
||||
}
|
||||
}
|
||||
theme={
|
||||
Object {
|
||||
"borderRadiusCircular": "10000px",
|
||||
"borderRadiusLarge": "6px",
|
||||
"borderRadiusMedium": "4px",
|
||||
"borderRadiusNone": "0",
|
||||
"borderRadiusSmall": "2px",
|
||||
"borderRadiusXLarge": "8px",
|
||||
"colorBackgroundOverlay": "rgba(0, 0, 0, 0.4)",
|
||||
"colorBrandBackground": "#117865",
|
||||
"colorBrandBackground2": "#e3f7ef",
|
||||
"colorBrandBackground2Hover": "#c0ecdd",
|
||||
"colorBrandBackground2Pressed": "#78d3b9",
|
||||
"colorBrandBackgroundHover": "#0c695a",
|
||||
"colorBrandBackgroundInverted": "#ffffff",
|
||||
"colorBrandBackgroundInvertedHover": "#e3f7ef",
|
||||
"colorBrandBackgroundInvertedPressed": "#9ee0cb",
|
||||
"colorBrandBackgroundInvertedSelected": "#c0ecdd",
|
||||
"colorBrandBackgroundPressed": "#033f38",
|
||||
"colorBrandBackgroundSelected": "#0a5c50",
|
||||
"colorBrandBackgroundStatic": "#117865",
|
||||
"colorBrandForeground1": "#117865",
|
||||
"colorBrandForeground2": "#0c695a",
|
||||
"colorBrandForeground2Hover": "#0a5c50",
|
||||
"colorBrandForeground2Pressed": "#01322E",
|
||||
"colorBrandForegroundInverted": "#2aaC94",
|
||||
"colorBrandForegroundInvertedHover": "#3abb9f",
|
||||
"colorBrandForegroundInvertedPressed": "#2aaC94",
|
||||
"colorBrandForegroundLink": "#0c695a",
|
||||
"colorBrandForegroundLinkHover": "#0a5c50",
|
||||
"colorBrandForegroundLinkPressed": "#033f38",
|
||||
"colorBrandForegroundLinkSelected": "#0c695a",
|
||||
"colorBrandForegroundOnLight": "#117865",
|
||||
"colorBrandForegroundOnLightHover": "#0c695a",
|
||||
"colorBrandForegroundOnLightPressed": "#054d43",
|
||||
"colorBrandForegroundOnLightSelected": "#0a5c50",
|
||||
"colorBrandShadowAmbient": "rgba(0,0,0,0.30)",
|
||||
"colorBrandShadowKey": "rgba(0,0,0,0.25)",
|
||||
"colorBrandStroke1": "#117865",
|
||||
"colorBrandStroke2": "#9ee0cb",
|
||||
"colorBrandStroke2Contrast": "#9ee0cb",
|
||||
"colorBrandStroke2Hover": "#52c7aa",
|
||||
"colorBrandStroke2Pressed": "#117865",
|
||||
"colorCompoundBrandBackground": "#117865",
|
||||
"colorCompoundBrandBackgroundHover": "#0c695a",
|
||||
"colorCompoundBrandBackgroundPressed": "#0a5c50",
|
||||
"colorCompoundBrandForeground1": "#117865",
|
||||
"colorCompoundBrandForeground1Hover": "#0c695a",
|
||||
"colorCompoundBrandForeground1Pressed": "#0a5c50",
|
||||
"colorCompoundBrandStroke": "#117865",
|
||||
"colorCompoundBrandStrokeHover": "#0c695a",
|
||||
"colorCompoundBrandStrokePressed": "#0a5c50",
|
||||
"colorNeutralBackground1": "#ffffff",
|
||||
"colorNeutralBackground1Hover": "#f5f5f5",
|
||||
"colorNeutralBackground1Pressed": "#e0e0e0",
|
||||
"colorNeutralBackground1Selected": "#ebebeb",
|
||||
"colorNeutralBackground2": "#fafafa",
|
||||
"colorNeutralBackground2Hover": "#f0f0f0",
|
||||
"colorNeutralBackground2Pressed": "#dbdbdb",
|
||||
"colorNeutralBackground2Selected": "#e6e6e6",
|
||||
"colorNeutralBackground3": "#f5f5f5",
|
||||
"colorNeutralBackground3Hover": "#ebebeb",
|
||||
"colorNeutralBackground3Pressed": "#d6d6d6",
|
||||
"colorNeutralBackground3Selected": "#e0e0e0",
|
||||
"colorNeutralBackground4": "#f0f0f0",
|
||||
"colorNeutralBackground4Hover": "#fafafa",
|
||||
"colorNeutralBackground4Pressed": "#f5f5f5",
|
||||
"colorNeutralBackground4Selected": "#ffffff",
|
||||
"colorNeutralBackground5": "#ebebeb",
|
||||
"colorNeutralBackground5Hover": "#f5f5f5",
|
||||
"colorNeutralBackground5Pressed": "#f0f0f0",
|
||||
"colorNeutralBackground5Selected": "#fafafa",
|
||||
"colorNeutralBackground6": "#e6e6e6",
|
||||
"colorNeutralBackgroundAlpha": "rgba(255, 255, 255, 0.5)",
|
||||
"colorNeutralBackgroundAlpha2": "rgba(255, 255, 255, 0.8)",
|
||||
"colorNeutralBackgroundDisabled": "#f0f0f0",
|
||||
"colorNeutralBackgroundInverted": "#292929",
|
||||
"colorNeutralBackgroundInvertedDisabled": "rgba(255, 255, 255, 0.1)",
|
||||
"colorNeutralBackgroundStatic": "#333333",
|
||||
"colorNeutralForeground1": "#242424",
|
||||
"colorNeutralForeground1Hover": "#242424",
|
||||
"colorNeutralForeground1Pressed": "#242424",
|
||||
"colorNeutralForeground1Selected": "#242424",
|
||||
"colorNeutralForeground1Static": "#242424",
|
||||
"colorNeutralForeground2": "#424242",
|
||||
"colorNeutralForeground2BrandHover": "#117865",
|
||||
"colorNeutralForeground2BrandPressed": "#0c695a",
|
||||
"colorNeutralForeground2BrandSelected": "#117865",
|
||||
"colorNeutralForeground2Hover": "#242424",
|
||||
"colorNeutralForeground2Link": "#424242",
|
||||
"colorNeutralForeground2LinkHover": "#242424",
|
||||
"colorNeutralForeground2LinkPressed": "#242424",
|
||||
"colorNeutralForeground2LinkSelected": "#242424",
|
||||
"colorNeutralForeground2Pressed": "#242424",
|
||||
"colorNeutralForeground2Selected": "#242424",
|
||||
"colorNeutralForeground3": "#616161",
|
||||
"colorNeutralForeground3BrandHover": "#117865",
|
||||
"colorNeutralForeground3BrandPressed": "#0c695a",
|
||||
"colorNeutralForeground3BrandSelected": "#117865",
|
||||
"colorNeutralForeground3Hover": "#424242",
|
||||
"colorNeutralForeground3Pressed": "#424242",
|
||||
"colorNeutralForeground3Selected": "#424242",
|
||||
"colorNeutralForeground4": "#707070",
|
||||
"colorNeutralForegroundDisabled": "#bdbdbd",
|
||||
"colorNeutralForegroundInverted": "#ffffff",
|
||||
"colorNeutralForegroundInverted2": "#ffffff",
|
||||
"colorNeutralForegroundInvertedDisabled": "rgba(255, 255, 255, 0.4)",
|
||||
"colorNeutralForegroundInvertedHover": "#ffffff",
|
||||
"colorNeutralForegroundInvertedLink": "#ffffff",
|
||||
"colorNeutralForegroundInvertedLinkHover": "#ffffff",
|
||||
"colorNeutralForegroundInvertedLinkPressed": "#ffffff",
|
||||
"colorNeutralForegroundInvertedLinkSelected": "#ffffff",
|
||||
"colorNeutralForegroundInvertedPressed": "#ffffff",
|
||||
"colorNeutralForegroundInvertedSelected": "#ffffff",
|
||||
"colorNeutralForegroundOnBrand": "#ffffff",
|
||||
"colorNeutralForegroundStaticInverted": "#ffffff",
|
||||
"colorNeutralShadowAmbient": "rgba(0,0,0,0.12)",
|
||||
"colorNeutralShadowAmbientDarker": "rgba(0,0,0,0.20)",
|
||||
"colorNeutralShadowAmbientLighter": "rgba(0,0,0,0.06)",
|
||||
"colorNeutralShadowKey": "rgba(0,0,0,0.14)",
|
||||
"colorNeutralShadowKeyDarker": "rgba(0,0,0,0.24)",
|
||||
"colorNeutralShadowKeyLighter": "rgba(0,0,0,0.07)",
|
||||
"colorNeutralStencil1": "#e6e6e6",
|
||||
"colorNeutralStencil1Alpha": "rgba(0, 0, 0, 0.1)",
|
||||
"colorNeutralStencil2": "#fafafa",
|
||||
"colorNeutralStencil2Alpha": "rgba(0, 0, 0, 0.05)",
|
||||
"colorNeutralStroke1": "#d1d1d1",
|
||||
"colorNeutralStroke1Hover": "#c7c7c7",
|
||||
"colorNeutralStroke1Pressed": "#b3b3b3",
|
||||
"colorNeutralStroke1Selected": "#bdbdbd",
|
||||
"colorNeutralStroke2": "#e0e0e0",
|
||||
"colorNeutralStroke3": "#f0f0f0",
|
||||
"colorNeutralStrokeAccessible": "#616161",
|
||||
"colorNeutralStrokeAccessibleHover": "#575757",
|
||||
"colorNeutralStrokeAccessiblePressed": "#4d4d4d",
|
||||
"colorNeutralStrokeAccessibleSelected": "#117865",
|
||||
"colorNeutralStrokeAlpha": "rgba(0, 0, 0, 0.05)",
|
||||
"colorNeutralStrokeAlpha2": "rgba(255, 255, 255, 0.2)",
|
||||
"colorNeutralStrokeDisabled": "#e0e0e0",
|
||||
"colorNeutralStrokeInvertedDisabled": "rgba(255, 255, 255, 0.4)",
|
||||
"colorNeutralStrokeOnBrand": "#ffffff",
|
||||
"colorNeutralStrokeOnBrand2": "#ffffff",
|
||||
"colorNeutralStrokeOnBrand2Hover": "#ffffff",
|
||||
"colorNeutralStrokeOnBrand2Pressed": "#ffffff",
|
||||
"colorNeutralStrokeOnBrand2Selected": "#ffffff",
|
||||
"colorNeutralStrokeSubtle": "#e0e0e0",
|
||||
"colorPaletteAnchorBackground2": "#bcc3c7",
|
||||
"colorPaletteAnchorBorderActive": "#394146",
|
||||
"colorPaletteAnchorForeground2": "#202427",
|
||||
"colorPaletteBeigeBackground2": "#d7d4d4",
|
||||
"colorPaletteBeigeBorderActive": "#7a7574",
|
||||
"colorPaletteBeigeForeground2": "#444241",
|
||||
"colorPaletteBerryBackground1": "#fdf5fc",
|
||||
"colorPaletteBerryBackground2": "#edbbe7",
|
||||
"colorPaletteBerryBackground3": "#c239b3",
|
||||
"colorPaletteBerryBorder1": "#edbbe7",
|
||||
"colorPaletteBerryBorder2": "#c239b3",
|
||||
"colorPaletteBerryBorderActive": "#c239b3",
|
||||
"colorPaletteBerryForeground1": "#af33a1",
|
||||
"colorPaletteBerryForeground2": "#6d2064",
|
||||
"colorPaletteBerryForeground3": "#c239b3",
|
||||
"colorPaletteBlueBackground2": "#a9d3f2",
|
||||
"colorPaletteBlueBorderActive": "#0078d4",
|
||||
"colorPaletteBlueForeground2": "#004377",
|
||||
"colorPaletteBrassBackground2": "#e0cea2",
|
||||
"colorPaletteBrassBorderActive": "#986f0b",
|
||||
"colorPaletteBrassForeground2": "#553e06",
|
||||
"colorPaletteBrownBackground2": "#ddc3b0",
|
||||
"colorPaletteBrownBorderActive": "#8e562e",
|
||||
"colorPaletteBrownForeground2": "#50301a",
|
||||
"colorPaletteCornflowerBackground2": "#c8d1fa",
|
||||
"colorPaletteCornflowerBorderActive": "#4f6bed",
|
||||
"colorPaletteCornflowerForeground2": "#2c3c85",
|
||||
"colorPaletteCranberryBackground2": "#eeacb2",
|
||||
"colorPaletteCranberryBorderActive": "#c50f1f",
|
||||
"colorPaletteCranberryForeground2": "#6e0811",
|
||||
"colorPaletteDarkGreenBackground2": "#9ad29a",
|
||||
"colorPaletteDarkGreenBorderActive": "#0b6a0b",
|
||||
"colorPaletteDarkGreenForeground2": "#063b06",
|
||||
"colorPaletteDarkOrangeBackground1": "#fdf6f3",
|
||||
"colorPaletteDarkOrangeBackground2": "#f4bfab",
|
||||
"colorPaletteDarkOrangeBackground3": "#da3b01",
|
||||
"colorPaletteDarkOrangeBorder1": "#f4bfab",
|
||||
"colorPaletteDarkOrangeBorder2": "#da3b01",
|
||||
"colorPaletteDarkOrangeBorderActive": "#da3b01",
|
||||
"colorPaletteDarkOrangeForeground1": "#c43501",
|
||||
"colorPaletteDarkOrangeForeground2": "#7a2101",
|
||||
"colorPaletteDarkOrangeForeground3": "#da3b01",
|
||||
"colorPaletteDarkRedBackground2": "#d69ca5",
|
||||
"colorPaletteDarkRedBorderActive": "#750b1c",
|
||||
"colorPaletteDarkRedForeground2": "#420610",
|
||||
"colorPaletteForestBackground2": "#bdd99b",
|
||||
"colorPaletteForestBorderActive": "#498205",
|
||||
"colorPaletteForestForeground2": "#294903",
|
||||
"colorPaletteGoldBackground2": "#ecdfa5",
|
||||
"colorPaletteGoldBorderActive": "#c19c00",
|
||||
"colorPaletteGoldForeground2": "#6c5700",
|
||||
"colorPaletteGrapeBackground2": "#d9a7e0",
|
||||
"colorPaletteGrapeBorderActive": "#881798",
|
||||
"colorPaletteGrapeForeground2": "#4c0d55",
|
||||
"colorPaletteGreenBackground1": "#f1faf1",
|
||||
"colorPaletteGreenBackground2": "#9fd89f",
|
||||
"colorPaletteGreenBackground3": "#107c10",
|
||||
"colorPaletteGreenBorder1": "#9fd89f",
|
||||
"colorPaletteGreenBorder2": "#107c10",
|
||||
"colorPaletteGreenBorderActive": "#107c10",
|
||||
"colorPaletteGreenForeground1": "#0e700e",
|
||||
"colorPaletteGreenForeground2": "#094509",
|
||||
"colorPaletteGreenForeground3": "#107c10",
|
||||
"colorPaletteGreenForegroundInverted": "#359b35",
|
||||
"colorPaletteLavenderBackground2": "#d2ccf8",
|
||||
"colorPaletteLavenderBorderActive": "#7160e8",
|
||||
"colorPaletteLavenderForeground2": "#3f3682",
|
||||
"colorPaletteLightGreenBackground1": "#f2fbf2",
|
||||
"colorPaletteLightGreenBackground2": "#a7e3a5",
|
||||
"colorPaletteLightGreenBackground3": "#13a10e",
|
||||
"colorPaletteLightGreenBorder1": "#a7e3a5",
|
||||
"colorPaletteLightGreenBorder2": "#13a10e",
|
||||
"colorPaletteLightGreenBorderActive": "#13a10e",
|
||||
"colorPaletteLightGreenForeground1": "#11910d",
|
||||
"colorPaletteLightGreenForeground2": "#0b5a08",
|
||||
"colorPaletteLightGreenForeground3": "#13a10e",
|
||||
"colorPaletteLightTealBackground2": "#a6e9ed",
|
||||
"colorPaletteLightTealBorderActive": "#00b7c3",
|
||||
"colorPaletteLightTealForeground2": "#00666d",
|
||||
"colorPaletteLilacBackground2": "#e6bfed",
|
||||
"colorPaletteLilacBorderActive": "#b146c2",
|
||||
"colorPaletteLilacForeground2": "#63276d",
|
||||
"colorPaletteMagentaBackground2": "#eca5d1",
|
||||
"colorPaletteMagentaBorderActive": "#bf0077",
|
||||
"colorPaletteMagentaForeground2": "#6b0043",
|
||||
"colorPaletteMarigoldBackground1": "#fefbf4",
|
||||
"colorPaletteMarigoldBackground2": "#f9e2ae",
|
||||
"colorPaletteMarigoldBackground3": "#eaa300",
|
||||
"colorPaletteMarigoldBorder1": "#f9e2ae",
|
||||
"colorPaletteMarigoldBorder2": "#eaa300",
|
||||
"colorPaletteMarigoldBorderActive": "#eaa300",
|
||||
"colorPaletteMarigoldForeground1": "#d39300",
|
||||
"colorPaletteMarigoldForeground2": "#835b00",
|
||||
"colorPaletteMarigoldForeground3": "#eaa300",
|
||||
"colorPaletteMinkBackground2": "#cecccb",
|
||||
"colorPaletteMinkBorderActive": "#5d5a58",
|
||||
"colorPaletteMinkForeground2": "#343231",
|
||||
"colorPaletteNavyBackground2": "#a3b2e8",
|
||||
"colorPaletteNavyBorderActive": "#0027b4",
|
||||
"colorPaletteNavyForeground2": "#001665",
|
||||
"colorPalettePeachBackground2": "#ffddb3",
|
||||
"colorPalettePeachBorderActive": "#ff8c00",
|
||||
"colorPalettePeachForeground2": "#8f4e00",
|
||||
"colorPalettePinkBackground2": "#f7c0e3",
|
||||
"colorPalettePinkBorderActive": "#e43ba6",
|
||||
"colorPalettePinkForeground2": "#80215d",
|
||||
"colorPalettePlatinumBackground2": "#cdd6d8",
|
||||
"colorPalettePlatinumBorderActive": "#69797e",
|
||||
"colorPalettePlatinumForeground2": "#3b4447",
|
||||
"colorPalettePlumBackground2": "#d696c0",
|
||||
"colorPalettePlumBorderActive": "#77004d",
|
||||
"colorPalettePlumForeground2": "#43002b",
|
||||
"colorPalettePumpkinBackground2": "#efc4ad",
|
||||
"colorPalettePumpkinBorderActive": "#ca5010",
|
||||
"colorPalettePumpkinForeground2": "#712d09",
|
||||
"colorPalettePurpleBackground2": "#c6b1de",
|
||||
"colorPalettePurpleBorderActive": "#5c2e91",
|
||||
"colorPalettePurpleForeground2": "#341a51",
|
||||
"colorPaletteRedBackground1": "#fdf6f6",
|
||||
"colorPaletteRedBackground2": "#f1bbbc",
|
||||
"colorPaletteRedBackground3": "#d13438",
|
||||
"colorPaletteRedBorder1": "#f1bbbc",
|
||||
"colorPaletteRedBorder2": "#d13438",
|
||||
"colorPaletteRedBorderActive": "#d13438",
|
||||
"colorPaletteRedForeground1": "#bc2f32",
|
||||
"colorPaletteRedForeground2": "#751d1f",
|
||||
"colorPaletteRedForeground3": "#d13438",
|
||||
"colorPaletteRedForegroundInverted": "#dc5e62",
|
||||
"colorPaletteRoyalBlueBackground2": "#9abfdc",
|
||||
"colorPaletteRoyalBlueBorderActive": "#004e8c",
|
||||
"colorPaletteRoyalBlueForeground2": "#002c4e",
|
||||
"colorPaletteSeafoamBackground2": "#a8f0cd",
|
||||
"colorPaletteSeafoamBorderActive": "#00cc6a",
|
||||
"colorPaletteSeafoamForeground2": "#00723b",
|
||||
"colorPaletteSteelBackground2": "#94c8d4",
|
||||
"colorPaletteSteelBorderActive": "#005b70",
|
||||
"colorPaletteSteelForeground2": "#00333f",
|
||||
"colorPaletteTealBackground2": "#9bd9db",
|
||||
"colorPaletteTealBorderActive": "#038387",
|
||||
"colorPaletteTealForeground2": "#02494c",
|
||||
"colorPaletteYellowBackground1": "#fffef5",
|
||||
"colorPaletteYellowBackground2": "#fef7b2",
|
||||
"colorPaletteYellowBackground3": "#fde300",
|
||||
"colorPaletteYellowBorder1": "#fef7b2",
|
||||
"colorPaletteYellowBorder2": "#fde300",
|
||||
"colorPaletteYellowBorderActive": "#fde300",
|
||||
"colorPaletteYellowForeground1": "#817400",
|
||||
"colorPaletteYellowForeground2": "#817400",
|
||||
"colorPaletteYellowForeground3": "#fde300",
|
||||
"colorPaletteYellowForegroundInverted": "#fef7b2",
|
||||
"colorScrollbarOverlay": "rgba(0, 0, 0, 0.5)",
|
||||
"colorStatusDangerBackground1": "#fdf3f4",
|
||||
"colorStatusDangerBackground2": "#eeacb2",
|
||||
"colorStatusDangerBackground3": "#c50f1f",
|
||||
"colorStatusDangerBorder1": "#eeacb2",
|
||||
"colorStatusDangerBorder2": "#c50f1f",
|
||||
"colorStatusDangerBorderActive": "#c50f1f",
|
||||
"colorStatusDangerForeground1": "#b10e1c",
|
||||
"colorStatusDangerForeground2": "#6e0811",
|
||||
"colorStatusDangerForeground3": "#c50f1f",
|
||||
"colorStatusDangerForegroundInverted": "#dc626d",
|
||||
"colorStatusSuccessBackground1": "#f1faf1",
|
||||
"colorStatusSuccessBackground2": "#9fd89f",
|
||||
"colorStatusSuccessBackground3": "#107c10",
|
||||
"colorStatusSuccessBorder1": "#9fd89f",
|
||||
"colorStatusSuccessBorder2": "#107c10",
|
||||
"colorStatusSuccessBorderActive": "#107c10",
|
||||
"colorStatusSuccessForeground1": "#0e700e",
|
||||
"colorStatusSuccessForeground2": "#094509",
|
||||
"colorStatusSuccessForeground3": "#107c10",
|
||||
"colorStatusSuccessForegroundInverted": "#54b054",
|
||||
"colorStatusWarningBackground1": "#fff9f5",
|
||||
"colorStatusWarningBackground2": "#fdcfb4",
|
||||
"colorStatusWarningBackground3": "#f7630c",
|
||||
"colorStatusWarningBorder1": "#fdcfb4",
|
||||
"colorStatusWarningBorder2": "#bc4b09",
|
||||
"colorStatusWarningBorderActive": "#f7630c",
|
||||
"colorStatusWarningForeground1": "#bc4b09",
|
||||
"colorStatusWarningForeground2": "#8a3707",
|
||||
"colorStatusWarningForeground3": "#bc4b09",
|
||||
"colorStatusWarningForegroundInverted": "#faa06b",
|
||||
"colorStrokeFocus1": "#ffffff",
|
||||
"colorStrokeFocus2": "#000000",
|
||||
"colorSubtleBackground": "transparent",
|
||||
"colorSubtleBackgroundHover": "#f5f5f5",
|
||||
"colorSubtleBackgroundInverted": "transparent",
|
||||
"colorSubtleBackgroundInvertedHover": "rgba(0, 0, 0, 0.1)",
|
||||
"colorSubtleBackgroundInvertedPressed": "rgba(0, 0, 0, 0.3)",
|
||||
"colorSubtleBackgroundInvertedSelected": "rgba(0, 0, 0, 0.2)",
|
||||
"colorSubtleBackgroundLightAlphaHover": "rgba(255, 255, 255, 0.7)",
|
||||
"colorSubtleBackgroundLightAlphaPressed": "rgba(255, 255, 255, 0.5)",
|
||||
"colorSubtleBackgroundLightAlphaSelected": "transparent",
|
||||
"colorSubtleBackgroundPressed": "#e0e0e0",
|
||||
"colorSubtleBackgroundSelected": "#ebebeb",
|
||||
"colorTransparentBackground": "transparent",
|
||||
"colorTransparentBackgroundHover": "transparent",
|
||||
"colorTransparentBackgroundPressed": "transparent",
|
||||
"colorTransparentBackgroundSelected": "transparent",
|
||||
"colorTransparentStroke": "transparent",
|
||||
"colorTransparentStrokeDisabled": "transparent",
|
||||
"colorTransparentStrokeInteractive": "transparent",
|
||||
"curveAccelerateMax": "cubic-bezier(0.9,0.1,1,0.2)",
|
||||
"curveAccelerateMid": "cubic-bezier(1,0,1,1)",
|
||||
"curveAccelerateMin": "cubic-bezier(0.8,0,0.78,1)",
|
||||
"curveDecelerateMax": "cubic-bezier(0.1,0.9,0.2,1)",
|
||||
"curveDecelerateMid": "cubic-bezier(0,0,0,1)",
|
||||
"curveDecelerateMin": "cubic-bezier(0.33,0,0.1,1)",
|
||||
"curveEasyEase": "cubic-bezier(0.33,0,0.67,1)",
|
||||
"curveEasyEaseMax": "cubic-bezier(0.8,0,0.2,1)",
|
||||
"curveLinear": "cubic-bezier(0,0,1,1)",
|
||||
"durationFast": "150ms",
|
||||
"durationFaster": "100ms",
|
||||
"durationGentle": "250ms",
|
||||
"durationNormal": "200ms",
|
||||
"durationSlow": "300ms",
|
||||
"durationSlower": "400ms",
|
||||
"durationUltraFast": "50ms",
|
||||
"durationUltraSlow": "500ms",
|
||||
"fontFamilyBase": "'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif",
|
||||
"fontFamilyMonospace": "Consolas, 'Courier New', Courier, monospace",
|
||||
"fontFamilyNumeric": "Bahnschrift, 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif",
|
||||
"fontSizeBase100": "10px",
|
||||
"fontSizeBase200": "12px",
|
||||
"fontSizeBase300": "14px",
|
||||
"fontSizeBase400": "16px",
|
||||
"fontSizeBase500": "20px",
|
||||
"fontSizeBase600": "24px",
|
||||
"fontSizeHero1000": "68px",
|
||||
"fontSizeHero700": "28px",
|
||||
"fontSizeHero800": "32px",
|
||||
"fontSizeHero900": "40px",
|
||||
"fontWeightBold": 700,
|
||||
"fontWeightMedium": 500,
|
||||
"fontWeightRegular": 400,
|
||||
"fontWeightSemibold": 600,
|
||||
"lineHeightBase100": "14px",
|
||||
"lineHeightBase200": "16px",
|
||||
"lineHeightBase300": "20px",
|
||||
"lineHeightBase400": "22px",
|
||||
"lineHeightBase500": "28px",
|
||||
"lineHeightBase600": "32px",
|
||||
"lineHeightHero1000": "92px",
|
||||
"lineHeightHero700": "36px",
|
||||
"lineHeightHero800": "40px",
|
||||
"lineHeightHero900": "52px",
|
||||
"shadow16": "0 0 2px rgba(0,0,0,0.12), 0 8px 16px rgba(0,0,0,0.14)",
|
||||
"shadow16Brand": "0 0 2px rgba(0,0,0,0.30), 0 8px 16px rgba(0,0,0,0.25)",
|
||||
"shadow2": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
|
||||
"shadow28": "0 0 8px rgba(0,0,0,0.12), 0 14px 28px rgba(0,0,0,0.14)",
|
||||
"shadow28Brand": "0 0 8px rgba(0,0,0,0.30), 0 14px 28px rgba(0,0,0,0.25)",
|
||||
"shadow2Brand": "0 0 2px rgba(0,0,0,0.30), 0 1px 2px rgba(0,0,0,0.25)",
|
||||
"shadow4": "0 0 2px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.14)",
|
||||
"shadow4Brand": "0 0 2px rgba(0,0,0,0.30), 0 2px 4px rgba(0,0,0,0.25)",
|
||||
"shadow64": "0 0 8px rgba(0,0,0,0.12), 0 32px 64px rgba(0,0,0,0.14)",
|
||||
"shadow64Brand": "0 0 8px rgba(0,0,0,0.30), 0 32px 64px rgba(0,0,0,0.25)",
|
||||
"shadow8": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
|
||||
"shadow8Brand": "0 0 2px rgba(0,0,0,0.30), 0 4px 8px rgba(0,0,0,0.25)",
|
||||
"spacingHorizontalL": "16px",
|
||||
"spacingHorizontalM": "12px",
|
||||
"spacingHorizontalMNudge": "10px",
|
||||
"spacingHorizontalNone": "0",
|
||||
"spacingHorizontalS": "8px",
|
||||
"spacingHorizontalSNudge": "6px",
|
||||
"spacingHorizontalXL": "20px",
|
||||
"spacingHorizontalXS": "4px",
|
||||
"spacingHorizontalXXL": "24px",
|
||||
"spacingHorizontalXXS": "2px",
|
||||
"spacingHorizontalXXXL": "32px",
|
||||
"spacingVerticalL": "16px",
|
||||
"spacingVerticalM": "12px",
|
||||
"spacingVerticalMNudge": "10px",
|
||||
"spacingVerticalNone": "0",
|
||||
"spacingVerticalS": "8px",
|
||||
"spacingVerticalSNudge": "6px",
|
||||
"spacingVerticalXL": "20px",
|
||||
"spacingVerticalXS": "4px",
|
||||
"spacingVerticalXXL": "24px",
|
||||
"spacingVerticalXXS": "2px",
|
||||
"spacingVerticalXXXL": "32px",
|
||||
"strokeWidthThick": "2px",
|
||||
"strokeWidthThicker": "3px",
|
||||
"strokeWidthThickest": "4px",
|
||||
"strokeWidthThin": "1px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="tab-pane active documentsTab"
|
||||
role="tabpanel"
|
||||
style={
|
||||
Object {
|
||||
"display": "flex",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="filterdivs"
|
||||
>
|
||||
<div
|
||||
className="filterDocCollapsed"
|
||||
>
|
||||
<span
|
||||
className="selectQuery"
|
||||
>
|
||||
SELECT * FROM c
|
||||
</span>
|
||||
<span
|
||||
className="appliedQuery"
|
||||
/>
|
||||
<Button
|
||||
appearance="primary"
|
||||
onClick={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"marginLeft": 8,
|
||||
}
|
||||
}
|
||||
>
|
||||
Edit Filter
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"height": "100%",
|
||||
"overflow": "hidden",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Split
|
||||
mode="horizontal"
|
||||
prefixCls="w-split"
|
||||
visiable={true}
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"minWidth": 120,
|
||||
"overflow": "hidden",
|
||||
"position": "relative",
|
||||
"width": "35%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Button
|
||||
appearance="transparent"
|
||||
aria-label="Refresh"
|
||||
icon={<ArrowClockwise16Filled />}
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
size="small"
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "white",
|
||||
"color": undefined,
|
||||
"float": "right",
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 6,
|
||||
"zIndex": 1,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"height": "100%",
|
||||
"width": "calc(100% - 50px)",
|
||||
}
|
||||
}
|
||||
>
|
||||
<DocumentsTableComponent
|
||||
columnHeaders={
|
||||
Object {
|
||||
"idHeader": "id",
|
||||
"partitionKeyHeaders": Array [],
|
||||
}
|
||||
}
|
||||
items={Array []}
|
||||
onItemClicked={[Function]}
|
||||
onSelectedRowsChange={[Function]}
|
||||
selectedRows={
|
||||
Set {
|
||||
0,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"minWidth": "20%",
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Split>
|
||||
</div>
|
||||
</div>
|
||||
</FluentProvider>
|
||||
`;
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user