mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 21:26:00 +00:00
admin screenshots
This commit is contained in:
@@ -32,6 +32,9 @@ module.exports = defineConfig({
|
||||
case 'browse-data':
|
||||
serverProcess = exec('yarn start:browse-data');
|
||||
break;
|
||||
case 'team':
|
||||
serverProcess = exec('yarn start:team');
|
||||
break;
|
||||
}
|
||||
|
||||
await waitOn({ resources: ['http://localhost:3000'] });
|
||||
|
||||
@@ -321,4 +321,31 @@ describe('Data browser data', () => {
|
||||
cy.testid('WidgetIconPanel_cell-data').click();
|
||||
cy.themeshot('collection');
|
||||
});
|
||||
|
||||
it('Table structure editor', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('Customer').rightclick();
|
||||
cy.contains('Open structure').click();
|
||||
cy.contains('varchar(40)');
|
||||
cy.themeshot('structure');
|
||||
cy.contains('EmployeeId').click();
|
||||
cy.contains('Ref column - Employee');
|
||||
cy.themeshot('fkeditor');
|
||||
});
|
||||
|
||||
it('Compare database', () => {
|
||||
// TODO FIX: SQL diff is not dark in dark mode
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.contains('MyChangedChinook').rightclick();
|
||||
cy.contains('Compare with').click();
|
||||
cy.testid('CompareModelTab_gridObjects_Customer_Customer').click();
|
||||
cy.testid('WidgetIconPanel_database').click();
|
||||
cy.testid('CompareModelTab_tabDdl').click();
|
||||
cy.themeshot('dbcompare');
|
||||
cy.contains('Settings').click();
|
||||
cy.testid('CompareModelTab_tabOperations').click();
|
||||
cy.themeshot('comparesettings');
|
||||
});
|
||||
});
|
||||
|
||||
30
e2e-tests/cypress/e2e/team.cy.js
Normal file
30
e2e-tests/cypress/e2e/team.cy.js
Normal file
@@ -0,0 +1,30 @@
|
||||
beforeEach(() => {
|
||||
cy.visit('http://localhost:3000');
|
||||
cy.viewport(1250, 900);
|
||||
});
|
||||
|
||||
describe('Team edition tests', () => {
|
||||
it('Data archive editor - macros', () => {
|
||||
cy.testid('LoginPage_linkAdmin').click();
|
||||
cy.testid('LoginPage_password').type('adminpwd');
|
||||
cy.testid('LoginPage_submitLogin').click();
|
||||
|
||||
cy.testid('AdminMenuWidget_itemConnections').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.contains('New connection').click();
|
||||
cy.testid('ConnectionDriverFields_connectionType').select('PostgreSQL');
|
||||
cy.themeshot('connadmin');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemRoles').click();
|
||||
cy.contains('Permissions').click();
|
||||
cy.themeshot('roleadmin');
|
||||
|
||||
cy.testid('AdminMenuWidget_itemAuthentication').click();
|
||||
cy.contains('Add authentication').click();
|
||||
cy.contains('Use database login').click();
|
||||
cy.contains('Add authentication').click();
|
||||
cy.contains('OAuth 2.0').click();
|
||||
cy.themeshot('authadmin');
|
||||
});
|
||||
});
|
||||
176
e2e-tests/data/chinook-mysql-changed.sql
Normal file
176
e2e-tests/data/chinook-mysql-changed.sql
Normal file
@@ -0,0 +1,176 @@
|
||||
|
||||
/*******************************************************************************
|
||||
Create Tables
|
||||
********************************************************************************/
|
||||
CREATE TABLE `Album`
|
||||
(
|
||||
`AlbumId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(160) NOT NULL,
|
||||
`ArtistId` INT NOT NULL,
|
||||
CONSTRAINT `PK_Album` PRIMARY KEY (`AlbumId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Artist`
|
||||
(
|
||||
`ArtistId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(120),
|
||||
CONSTRAINT `PK_Artist` PRIMARY KEY (`ArtistId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Customer`
|
||||
(
|
||||
`CustomerId` INT NOT NULL AUTO_INCREMENT,
|
||||
`FirstName` NVARCHAR(40) NOT NULL,
|
||||
`LastName` NVARCHAR(20) NOT NULL,
|
||||
`MiddleName` NVARCHAR(20) NOT NULL,
|
||||
`Company` NVARCHAR(80),
|
||||
`Street` NVARCHAR(70),
|
||||
`City` NVARCHAR(40),
|
||||
`State` NVARCHAR(40),
|
||||
`Country` NVARCHAR(40),
|
||||
`PostalCode` NVARCHAR(10),
|
||||
`Phone` NVARCHAR(24),
|
||||
`Fax` NVARCHAR(24),
|
||||
`Email` NVARCHAR(60) NOT NULL,
|
||||
`SupportRepId` INT,
|
||||
CONSTRAINT `PK_Customer` PRIMARY KEY (`CustomerId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Employee`
|
||||
(
|
||||
`EmployeeId` INT NOT NULL AUTO_INCREMENT,
|
||||
`LastName` NVARCHAR(20) NOT NULL,
|
||||
`FirstName` NVARCHAR(20) NOT NULL,
|
||||
`Title` NVARCHAR(30),
|
||||
`ReportsTo` INT,
|
||||
`BirthDate` DATETIME,
|
||||
`HireDate` DATETIME,
|
||||
`Address` NVARCHAR(70),
|
||||
`City` NVARCHAR(40),
|
||||
`State` NVARCHAR(40),
|
||||
`Country` NVARCHAR(40),
|
||||
`PostalCode` NVARCHAR(10),
|
||||
`Phone` NVARCHAR(24),
|
||||
`Fax` NVARCHAR(24),
|
||||
`Email` NVARCHAR(60),
|
||||
CONSTRAINT `PK_Employee` PRIMARY KEY (`EmployeeId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Genre`
|
||||
(
|
||||
`GenreId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(120),
|
||||
CONSTRAINT `PK_Genre` PRIMARY KEY (`GenreId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Genre_Backup`
|
||||
(
|
||||
`GenreId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(120),
|
||||
CONSTRAINT `PK_GenreBackup` PRIMARY KEY (`GenreId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Invoice`
|
||||
(
|
||||
`InvoiceId` INT NOT NULL AUTO_INCREMENT,
|
||||
`CustomerId` INT NOT NULL,
|
||||
`InvoiceDate` DATETIME NOT NULL,
|
||||
`BillingAddress` NVARCHAR(70),
|
||||
`BillingCity` NVARCHAR(40),
|
||||
`BillingState` NVARCHAR(40),
|
||||
`BillingCountry` NVARCHAR(40),
|
||||
`BillingPostalCode` NVARCHAR(10),
|
||||
`Total` NUMERIC(10,2) NOT NULL,
|
||||
CONSTRAINT `PK_Invoice` PRIMARY KEY (`InvoiceId`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `MediaType`
|
||||
(
|
||||
`MediaTypeId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(120),
|
||||
CONSTRAINT `PK_MediaType` PRIMARY KEY (`MediaTypeId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Playlist`
|
||||
(
|
||||
`PlaylistId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(120),
|
||||
CONSTRAINT `PK_Playlist` PRIMARY KEY (`PlaylistId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `PlaylistTrack`
|
||||
(
|
||||
`PlaylistId` INT NOT NULL,
|
||||
`TrackId` INT NOT NULL,
|
||||
CONSTRAINT `PK_PlaylistTrack` PRIMARY KEY (`PlaylistId`, `TrackId`)
|
||||
);
|
||||
|
||||
CREATE TABLE `Track`
|
||||
(
|
||||
`TrackId` INT NOT NULL AUTO_INCREMENT,
|
||||
`Name` NVARCHAR(200) NOT NULL,
|
||||
`AlbumId` INT,
|
||||
`MediaTypeId` INT NOT NULL,
|
||||
`GenreId` INT,
|
||||
`Composer` NVARCHAR(220),
|
||||
`Milliseconds` INT NOT NULL,
|
||||
`Bytes` INT,
|
||||
`UnitPrice` NUMERIC(10,2) NOT NULL,
|
||||
CONSTRAINT `PK_Track` PRIMARY KEY (`TrackId`)
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Create Primary Key Unique Indexes
|
||||
********************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
Create Foreign Keys
|
||||
********************************************************************************/
|
||||
ALTER TABLE `Album` ADD CONSTRAINT `FK_AlbumArtistId`
|
||||
FOREIGN KEY (`ArtistId`) REFERENCES `Artist` (`ArtistId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_AlbumArtistId` ON `Album` (`ArtistId`);
|
||||
|
||||
ALTER TABLE `Customer` ADD CONSTRAINT `FK_CustomerSupportRepId`
|
||||
FOREIGN KEY (`SupportRepId`) REFERENCES `Employee` (`EmployeeId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_CustomerSupportRepId` ON `Customer` (`SupportRepId`);
|
||||
|
||||
ALTER TABLE `Employee` ADD CONSTRAINT `FK_EmployeeReportsTo`
|
||||
FOREIGN KEY (`ReportsTo`) REFERENCES `Employee` (`EmployeeId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_EmployeeReportsTo` ON `Employee` (`ReportsTo`);
|
||||
|
||||
ALTER TABLE `Invoice` ADD CONSTRAINT `FK_InvoiceCustomerId`
|
||||
FOREIGN KEY (`CustomerId`) REFERENCES `Customer` (`CustomerId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_InvoiceCustomerId` ON `Invoice` (`CustomerId`);
|
||||
|
||||
ALTER TABLE `PlaylistTrack` ADD CONSTRAINT `FK_PlaylistTrackPlaylistId`
|
||||
FOREIGN KEY (`PlaylistId`) REFERENCES `Playlist` (`PlaylistId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_PlaylistTrackPlaylistId` ON `PlaylistTrack` (`PlaylistId`);
|
||||
|
||||
ALTER TABLE `PlaylistTrack` ADD CONSTRAINT `FK_PlaylistTrackTrackId`
|
||||
FOREIGN KEY (`TrackId`) REFERENCES `Track` (`TrackId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_PlaylistTrackTrackId` ON `PlaylistTrack` (`TrackId`);
|
||||
|
||||
ALTER TABLE `Track` ADD CONSTRAINT `FK_TrackAlbumId`
|
||||
FOREIGN KEY (`AlbumId`) REFERENCES `Album` (`AlbumId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_TrackAlbumId` ON `Track` (`AlbumId`);
|
||||
|
||||
ALTER TABLE `Track` ADD CONSTRAINT `FK_TrackGenreId`
|
||||
FOREIGN KEY (`GenreId`) REFERENCES `Genre` (`GenreId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_TrackGenreId` ON `Track` (`GenreId`);
|
||||
|
||||
ALTER TABLE `Track` ADD CONSTRAINT `FK_TrackMediaTypeId`
|
||||
FOREIGN KEY (`MediaTypeId`) REFERENCES `MediaType` (`MediaTypeId`) ON DELETE NO ACTION ON UPDATE NO ACTION;
|
||||
|
||||
CREATE INDEX `IFK_TrackMediaTypeId` ON `Track` (`MediaTypeId`);
|
||||
|
||||
7
e2e-tests/env/team/.env
vendored
Normal file
7
e2e-tests/env/team/.env
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
STORAGE_SERVER=localhost
|
||||
STORAGE_USER=root
|
||||
STORAGE_PASSWORD=Pwd2020Db
|
||||
STORAGE_PORT=16004
|
||||
STORAGE_DATABASE=DbGateInternal
|
||||
STORAGE_ENGINE=mysql@dbgate-plugin-mysql
|
||||
ADMIN_PASSWORD=adminpwd
|
||||
@@ -178,6 +178,7 @@ async function copyFolder(source, target) {
|
||||
|
||||
async function run() {
|
||||
await initMySqlDatabase('MyChinook', path.resolve(path.join(__dirname, '../data/chinook-mysql.sql')));
|
||||
await initMySqlDatabase('MyChangedChinook', path.resolve(path.join(__dirname, '../data/chinook-mysql-changed.sql')));
|
||||
// await initMySqlDatabase('Northwind', path.resolve(path.join(__dirname, '../data/northwind-mysql.sql')));
|
||||
// await initMySqlDatabase('Sakila', path.resolve(path.join(__dirname, '../data/sakila-mysql.sql')));
|
||||
|
||||
|
||||
34
e2e-tests/init/team.js
Normal file
34
e2e-tests/init/team.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const dbgateApi = require('dbgate-api');
|
||||
dbgateApi.initializeApiEnvironment();
|
||||
const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
|
||||
async function initStorageDatabase() {
|
||||
await dbgateApi.executeQuery({
|
||||
connection: {
|
||||
server: process.env.STORAGE_SERVER,
|
||||
user: process.env.STORAGE_USER,
|
||||
password: process.env.STORAGE_PASSWORD,
|
||||
port: process.env.STORAGE_PORT,
|
||||
engine: process.env.STORAGE_ENGINE,
|
||||
},
|
||||
sql: `drop database if exists ${process.env.STORAGE_DATABASE}`,
|
||||
});
|
||||
|
||||
await dbgateApi.executeQuery({
|
||||
connection: {
|
||||
server: process.env.STORAGE_SERVER,
|
||||
user: process.env.STORAGE_USER,
|
||||
password: process.env.STORAGE_PASSWORD,
|
||||
port: process.env.STORAGE_PORT,
|
||||
engine: process.env.STORAGE_ENGINE,
|
||||
},
|
||||
sql: `create database ${process.env.STORAGE_DATABASE}`,
|
||||
});
|
||||
}
|
||||
|
||||
async function run() {
|
||||
await initStorageDatabase();
|
||||
}
|
||||
|
||||
dbgateApi.runScript(run);
|
||||
@@ -14,15 +14,26 @@
|
||||
},
|
||||
"scripts": {
|
||||
"cy:open": "cypress open --config experimentalInteractiveRunEvents=true",
|
||||
|
||||
"cy:run:add-connection": "cypress run --spec cypress/e2e/add-connection.cy.js",
|
||||
"cy:run:portal": "cypress run --spec cypress/e2e/portal.cy.js",
|
||||
"cy:run:oauth": "cypress run --spec cypress/e2e/oauth.cy.js",
|
||||
"cy:run:browse-data": "cypress run --spec cypress/e2e/browse-data.cy.js",
|
||||
"cy:run:team": "cypress run --spec cypress/e2e/team.cy.js",
|
||||
|
||||
"start:add-connection": "cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:portal": "cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:oauth": "cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"start:browse-data": "cd .. && env-cmd -f e2e-tests/env/browse-data/.env node e2e-tests/init/browse-data.js && env-cmd -f e2e-tests/env/browse-data/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
"test": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection && start-server-and-test start:portal http://localhost:3000 cy:run:portal && start-server-and-test start:oauth http://localhost:3000 cy:run:oauth && start-server-and-test start:browse-data http://localhost:3000 cy:run:browse-data",
|
||||
"start:team": "cd .. && env-cmd -f e2e-tests/env/team/.env node e2e-tests/init/team.js && env-cmd -f e2e-tests/env/team/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
|
||||
|
||||
"test:add-connection": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection",
|
||||
"test:portal": "start-server-and-test start:portal http://localhost:3000 cy:run:portal",
|
||||
"test:oauth": "start-server-and-test start:oauth http://localhost:3000 cy:run:oauth",
|
||||
"test:browse-data": "start-server-and-test start:browse-data http://localhost:3000 cy:run:browse-data",
|
||||
"test:team": "start-server-and-test start:team http://localhost:3000 cy:run:team",
|
||||
|
||||
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team",
|
||||
"test:ci": "yarn test"
|
||||
},
|
||||
"dependencies": {}
|
||||
|
||||
@@ -137,9 +137,9 @@
|
||||
<div class="login-link">
|
||||
{#if $config?.isAdminLoginForm}
|
||||
{#if isAdminPage}
|
||||
<Link internalRedirect="/login.html">Log In as Regular User</Link>
|
||||
<Link internalRedirect="/login.html" data-testid="LoginPage_linkRegularUser">Log In as Regular User</Link>
|
||||
{:else}
|
||||
<Link internalRedirect="/admin-login.html">Log In as Administrator</Link>
|
||||
<Link internalRedirect="/admin-login.html" data-testid="LoginPage_linkAdmin">Log In as Administrator</Link>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
@@ -164,17 +164,41 @@
|
||||
|
||||
{#if selectedConnection}
|
||||
{#if selectedConnection.passwordMode == 'askUser'}
|
||||
<FormTextField label="Username" name="login" autocomplete="username" saveOnInput />
|
||||
<FormTextField
|
||||
label="Username"
|
||||
name="login"
|
||||
autocomplete="username"
|
||||
saveOnInput
|
||||
data-testid="LoginPage_username"
|
||||
/>
|
||||
{/if}
|
||||
{#if selectedConnection.passwordMode == 'askUser' || selectedConnection.passwordMode == 'askPassword'}
|
||||
<FormPasswordField label="Password" name="password" autocomplete="current-password" saveOnInput />
|
||||
<FormPasswordField
|
||||
label="Password"
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
saveOnInput
|
||||
data-testid="LoginPage_password"
|
||||
/>
|
||||
{/if}
|
||||
{:else}
|
||||
{#if !isAdminPage && workflowType == 'credentials'}
|
||||
<FormTextField label="Username" name="login" autocomplete="username" saveOnInput />
|
||||
<FormTextField
|
||||
label="Username"
|
||||
name="login"
|
||||
autocomplete="username"
|
||||
saveOnInput
|
||||
data-testid="LoginPage_username"
|
||||
/>
|
||||
{/if}
|
||||
{#if workflowType == 'credentials'}
|
||||
<FormPasswordField label="Password" name="password" autocomplete="current-password" saveOnInput />
|
||||
<FormPasswordField
|
||||
label="Password"
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
saveOnInput
|
||||
data-testid="LoginPage_password"
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -199,6 +223,7 @@
|
||||
{#if selectedConnection?.useRedirectDbLogin}
|
||||
<FormSubmit
|
||||
value="Open database login page"
|
||||
data-testid="LoginPage_submitLogin"
|
||||
on:click={async e => {
|
||||
const state = `dbg-dblogin:${strmid}:${selectedConnection?.conid}:${$values.amoid}`;
|
||||
sessionStorage.setItem('dbloginAuthState', state);
|
||||
@@ -210,6 +235,7 @@
|
||||
{:else if selectedConnection}
|
||||
<FormSubmit
|
||||
value="Log In"
|
||||
data-testid="LoginPage_submitLogin"
|
||||
on:click={async e => {
|
||||
if (selectedConnection.passwordMode == 'askUser' || selectedConnection.passwordMode == 'askPassword') {
|
||||
enableApi();
|
||||
@@ -257,6 +283,7 @@
|
||||
await processRedirectLogin($values.amoid);
|
||||
}
|
||||
}}
|
||||
data-testid="LoginPage_submitLogin"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -264,7 +291,11 @@
|
||||
|
||||
<svelte:fragment slot="bottom-buttons">
|
||||
{#each availableProviders.filter(x => x.workflowType == 'anonymous' || x.workflowType == 'redirect') as provider}
|
||||
<div class="loginButton" on:click={() => processSingleProvider(provider)}>
|
||||
<div
|
||||
class="loginButton"
|
||||
on:click={() => processSingleProvider(provider)}
|
||||
data-testid={`LoginPage_loginButton_${provider.name}`}
|
||||
>
|
||||
{provider.name}
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
export let vertical = false;
|
||||
</script>
|
||||
|
||||
<div on:click|stopPropagation class="collapseButtonMarker">
|
||||
<div on:click|stopPropagation class="collapseButtonMarker" {...$$restProps}>
|
||||
<FontIcon
|
||||
icon={collapsed
|
||||
? vertical
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
else openWebLink(href);
|
||||
}}
|
||||
use:contextMenu={menu}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
headerSlot?: number;
|
||||
isHighlighted?: Function;
|
||||
width?: string;
|
||||
testid?: (row: any) => string;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -173,6 +174,7 @@
|
||||
<td
|
||||
class:isHighlighted={col.isHighlighted && col.isHighlighted(row)}
|
||||
style={col.width ? `width: ${col.width}` : undefined}
|
||||
data-testid={col.testid ? col.testid(row) : undefined}
|
||||
>
|
||||
{#if col.component}
|
||||
<svelte:component this={col.component} {...col.getProps(row)} />
|
||||
@@ -237,7 +239,7 @@
|
||||
table.singleLineRow tbody tr td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
table tbody {
|
||||
display: block;
|
||||
overflow-y: scroll;
|
||||
|
||||
Reference in New Issue
Block a user