mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Styling updates for HDFS Manage Access Dialog (#7551)
This commit is contained in:
3
extensions/mssql/resources/dark/delete_inverse.svg
Normal file
3
extensions/mssql/resources/dark/delete_inverse.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" width="24" height="24">
|
||||
<path d="M1792 384h-128v1472q0 40-15 75t-41 61-61 41-75 15H448q-40 0-75-15t-61-41-41-61-15-75V384H128V256h512V128q0-27 10-50t27-40 41-28 50-10h384q27 0 50 10t40 27 28 41 10 50v128h512v128zM768 256h384V128H768v128zm768 128H384v1472q0 26 19 45t45 19h1024q26 0 45-19t19-45V384zM768 1664H640V640h128v1024zm256 0H896V640h128v1024zm256 0h-128V640h128v1024z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
3
extensions/mssql/resources/light/delete.svg
Normal file
3
extensions/mssql/resources/light/delete.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" width="24" height="24">
|
||||
<path d="M1792 384h-128v1472q0 40-15 75t-41 61-61 41-75 15H448q-40 0-75-15t-61-41-41-61-15-75V384H128V256h512V128q0-27 10-50t27-40 41-28 50-10h384q27 0 50 10t40 27 28 41 10 50v128h512v128zM768 256h384V128H768v128zm768 128H384v1472q0 26 19 45t45 19h1024q26 0 45-19t19-45V384zM768 1664H640V640h128v1024zm256 0H896V640h128v1024zm256 0h-128V640h128v1024z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
@@ -8,9 +8,10 @@ import { HdfsModel } from '../hdfsModel';
|
||||
import { IFileSource } from '../../objectExplorerNodeProvider/fileSources';
|
||||
import { IAclStatus, AclEntry, AclEntryType } from '../../hdfs/aclEntry';
|
||||
import { cssStyles } from './uiConstants';
|
||||
import { ownersHeader, permissionsHeader, stickyHeader, readHeader, writeHeader, executeHeader, manageAccessTitle, allOthersHeader, addUserOrGroupHeader, enterNamePlaceholder, addLabel, accessHeader, defaultHeader, applyText, applyRecursivelyText, userLabel, groupLabel, errorApplyingAclChanges } from '../../localizedConstants';
|
||||
import * as loc from '../../localizedConstants';
|
||||
import { HdfsError } from '../webhdfs';
|
||||
import { ApiWrapper } from '../../apiWrapper';
|
||||
import { IconPathHelper } from '../../iconHelper';
|
||||
|
||||
const permissionsNameColumnWidth = 250;
|
||||
const permissionsStickyColumnWidth = 50;
|
||||
@@ -19,7 +20,8 @@ const permissionsWriteColumnWidth = 50;
|
||||
const permissionsExecuteColumnWidth = 50;
|
||||
const permissionsDeleteColumnWidth = 50;
|
||||
|
||||
const permissionsRowHeight = 75;
|
||||
const permissionsRowHeight = 35;
|
||||
const locationLabelHeight = 23; // Fits the text size without too much white space
|
||||
|
||||
export class ManageAccessDialog {
|
||||
|
||||
@@ -43,15 +45,15 @@ export class ManageAccessDialog {
|
||||
|
||||
public openDialog(): void {
|
||||
if (!this.dialog) {
|
||||
this.dialog = this.apiWrapper.createDialog(manageAccessTitle, 'HdfsManageAccess', true);
|
||||
this.dialog.okButton.label = applyText;
|
||||
this.dialog = this.apiWrapper.createDialog(loc.manageAccessTitle, 'HdfsManageAccess', true);
|
||||
this.dialog.okButton.label = loc.applyText;
|
||||
|
||||
const applyRecursivelyButton = azdata.window.createButton(applyRecursivelyText);
|
||||
const applyRecursivelyButton = azdata.window.createButton(loc.applyRecursivelyText);
|
||||
applyRecursivelyButton.onClick(async () => {
|
||||
try {
|
||||
await this.hdfsModel.apply(true);
|
||||
} catch (err) {
|
||||
this.apiWrapper.showErrorMessage(errorApplyingAclChanges(err instanceof HdfsError ? err.message : err));
|
||||
this.apiWrapper.showErrorMessage(loc.errorApplyingAclChanges(err instanceof HdfsError ? err.message : err));
|
||||
}
|
||||
});
|
||||
this.dialog.customButtons = [applyRecursivelyButton];
|
||||
@@ -60,11 +62,11 @@ export class ManageAccessDialog {
|
||||
await this.hdfsModel.apply();
|
||||
return true;
|
||||
} catch (err) {
|
||||
this.apiWrapper.showErrorMessage(errorApplyingAclChanges(err instanceof HdfsError ? err.message : err));
|
||||
this.apiWrapper.showErrorMessage(loc.errorApplyingAclChanges(err instanceof HdfsError ? err.message : err));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const tab = azdata.window.createTab(manageAccessTitle);
|
||||
const tab = azdata.window.createTab(loc.manageAccessTitle);
|
||||
tab.registerContent(async (modelView: azdata.ModelView) => {
|
||||
this.modelBuilder = modelView.modelBuilder;
|
||||
|
||||
@@ -74,75 +76,107 @@ export class ManageAccessDialog {
|
||||
|
||||
this.rootLoadingComponent = modelView.modelBuilder.loadingComponent().withItem(rootContainer).component();
|
||||
|
||||
const pathLabel = modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: this.hdfsPath }).component();
|
||||
rootContainer.addItem(pathLabel, { flex: '0 0 auto' });
|
||||
// We nest the content inside another container for the margins - getting them on the root container isn't supported
|
||||
const contentContainer = modelView.modelBuilder.flexContainer()
|
||||
.withLayout({ flexFlow: 'column', width: '100%', height: '100%' })
|
||||
.component();
|
||||
rootContainer.addItem(contentContainer, { CSSStyles: { 'margin-left': '20px', 'margin-right': '20px' } });
|
||||
|
||||
const locationContainer = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
|
||||
|
||||
const locationLabel = modelView.modelBuilder.text()
|
||||
.withProperties<azdata.TextComponentProperties>({
|
||||
value: loc.locationTitle,
|
||||
CSSStyles: { ...cssStyles.titleCss }
|
||||
}).component();
|
||||
|
||||
const pathLabel = modelView.modelBuilder.text()
|
||||
.withProperties<azdata.TextComponentProperties>({
|
||||
value: this.hdfsPath,
|
||||
title: this.hdfsPath,
|
||||
height: locationLabelHeight,
|
||||
CSSStyles: { 'user-select': 'text', 'overflow': 'hidden', 'text-overflow': 'ellipsis', ...cssStyles.titleCss }
|
||||
}).component();
|
||||
|
||||
locationContainer.addItem(locationLabel,
|
||||
{
|
||||
flex: '0 0 auto',
|
||||
CSSStyles: { 'margin-bottom': '5px' }
|
||||
});
|
||||
locationContainer.addItem(pathLabel,
|
||||
{
|
||||
flex: '1 1 auto',
|
||||
CSSStyles: { 'border': '1px solid #ccc', 'padding': '5px', 'margin-left': '10px', 'min-height': `${locationLabelHeight}px` }
|
||||
});
|
||||
|
||||
contentContainer.addItem(locationContainer, { flex: '0 0 auto', CSSStyles: { 'margin-top': '20px' } });
|
||||
|
||||
// =====================
|
||||
// = Permissions Title =
|
||||
// =====================
|
||||
const permissionsTitle = modelView.modelBuilder.text()
|
||||
.withProperties<azdata.TextComponentProperties>({ value: permissionsHeader, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '10px' } })
|
||||
.withProperties<azdata.TextComponentProperties>({ value: loc.permissionsHeader })
|
||||
.component();
|
||||
rootContainer.addItem(permissionsTitle, { CSSStyles: { 'margin-top': '15px', 'padding-left': '10px', ...cssStyles.titleCss } });
|
||||
contentContainer.addItem(permissionsTitle, { CSSStyles: { 'margin-top': '15px', ...cssStyles.titleCss } });
|
||||
|
||||
// ==============================
|
||||
// = Owners permissions section =
|
||||
// ==============================
|
||||
|
||||
const ownersPermissionsHeaderRow = createPermissionsHeaderRow(modelView.modelBuilder, ownersHeader, true);
|
||||
rootContainer.addItem(ownersPermissionsHeaderRow, { CSSStyles: { 'padding-left': '10px', 'box-sizing': 'border-box', 'user-select': 'text' } });
|
||||
const ownersPermissionsHeaderRow = createPermissionsHeaderRow(modelView.modelBuilder, loc.ownersHeader, true);
|
||||
contentContainer.addItem(ownersPermissionsHeaderRow, { CSSStyles: { ...cssStyles.tableHeaderLayoutCss } });
|
||||
|
||||
// Empty initially - this is going to eventually be populated with the owner/owning group permissions
|
||||
this.ownersPermissionsContainer = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
|
||||
rootContainer.addItem(this.ownersPermissionsContainer);
|
||||
contentContainer.addItem(this.ownersPermissionsContainer, { flex: '0 0 auto', CSSStyles: { 'margin-bottom': '20px' } });
|
||||
|
||||
// ==============================
|
||||
// = Others permissions section =
|
||||
// ==============================
|
||||
|
||||
const othersPermissionsHeaderRow = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'row' }).component();
|
||||
const ownersHeaderCell = modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: allOthersHeader }).component();
|
||||
const ownersHeaderCell = modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.allOthersHeader }).component();
|
||||
othersPermissionsHeaderRow.addItem(ownersHeaderCell, { flex: '1 1 auto', CSSStyles: { 'width': `${permissionsNameColumnWidth}px`, 'min-width': `${permissionsNameColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
|
||||
rootContainer.addItem(othersPermissionsHeaderRow, { CSSStyles: { 'padding-left': '10px', 'box-sizing': 'border-box', 'user-select': 'text' } });
|
||||
contentContainer.addItem(othersPermissionsHeaderRow, { CSSStyles: { ...cssStyles.tableHeaderLayoutCss } });
|
||||
|
||||
// Empty initially - this is eventually going to be populated with the "Everyone" permissions
|
||||
this.othersPermissionsContainer = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
|
||||
rootContainer.addItem(this.othersPermissionsContainer);
|
||||
contentContainer.addItem(this.othersPermissionsContainer, { flex: '0 0 auto', CSSStyles: { 'margin-bottom': '20px' } });
|
||||
|
||||
// ===========================
|
||||
// = Add User Or Group Input =
|
||||
// ===========================
|
||||
|
||||
const addUserOrGroupTitle = modelView.modelBuilder.text()
|
||||
.withProperties<azdata.TextComponentProperties>({ value: addUserOrGroupHeader, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '10px' } })
|
||||
.withProperties<azdata.TextComponentProperties>({ value: loc.addUserOrGroupHeader, CSSStyles: { 'margin-block-start': '0px', 'margin-block-end': '10px' } })
|
||||
.component();
|
||||
rootContainer.addItem(addUserOrGroupTitle, { CSSStyles: { 'margin-top': '15px', 'padding-left': '10px', ...cssStyles.titleCss } });
|
||||
contentContainer.addItem(addUserOrGroupTitle, { CSSStyles: { 'margin-top': '15px', ...cssStyles.titleCss } });
|
||||
|
||||
const typeContainer = modelView.modelBuilder.flexContainer().withProperties({ flexFlow: 'row' }).component();
|
||||
const aclEntryTypeGroup = 'aclEntryType';
|
||||
const userTypeButton = this.createRadioButton(modelView.modelBuilder, userLabel, aclEntryTypeGroup, AclEntryType.user);
|
||||
const groupTypeButton = this.createRadioButton(modelView.modelBuilder, groupLabel, aclEntryTypeGroup, AclEntryType.group);
|
||||
const userTypeButton = this.createRadioButton(modelView.modelBuilder, loc.userLabel, aclEntryTypeGroup, AclEntryType.user);
|
||||
const groupTypeButton = this.createRadioButton(modelView.modelBuilder, loc.groupLabel, aclEntryTypeGroup, AclEntryType.group);
|
||||
userTypeButton.checked = true;
|
||||
this.addUserOrGroupSelectedType = AclEntryType.user;
|
||||
|
||||
typeContainer.addItems([userTypeButton, groupTypeButton], { flex: '0 0 auto' });
|
||||
rootContainer.addItem(typeContainer, { flex: '0 0 auto' });
|
||||
contentContainer.addItem(typeContainer, { flex: '0 0 auto' });
|
||||
const addUserOrGroupInputRow = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'row' }).component();
|
||||
|
||||
this.addUserOrGroupInput = modelView.modelBuilder.inputBox()
|
||||
.withProperties<azdata.InputBoxProperties>(
|
||||
{
|
||||
inputType: 'text',
|
||||
placeHolder: enterNamePlaceholder,
|
||||
width: 250,
|
||||
stopEnterPropagation: true
|
||||
}).component();
|
||||
.withProperties<azdata.InputBoxProperties>({
|
||||
inputType: 'text',
|
||||
placeHolder: loc.enterNamePlaceholder,
|
||||
width: 250,
|
||||
stopEnterPropagation: true
|
||||
})
|
||||
.component();
|
||||
this.addUserOrGroupInput.onEnterKeyPressed((value: string) => {
|
||||
this.hdfsModel.createAndAddAclEntry(value, this.addUserOrGroupSelectedType);
|
||||
this.addUserOrGroupInput.value = '';
|
||||
});
|
||||
const addUserOrGroupButton = modelView.modelBuilder.button().withProperties<azdata.ButtonProperties>({ label: addLabel, width: 75 }).component();
|
||||
const addUserOrGroupButton = modelView.modelBuilder.button().withProperties<azdata.ButtonProperties>({ label: loc.addLabel, width: 75 }).component();
|
||||
addUserOrGroupButton.onDidClick(() => {
|
||||
this.hdfsModel.createAndAddAclEntry(this.addUserOrGroupInput.value, this.addUserOrGroupSelectedType);
|
||||
this.addUserOrGroupInput.value = '';
|
||||
@@ -155,21 +189,24 @@ export class ManageAccessDialog {
|
||||
addUserOrGroupButton.enabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
addUserOrGroupInputRow.addItem(this.addUserOrGroupInput, { flex: '0 0 auto' });
|
||||
addUserOrGroupInputRow.addItem(addUserOrGroupButton, { flex: '0 0 auto', CSSStyles: { 'margin-left': '20px' } });
|
||||
|
||||
rootContainer.addItem(addUserOrGroupInputRow);
|
||||
contentContainer.addItem(addUserOrGroupInputRow, { flex: '0 0 auto', CSSStyles: { 'margin-bottom': '20px' } });
|
||||
|
||||
// =================================================
|
||||
// = Named Users and Groups permissions header row =
|
||||
// =================================================
|
||||
|
||||
const namedUsersAndGroupsPermissionsHeaderRow = createPermissionsHeaderRow(modelView.modelBuilder, ownersHeader, false);
|
||||
rootContainer.addItem(namedUsersAndGroupsPermissionsHeaderRow, { CSSStyles: { 'padding-left': '10px', 'box-sizing': 'border-box', 'user-select': 'text' } });
|
||||
const namedUsersAndGroupsPermissionsHeaderRow = createPermissionsHeaderRow(modelView.modelBuilder, loc.namedUsersAndGroupsHeader, false);
|
||||
contentContainer.addItem(namedUsersAndGroupsPermissionsHeaderRow, { CSSStyles: { ...cssStyles.tableHeaderLayoutCss } });
|
||||
|
||||
// Empty initially - this is eventually going to be populated with the ACL entries set for this path
|
||||
this.namedUsersAndGroupsPermissionsContainer = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
|
||||
rootContainer.addItem(this.namedUsersAndGroupsPermissionsContainer);
|
||||
this.namedUsersAndGroupsPermissionsContainer = modelView.modelBuilder.flexContainer()
|
||||
.withLayout({ flexFlow: 'column' })
|
||||
.component();
|
||||
contentContainer.addItem(this.namedUsersAndGroupsPermissionsContainer, { flex: '1', CSSStyles: { 'overflow': 'scroll', 'min-height': '200px' } });
|
||||
|
||||
this.viewInitialized = true;
|
||||
this.handleAclStatusUpdated(this.hdfsModel.aclStatus);
|
||||
@@ -190,18 +227,18 @@ export class ManageAccessDialog {
|
||||
const ownerPermissionsRow = this.createOwnerPermissionsRow(this.modelBuilder, aclStatus.stickyBit, aclStatus.owner);
|
||||
const owningGroupPermissionsRow = this.createPermissionsRow(this.modelBuilder, aclStatus.group, false);
|
||||
this.ownersPermissionsContainer.clearItems();
|
||||
this.ownersPermissionsContainer.addItems([ownerPermissionsRow, owningGroupPermissionsRow], { CSSStyles: { 'border-bottom': cssStyles.tableBorder, 'border-top': cssStyles.tableBorder } });
|
||||
this.ownersPermissionsContainer.addItems([ownerPermissionsRow, owningGroupPermissionsRow], { CSSStyles: { 'border-bottom': cssStyles.tableBorderCss, 'border-top': cssStyles.tableBorderCss, 'margin-right': '14px' } });
|
||||
|
||||
// Others
|
||||
const otherPermissionsRow = this.createPermissionsRow(this.modelBuilder, aclStatus.other, false);
|
||||
this.othersPermissionsContainer.clearItems();
|
||||
this.othersPermissionsContainer.addItem(otherPermissionsRow, { CSSStyles: { 'border-bottom': cssStyles.tableBorder, 'border-top': cssStyles.tableBorder } });
|
||||
this.othersPermissionsContainer.addItem(otherPermissionsRow, { CSSStyles: { 'border-bottom': cssStyles.tableBorderCss, 'border-top': cssStyles.tableBorderCss, 'margin-right': '14px' } });
|
||||
|
||||
this.namedUsersAndGroupsPermissionsContainer.clearItems();
|
||||
// Named users and groups
|
||||
aclStatus.entries.forEach(entry => {
|
||||
const namedEntryRow = this.createPermissionsRow(this.modelBuilder, entry, true);
|
||||
this.namedUsersAndGroupsPermissionsContainer.addItem(namedEntryRow, { CSSStyles: { 'border-bottom': cssStyles.tableBorder, 'border-top': cssStyles.tableBorder } });
|
||||
this.namedUsersAndGroupsPermissionsContainer.addItem(namedEntryRow, { CSSStyles: { 'border-bottom': cssStyles.tableBorderCss, 'border-top': cssStyles.tableBorderCss } });
|
||||
});
|
||||
|
||||
this.rootLoadingComponent.loading = false;
|
||||
@@ -217,10 +254,9 @@ export class ManageAccessDialog {
|
||||
|
||||
private createOwnerPermissionsRow(builder: azdata.ModelBuilder, sticky: boolean, entry: AclEntry): azdata.FlexContainer {
|
||||
const row = this.createPermissionsRow(builder, entry, false);
|
||||
const stickyCheckbox = builder.checkBox().withProperties({ checked: sticky, height: 25, width: 25 }).component();
|
||||
const stickyContainer = builder.flexContainer().withLayout({ width: permissionsReadColumnWidth }).withItems([stickyCheckbox]).component();
|
||||
const stickyComponents = createCheckbox(builder, sticky, permissionsReadColumnWidth, permissionsRowHeight);
|
||||
// Insert after name item but before other checkboxes
|
||||
row.insertItem(stickyContainer, 1, { flex: '0 0 auto' });
|
||||
row.insertItem(stickyComponents.container, 1, { flex: '0 0 auto' });
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -245,7 +281,7 @@ export class ManageAccessDialog {
|
||||
|
||||
// Access - Execute
|
||||
const accessExecuteComponents = createCheckbox(builder, entry.permission.execute, permissionsExecuteColumnWidth, permissionsRowHeight);
|
||||
rowContainer.addItem(accessExecuteComponents.container, { flex: '0 0 auto', CSSStyles: { 'border-right': cssStyles.tableBorder } });
|
||||
rowContainer.addItem(accessExecuteComponents.container, { flex: '0 0 auto', CSSStyles: { 'border-right': cssStyles.tableBorderCss } });
|
||||
accessExecuteComponents.checkbox.onChanged(() => {
|
||||
entry.permission.execute = accessExecuteComponents.checkbox.checked;
|
||||
});
|
||||
@@ -271,14 +307,23 @@ export class ManageAccessDialog {
|
||||
// entry.permission.execute = accessReadComponents.checkbox.checked; TODO hook up default logic
|
||||
});
|
||||
|
||||
const deleteContainer = builder.flexContainer().withLayout({ width: permissionsDeleteColumnWidth }).component();
|
||||
const deleteContainer = builder.flexContainer().withLayout({ width: permissionsDeleteColumnWidth, height: permissionsRowHeight }).component();
|
||||
|
||||
if (includeDelete) {
|
||||
const deleteButton = builder.button().withProperties<azdata.ButtonProperties>({ label: 'Delete' }).component();
|
||||
const deleteButton = builder.button()
|
||||
.withProperties<azdata.ButtonProperties>(
|
||||
{
|
||||
label: '',
|
||||
title: loc.deleteTitle,
|
||||
iconPath: IconPathHelper.delete,
|
||||
width: 20,
|
||||
height: 20
|
||||
})
|
||||
.component();
|
||||
deleteButton.onDidClick(() => { this.hdfsModel.deleteAclEntry(entry); });
|
||||
deleteContainer.addItem(deleteButton, { flex: '0 0 auto' });
|
||||
deleteContainer.addItem(deleteButton);
|
||||
}
|
||||
rowContainer.addItem(deleteContainer, { flex: '0 0 auto' });
|
||||
rowContainer.addItem(deleteContainer, { flex: '0 0 auto', CSSStyles: { 'margin-top': '5px', 'margin-left': '5px' } });
|
||||
|
||||
return rowContainer;
|
||||
}
|
||||
@@ -296,10 +341,13 @@ function createPermissionsHeaderRow(modelBuilder: azdata.ModelBuilder, nameColum
|
||||
|
||||
// Section Headers
|
||||
const sectionHeaderContainer = modelBuilder.flexContainer().withLayout({ flexFlow: 'row', justifyContent: 'flex-end' }).component();
|
||||
const accessSectionHeader = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: accessHeader }).component();
|
||||
sectionHeaderContainer.addItem(accessSectionHeader, { CSSStyles: { 'width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const defaultSectionHeader = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: defaultHeader }).component();
|
||||
sectionHeaderContainer.addItem(defaultSectionHeader, { CSSStyles: { 'width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const accessSectionHeader = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.accessHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
sectionHeaderContainer.addItem(accessSectionHeader, { CSSStyles: { 'width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px` } });
|
||||
const defaultSectionHeader = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.defaultHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
sectionHeaderContainer.addItem(defaultSectionHeader, { CSSStyles: { 'width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth + permissionsWriteColumnWidth + permissionsExecuteColumnWidth}px` } });
|
||||
// Delete - just used as a spacer
|
||||
const deleteSectionHeader = modelBuilder.text().component();
|
||||
sectionHeaderContainer.addItem(deleteSectionHeader, { CSSStyles: { 'width': `${permissionsDeleteColumnWidth}px`, 'min-width': `${permissionsDeleteColumnWidth}px` } });
|
||||
|
||||
rowsContainer.addItem(sectionHeaderContainer);
|
||||
|
||||
@@ -308,24 +356,24 @@ function createPermissionsHeaderRow(modelBuilder: azdata.ModelBuilder, nameColum
|
||||
const ownersCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: nameColumnText }).component();
|
||||
headerRowContainer.addItem(ownersCell, { flex: '1 1 auto', CSSStyles: { 'width': `${permissionsNameColumnWidth}px`, 'min-width': `${permissionsNameColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
if (includeSticky) {
|
||||
const stickyCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: stickyHeader }).component();
|
||||
headerRowContainer.addItem(stickyCell, { CSSStyles: { 'width': `${permissionsStickyColumnWidth}px`, 'min-width': `${permissionsStickyColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const stickyCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.stickyHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(stickyCell, { CSSStyles: { 'width': `${permissionsStickyColumnWidth}px`, 'min-width': `${permissionsStickyColumnWidth}px` } });
|
||||
}
|
||||
|
||||
// Access Permissions Group
|
||||
const accessReadCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: readHeader }).component();
|
||||
headerRowContainer.addItem(accessReadCell, { CSSStyles: { 'width': `${permissionsReadColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const accessWriteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: writeHeader }).component();
|
||||
headerRowContainer.addItem(accessWriteCell, { CSSStyles: { 'width': `${permissionsWriteColumnWidth}px`, 'min-width': `${permissionsWriteColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const accessExecuteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: executeHeader }).component();
|
||||
headerRowContainer.addItem(accessExecuteCell, { CSSStyles: { 'width': `${permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsExecuteColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const accessReadCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.readHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(accessReadCell, { CSSStyles: { 'width': `${permissionsReadColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth}px` } });
|
||||
const accessWriteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.writeHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(accessWriteCell, { CSSStyles: { 'width': `${permissionsWriteColumnWidth}px`, 'min-width': `${permissionsWriteColumnWidth}px` } });
|
||||
const accessExecuteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.executeHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(accessExecuteCell, { CSSStyles: { 'width': `${permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsExecuteColumnWidth}px`, 'margin-right': '5px' } });
|
||||
// Default Permissions Group
|
||||
const defaultReadCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: readHeader }).component();
|
||||
headerRowContainer.addItem(defaultReadCell, { CSSStyles: { 'width': `${permissionsReadColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const defaultWriteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: writeHeader }).component();
|
||||
headerRowContainer.addItem(defaultWriteCell, { CSSStyles: { 'width': `${permissionsWriteColumnWidth}px`, 'min-width': `${permissionsWriteColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const defaultExecuteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: executeHeader }).component();
|
||||
headerRowContainer.addItem(defaultExecuteCell, { CSSStyles: { 'width': `${permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsExecuteColumnWidth}px`, ...cssStyles.tableHeaderCss } });
|
||||
const defaultReadCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.readHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(defaultReadCell, { CSSStyles: { 'width': `${permissionsReadColumnWidth}px`, 'min-width': `${permissionsReadColumnWidth}px` } });
|
||||
const defaultWriteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.writeHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(defaultWriteCell, { CSSStyles: { 'width': `${permissionsWriteColumnWidth}px`, 'min-width': `${permissionsWriteColumnWidth}px` } });
|
||||
const defaultExecuteCell = modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: loc.executeHeader, CSSStyles: { ...cssStyles.permissionsTableHeaderCss } }).component();
|
||||
headerRowContainer.addItem(defaultExecuteCell, { CSSStyles: { 'width': `${permissionsExecuteColumnWidth}px`, 'min-width': `${permissionsExecuteColumnWidth}px` } });
|
||||
// Delete
|
||||
const deleteCell = modelBuilder.text().component();
|
||||
headerRowContainer.addItem(deleteCell, { CSSStyles: { 'width': `${permissionsDeleteColumnWidth}px`, 'min-width': `${permissionsDeleteColumnWidth}px` } });
|
||||
@@ -336,12 +384,15 @@ function createPermissionsHeaderRow(modelBuilder: azdata.ModelBuilder, nameColum
|
||||
}
|
||||
|
||||
function createCheckbox(builder: azdata.ModelBuilder, checked: boolean, containerWidth: number, containerHeight: number): { container: azdata.FlexContainer, checkbox: azdata.CheckBoxComponent } {
|
||||
const checkbox = builder.checkBox().withProperties({ checked: checked, height: 25, width: 25 }).component();
|
||||
const checkbox = builder.checkBox()
|
||||
.withProperties<azdata.CheckBoxProperties>({ checked: checked, height: 20, width: 20 }).component();
|
||||
const container = builder.flexContainer()
|
||||
.withLayout({ width: containerWidth, height: containerHeight })
|
||||
//.withItems([checkbox], { CSSStyles: { ...cssStyles.permissionCheckboxCss }})
|
||||
.component();
|
||||
container.addItem(checkbox, { CSSStyles: { ...cssStyles.permissionCheckboxCss } });
|
||||
return {
|
||||
container: builder.flexContainer()
|
||||
.withLayout({ width: containerWidth, height: containerHeight })
|
||||
.withItems([checkbox])
|
||||
.component(),
|
||||
container: container,
|
||||
checkbox: checkbox
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export namespace cssStyles {
|
||||
export const tableBorder = '1px solid #ccc';
|
||||
export const titleCss = { 'font-size': '20px', 'font-weight': '600' };
|
||||
export const tableBorderCss = '1px solid #ccc';
|
||||
export const titleCss = { 'font-size': '20px', 'font-weight': '600', 'margin-block-end': '0px', 'margin-block-start': '0px' };
|
||||
export const tableHeaderCss = { 'font-weight': 'bold', 'text-transform': 'uppercase', 'font-size': '10px', 'user-select': 'text' };
|
||||
export const permissionsTableHeaderCss = { ...tableHeaderCss, 'text-align': 'center' };
|
||||
export const permissionCheckboxCss = { 'margin-top': '5px', 'margin-left': '13px' };
|
||||
// The Named users/groups section potentially has a scrollbar so we shift all the other parts over so the columns still align correctly
|
||||
export const scrollbarMarginGapCss = { 'margin-right': '17px' };
|
||||
export const tableHeaderLayoutCss = { 'padding-left': '10px', 'box-sizing': 'border-box', 'user-select': 'text', ...cssStyles.scrollbarMarginGapCss };
|
||||
}
|
||||
|
||||
25
extensions/mssql/src/iconHelper.ts
Normal file
25
extensions/mssql/src/iconHelper.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export interface IconPath {
|
||||
dark: string;
|
||||
light: string;
|
||||
}
|
||||
|
||||
export class IconPathHelper {
|
||||
private static extensionContext: vscode.ExtensionContext;
|
||||
|
||||
public static delete: IconPath;
|
||||
|
||||
public static setExtensionContext(extensionContext: vscode.ExtensionContext) {
|
||||
IconPathHelper.extensionContext = extensionContext;
|
||||
IconPathHelper.delete = {
|
||||
dark: IconPathHelper.extensionContext.asAbsolutePath('resources/dark/delete_inverse.svg'),
|
||||
light: IconPathHelper.extensionContext.asAbsolutePath('resources/light/delete.svg')
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ export const msgMissingNodeContext = localize('msgMissingNodeContext', 'Node Com
|
||||
// HDFS Manage Access Dialog Constants ////////////////////////////////////
|
||||
|
||||
export const manageAccessTitle = localize('mssql.manageAccessTitle', "Manage Access");
|
||||
export const locationTitle = localize('mssql.locationTitle', "Location : ");
|
||||
export const permissionsHeader = localize('mssql.permissionsTitle', "Permissions");
|
||||
export const ownersHeader = localize('mssql.ownersHeader', "Owners");
|
||||
export const allOthersHeader = localize('mssql.allOthersHeader', "All Others");
|
||||
@@ -20,6 +21,7 @@ export const userLabel = localize('mssql.userLabel', "User");
|
||||
export const groupLabel = localize('mssql.groupLabel', "Group");
|
||||
export const accessHeader = localize('mssql.accessHeader', "Access");
|
||||
export const defaultHeader = localize('mssql.defaultHeader', "Default");
|
||||
export const deleteTitle = localize('mssql.delete', "Delete");
|
||||
export const stickyHeader = localize('mssql.stickyHeader', "Sticky");
|
||||
export const readHeader = localize('mssql.readHeader', "Read");
|
||||
export const writeHeader = localize('mssql.writeHeader', "Write");
|
||||
|
||||
@@ -29,6 +29,7 @@ import { createMssqlApi } from './mssqlApiFactory';
|
||||
import { localize } from './localize';
|
||||
import { SqlToolsServer } from './sqlToolsServer';
|
||||
import { promises as fs } from 'fs';
|
||||
import { IconPathHelper } from './iconHelper';
|
||||
|
||||
const msgSampleCodeDataFrame = localize('msgSampleCodeDataFrame', 'This sample code loads the file into a data frame and shows the first 10 results.');
|
||||
|
||||
@@ -47,6 +48,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<IExten
|
||||
await fs.mkdir(context.logPath);
|
||||
}
|
||||
|
||||
IconPathHelper.setExtensionContext(context);
|
||||
|
||||
let prompter: IPrompter = new CodeAdapter();
|
||||
let appContext = new AppContext(context, new ApiWrapper());
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ export default class ButtonComponent extends ComponentWithIconBase implements IC
|
||||
this._button.setWidth(this.convertSize(this.width.toString()));
|
||||
}
|
||||
if (this.height) {
|
||||
this._button.setWidth(this.convertSize(this.height.toString()));
|
||||
this._button.setHeight(this.convertSize(this.height.toString()));
|
||||
}
|
||||
this.updateIcon();
|
||||
this._changeRef.detectChanges();
|
||||
|
||||
Reference in New Issue
Block a user