Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions apps/api/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const baseConfig = require('../../jest.config.cjs');

module.exports = {
testEnvironment: "node",
testRegex: "src[/\\\\].*\\.test\\.js$",
transform: {},
...baseConfig,
testEnvironment: 'node',
rootDir: '../..',
testMatch: ['**/apps/api/src/*.test.js'],
};
10 changes: 5 additions & 5 deletions apps/cli/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const baseConfig = require('../../jest.config.cjs');

module.exports = {
verbose: true,
...baseConfig,
testEnvironment: 'node',
transform: {
'^.+\\.js$': 'babel-jest',
},
testRegex: 'src[/\\\\]tests[/\\\\].*\\.test\\.js$',
rootDir: '../..',
testMatch: ['**/apps/cli/src/tests/**/*.test.js'],
};
7 changes: 5 additions & 2 deletions apps/mcp/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const baseConfig = require('../../jest.config.cjs');

module.exports = {
...baseConfig,
testEnvironment: 'node',
transform: {},
testRegex: 'src[/\\\\].*\\.test\\.js$',
rootDir: '../..',
testMatch: ['**/apps/mcp/src/*.test.js'],
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class GridEditorComponent {
this.toolbar = this.container.locator('[data-role="grid-toolbar-root"]');
this.errorStatus = this.container.locator('[data-role="grid-error-status"]').first();
this.grid = this.container.locator('[data-role="data-grid-root"]');
this.contextMenu = this.page.locator('[data-role="data-grid-context-menu"]');
this.renderer = new GridRendererComponent(page, this.grid);
this.header = new GridHeaderComponent(page, this.grid, this.renderer);
this.confirmDialog = new ConfirmDialogComponent(page);
Expand Down Expand Up @@ -176,6 +177,24 @@ class GridEditorComponent {
await this._acceptConfirmIfVisible();
}

async openContextMenuOnCell(columnName, rowIndex) {
const columnIndex = await this.renderer._columnIndexByName(columnName);
await this.renderer.row(rowIndex).locator('.tabulator-cell').nth(columnIndex).click({ button: 'right' });
await expect(this.contextMenu).toBeVisible();
}

async contextMenuAddRow() {
await this.contextMenu.getByRole('button', { name: 'Add Row', exact: true }).click();
}

async contextMenuSetUniqueColumnNames(enabled = true) {
const checkbox = this.contextMenu.getByRole('checkbox', { name: 'Enforce Unique Column Names' });
const isChecked = await checkbox.isChecked();
if (isChecked !== enabled) {
await checkbox.click();
}
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.

async setUniqueColumnNames(enabled = true) {
if (enabled) {
await this.uniqueColumnNamesCheckbox.check();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { test } = require('@playwright/test');
const { openApp, seedRows, expectNoPageErrors, expect } = require('../../../abstractions/helpers/scenario-helpers');

test.describe('1. Grid Basic Operations', () => {
test('Right click context menu can add rows and sync unique column names to the toolbar', async ({ page }) => {
const { appPage, pageErrors } = await openApp(page);
await seedRows(appPage, ['Alpha', 'Beta']);

const [columnName] = await appPage.gridEditor.header.getColumnNames();
const initialRowCount = await appPage.gridEditor.renderer.countRows();

await appPage.gridEditor.openContextMenuOnCell(columnName, 0);
await appPage.gridEditor.contextMenuAddRow();
await expect.poll(async () => appPage.gridEditor.renderer.countRows()).toBe(initialRowCount + 1);

await appPage.gridEditor.openContextMenuOnCell(columnName, 0);
await appPage.gridEditor.contextMenuSetUniqueColumnNames(true);
await expect(appPage.gridEditor.uniqueColumnNamesCheckbox).toBeChecked();
await expect(appPage.gridEditor.contextMenu).toBeHidden();

expectNoPageErrors(pageErrors);
});
});
7 changes: 5 additions & 2 deletions apps/web/src/tests/jest/script-bootstrap.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ describe('script bootstrap', () => {
expect(createDataGridComponentFn).toHaveBeenCalledWith({
root: dom.window.document.getElementById('main-grid-view'),
documentObj: dom.window.document,
services: {
services: expect.objectContaining({
TabulatorCtor: globalThis.Tabulator,
GridExtensionClass: expect.any(Function),
},
getPreviewExportFormats: expect.any(Function),
previewAs: expect.any(Function),
exportAs: expect.any(Function),
}),
});
expect(dom.window.document.getElementById('initial-load')).toBeNull();
});
Expand Down
7 changes: 5 additions & 2 deletions apps/web/src/tests/jest/script-module-init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,13 @@ describe('script module initialization', () => {
expect(createDataGridComponent).toHaveBeenCalledWith({
root: global.document.getElementById('main-grid-view'),
documentObj: global.document,
services: {
services: expect.objectContaining({
TabulatorCtor: globalThis.Tabulator,
GridExtensionClass: expect.any(Function),
},
getPreviewExportFormats: expect.any(Function),
previewAs: expect.any(Function),
exportAs: expect.any(Function),
}),
});
expect(createImportExportWorkspaceComponent).toHaveBeenCalledWith({
root: global.document.getElementById('import-export-controls'),
Expand Down
55 changes: 55 additions & 0 deletions apps/web/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,61 @@ Custom header styles for default items
height: 0.8rem;
}

.data-grid-context-menu {
position: fixed;
z-index: 2500;
min-width: 14rem;
max-width: min(22rem, calc(100vw - 1rem));
padding: 0.45rem;
border: 1px solid var(--border-color);
border-radius: 8px;
background: var(--panel-bg);
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
}

.data-grid-context-menu__section,
.data-grid-context-menu__submenu {
display: grid;
gap: 0.25rem;
}

.data-grid-context-menu__section > button,
.data-grid-context-menu__submenu > button {
width: 100%;
text-align: left;
}

.data-grid-context-menu__separator {
height: 1px;
margin: 0.45rem 0;
background: color-mix(in srgb, var(--border-color) 75%, transparent);
}

.data-grid-context-menu__checkbox {
display: flex;
align-items: center;
gap: 0.45rem;
font-size: 0.95rem;
}

.data-grid-context-menu__details {
margin: 0;
}

.data-grid-context-menu__details > summary {
cursor: pointer;
font-weight: 600;
}

.data-grid-context-menu__details[open] {
border: 0;
background: transparent;
}

.data-grid-context-menu__details[open] > summary {
margin-bottom: 0.35rem;
}

/* Docs */

.bodycontent {
Expand Down
21 changes: 21 additions & 0 deletions jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
verbose: true,
transform: {},
testMatch: [
'**/packages/core/src/tests/**/*.test.js',
'**/packages/core-ui/src/tests/**/*.test.js',
'**/tests/integration/**/*.test.js',
'**/apps/web/src/tests/jest/**/*.test.js',
],
testPathIgnorePatterns: ['/node_modules/', '/tests/browser/', '/apps/web/src/tests/browser/'],
modulePathIgnorePatterns: ['<rootDir>/build/'],
collectCoverageFrom: ['packages/**/*.js', '!packages/core/js/libs/**'],
moduleNameMapper: {
'^@anywaydata/core$': '<rootDir>/packages/core/src/index.js',
'^@anywaydata/core/(.*)$': '<rootDir>/packages/core/js/$1',
'^@anywaydata/core/data_formats/(.*)$': '<rootDir>/packages/core/js/data_formats/$1',
'https://cdn.skypack.dev/@faker-js/faker@v9.7.0': '@faker-js/faker',
'https://unpkg.com/papaparse@5.5.2/papaparse.min.js': 'papaparse',
'/libs/randexp.min.js': 'randexp',
},
};
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
"apps/*"
],
"scripts": {
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js",
"testverbose": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --verbose",
"testcoverage": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --coverage",
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs",
"testverbose": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs --verbose",
"testcoverage": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs --coverage",
"storybook": "storybook dev -p 6006",
"build-storybook": "node ./scripts/run-build-storybook.mjs",
"test:storybook": "node ./scripts/run-storybook-tests.mjs",
"test:ui:jest": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js packages/core-ui/src/tests apps/web/src/tests/jest",
"test:ui:jest": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs --testPathPatterns packages/core-ui/src/tests apps/web/src/tests/jest",
"testenv:create": "node ./scripts/create-testenv.mjs",
"generate:faker-help": "node ./scripts/generate-faker-help.js",
"test:browser": "node ./node_modules/@playwright/test/cli.js test",
Expand All @@ -38,7 +38,7 @@
"build:web": "vite build --config ./apps/web/vite.config.mjs",
"preview:web": "vite preview --config ./apps/web/vite.config.mjs",
"serve:web": "pnpm run dev:web",
"benchmark:tabulator": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js packages/core-ui/src/tests/grid/tabulator-performance.benchmark.test.js --runInBand",
"benchmark:tabulator": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --config ./jest.config.cjs --runTestsByPath packages/core-ui/src/tests/grid/tabulator-performance.benchmark.test.js --runInBand",
"anywaydata:mac": "pnpm --dir docs-src run anywaydata && pnpm run build:web && node ./scripts/merge-web-build-into-docs-build.js && cp -R ./build/ ../../anywaydata-com",
"anywaydata:win": "pnpm --dir docs-src run anywaydata && pnpm run build:web && node .\\scripts\\merge-web-build-into-docs-build.js && echo cleaning anywaydata for deployment && ..\\anywaydata-com\\make-ready-for-prod.bat",
"previewdocs": "pnpm --dir docs-src run start",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,24 @@ function createImportExportWorkspaceRuntime({ root, props = {}, services = {}, d
setFileFormatType(format) {
workflow.handleFormatChange(format ?? getType());
},
openDetails() {
view.openToolbarDetails?.();
render();
},
previewAs(format) {
const selectedFormat = format ?? getType();
if (controller.getState().mode !== 'preview') {
controller.updateProps({ mode: 'preview', previewTextDirty: false });
render();
}
workflow.handleFormatChange(selectedFormat);
return workflow.renderTextFromGrid();
},
async downloadAs(format) {
const selectedFormat = format ?? getType();
workflow.handleFormatChange(selectedFormat);
return workflow.fileDownload();
},
setOptionsViewForFormatType: workflow.setOptionsViewForFormatType,
setCurrentTypeOptions: workflow.setCurrentTypeOptions,
applyCurrentTypeOptions(options) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ class ImportExportWorkspaceView {
return this.textPreviewEditor?.getTextArea?.() || null;
}

getToolbarDetailsElement() {
return this.getElementByRole('import-export-toolbar-details');
}

openToolbarDetails() {
const detailsElement = this.getToolbarDetailsElement();
if (detailsElement) {
detailsElement.open = true;
}
}

setCopyButtonText(value) {
this.textPreviewEditor?.setCopyButtonText?.(value);
}
Expand Down
23 changes: 23 additions & 0 deletions packages/core-ui/js/gui_components/app/page/app-page-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createDataGridComponent } from '../../data-grid-editor/index.js';
import { ensureGridLibraryLoaded } from '../../data-grid-editor/grid-library-loader.js';
import { GridExtension as TabulatorGridExtension } from '../../data-grid-editor/tabulator/gridExtension-tabulator.js';
import { createImportExportWorkspaceComponent } from '../import-export-workspace/index.js';
import { createDefaultTabDefinitions } from '../format-selector/format-selector-controller.js';
import { createInstructionsComponent } from '../../shared/instructions/index.js';
import { APP_PAGE_INSTRUCTIONS_PROPS } from '../../shared/instructions/app-page-instructions.js';
import { createAppPageComponent } from './app-page-shell.js';
Expand Down Expand Up @@ -117,6 +118,18 @@ function createInstructionsGridActions({ documentObj = getDefaultDocumentObj(),
};
}

function createContextMenuFormatItems() {
return createDefaultTabDefinitions().flatMap((definition) => {
if (Array.isArray(definition.subtasks)) {
return definition.subtasks.map((subtask) => ({
type: subtask.selectedType || subtask.type,
label: subtask.label,
}));
Comment thread
eviltester marked this conversation as resolved.
}
return definition.type ? [{ type: definition.type, label: definition.label }] : [];
});
}

async function bootstrapApp({
documentObj = getDefaultDocumentObj(),
ensureGridLibraryLoadedFn = ensureGridLibraryLoaded,
Expand Down Expand Up @@ -168,13 +181,23 @@ async function bootstrapApp({
let exporter = null;
let importer = null;
let instructionsGridActions = null;
const contextMenuFormatItems = createContextMenuFormatItems();
try {
mainDataGrid = createDataGridComponentFn({
root: documentObj.getElementById('main-grid-view'),
documentObj,
services: {
TabulatorCtor: resolvedTabulatorCtor,
GridExtensionClass,
getPreviewExportFormats: () => contextMenuFormatItems,
previewAs: async (format) => {
importExportController?.openDetails?.();
return importExportController?.previewAs?.(format);
},
exportAs: async (format) => {
importExportController?.openDetails?.();
return importExportController?.downloadAs?.(format);
},
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class DataGridComponentController {
this.getGridExtras()?.clearSort?.();
}

sizeColumnsToFit() {
this.getGridExtras()?.sizeColumnsToFit?.();
}

setFilterText(filterText) {
this.state.filterText = filterText || '';
this.getGridExtras()?.filterText?.(this.state.filterText);
Expand Down
Loading