mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-18 17:22:45 -05:00
* fixes button alignment and missing icons issues with ads welcome page * removes dead code, registers new Button * creates one button component and adds proper attributes depending on platform * Add CodeQL Analysis workflow (#10195) * Add CodeQL Analysis workflow * Fix path * adds return types to functions * fixes show all extensions command * formats css * fixes layering issue * updates querySelectors to be more specific Co-authored-by: Justin Hutchings <jhutchings1@users.noreply.github.com>
This commit is contained in:
BIN
src/sql/workbench/contrib/welcome/media/icon_postgre_sql.png
Normal file
BIN
src/sql/workbench/contrib/welcome/media/icon_postgre_sql.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
src/sql/workbench/contrib/welcome/media/icon_powershell.png
Normal file
BIN
src/sql/workbench/contrib/welcome/media/icon_powershell.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
@@ -11,7 +11,7 @@ export default () => `
|
||||
<div class="welcomePage">
|
||||
<div class="ads-homepage splash">
|
||||
<div class="gradient">
|
||||
<div class="preview-text tool-tip">
|
||||
<div class="ads-homepage-section tool-tip">
|
||||
<div class="tool-tip-container" id="tool-tip-container-wide">
|
||||
<a class="ads-welcome-page-link" aria-describedby="tooltip-text-wide" id="preview-link-wide" class="preview-link" tabindex="0" name="preview"><p>Preview</p><i class="icon-info themed-icon"></i></a>
|
||||
<span role="tooltip" id="tooltip-text-wide" class="tool-tip-text" aria-hidden="true">
|
||||
@@ -40,27 +40,10 @@ export default () => `
|
||||
<span class="icon xs"></span><h1 class="caption"></h1>
|
||||
</div>
|
||||
<div class="flex btn-container">
|
||||
<div>
|
||||
<button id="dropdown-btn" class="btn btn-primary dropdown" role="navigation" aria-haspopup="true" aria-controls="dropdown">
|
||||
<div class="dropdown-text" style="pointer-events: none;">
|
||||
<span>${escape(localize('welcomePage.new', "New"))}</span><i class="icon-arrow-down"></i>
|
||||
</div>
|
||||
</button>
|
||||
<nav role="navigation" class="dropdown-nav">
|
||||
<ul id="dropdown" class="dropdown-content" aria-hidden="true" aria-label="submenu" role="menu" aria-labelledby="dropdown-btn">
|
||||
<li role="none"><a class="ads-welcome-page-link" role="menuitem" tabIndex="-1" class="move" href="command:registeredServers.addConnection">${escape(localize('welcomePage.newConnection', "New connection"))}</a></li>
|
||||
<li role="none"><a class="ads-welcome-page-link" role="menuitem" tabIndex="-1" class="move" href="command:workbench.action.files.newUntitledFile">${escape(localize('welcomePage.newQuery', "New query"))}</a></li>
|
||||
<li role="none"><a class="ads-welcome-page-link" role="menuitem" tabIndex="-1" class="move" href="command:notebook.command.new">${escape(localize('welcomePage.newNotebook', "New notebook"))}</a></li>
|
||||
<li role="none" id="dropdown-mac-only"><a class="ads-welcome-page-link" role="menuitem" tabIndex="-1" class="move mac-only" href="command:workbench.action.files.openLocalFileFolder">${escape(localize('welcomePage.openFileMac', "Open file"))}</a></li>
|
||||
<li role="none" id="dropdown-windows-linux-only"><a class="ads-welcome-page-link" role="menuitem" tabIndex="-1" class="move windows-only linux-only" href="command:workbench.action.files.openFile">${escape(localize('welcomePage.openFileLinuxPC', "Open file"))}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div id="dropdown-btn-container" class="btn btn-primary dropdown">
|
||||
</div>
|
||||
<div id="open-file-btn-container" class="btn btn-secondary">
|
||||
</div>
|
||||
<a class="windows-only linux-only btn btn-secondary"
|
||||
href="command:workbench.action.files.openFile">
|
||||
${escape(localize('welcomePage.openFileLinuxPC', "Open file"))}
|
||||
</a>
|
||||
<a class="mac-only btn btn-secondary" href="command:workbench.action.files.openLocalFileFolder">${escape(localize('welcomePage.openFileMac', "Open file"))}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -158,8 +141,6 @@ export default () => `
|
||||
<p>${escape(localize('welcomePage.documentationBody',
|
||||
"Visit the documentation center for quickstarts, how-to guides, and references for PowerShell, APIs, etc."))}
|
||||
</p>
|
||||
|
||||
|
||||
<div class="videos-container row">
|
||||
<h2>Videos</h2>
|
||||
<div class="flex flex-container-video">
|
||||
@@ -169,7 +150,6 @@ export default () => `
|
||||
<h4>${escape(localize('welcomePage.videoDescriptionOverview',
|
||||
"Overview of Azure Data Studio"))}</h4>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<div class="videos-container-video">
|
||||
<a href="https://www.youtube.com/watch?v=Nt4kIHQ0IOc" class="video overview ads-welcome-page-link">
|
||||
@@ -186,7 +166,7 @@ export default () => `
|
||||
<div class="ads-homepage-section content extensions">
|
||||
<div class="flex flex-j-between">
|
||||
<h2>Extend your data studio</h2>
|
||||
<a class="link-show-all flex ads-welcome-page-link" href="command:extensions.listView.focus">${escape(localize('welcomePage.showAll', "Show All"))} <span class="icon-arrow-right"></span></a>
|
||||
<a class="link-show-all flex" href="command:workbench.view.extensions">${escape(localize('welcomePage.showAll', "Show All"))} <span class="icon-arrow-right"></span></a>
|
||||
</div>
|
||||
<div class="row ads-grid grip-gap-50">
|
||||
<div
|
||||
|
||||
@@ -144,43 +144,6 @@
|
||||
justify-content: flex-start
|
||||
}
|
||||
|
||||
.ads-homepage.XS:not(.SM) .btn-container div {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ads-homepage.XS:not(.SM) .btn {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
padding-top: 1px;
|
||||
font-size: 1.08em;
|
||||
line-height: 29px;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
margin: 10px 0
|
||||
}
|
||||
|
||||
.ads-homepage.SM .btn {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
padding-top: 1px;
|
||||
font-size: 1.08em;
|
||||
line-height: 29px;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
margin: 10px 0
|
||||
}
|
||||
|
||||
.ads-homepage .btn span {
|
||||
display: block
|
||||
}
|
||||
@@ -192,7 +155,6 @@
|
||||
.ads-homepage.XS .btn {
|
||||
margin: 0 8px 0 0;
|
||||
width: 77px;
|
||||
height: 25px;
|
||||
line-height: 18px
|
||||
}
|
||||
|
||||
@@ -304,7 +266,17 @@
|
||||
}
|
||||
|
||||
.ads-homepage #tool-tip-container-wide {
|
||||
display: none
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ads-homepage #tool-tip-container-wide .ads-welcome-page-link{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ads-homepage #tool-tip-container-narrow .ads-welcome-page-link{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ads-homepage #tool-tip-container-narrow {
|
||||
@@ -319,7 +291,9 @@
|
||||
}
|
||||
|
||||
.ads-homepage.XL #tool-tip-container-wide {
|
||||
display: block
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.ads-homepage.XL #tool-tip-container-narrow {
|
||||
@@ -331,6 +305,7 @@
|
||||
visibility: hidden;
|
||||
padding: 10px 15px;
|
||||
z-index: 1;
|
||||
top: 32px;
|
||||
right: -72px;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
@@ -420,6 +395,7 @@
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-left: 6px;
|
||||
margin-top: 3px;
|
||||
-webkit-mask: url(../../media/info.svg) no-repeat;
|
||||
-webkit-mask-size: 12px 12px;
|
||||
mask: url(../../media/info.svg) no-repeat;
|
||||
@@ -450,6 +426,11 @@
|
||||
margin: auto
|
||||
}
|
||||
|
||||
.ads-homepage .codicon-chevron-right {
|
||||
transform: rotate(90deg);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ads-homepage .icon-arrow-right {
|
||||
position: relative;
|
||||
height: 16px;
|
||||
@@ -484,7 +465,6 @@
|
||||
mask: url(../../media/link_icon.svg) no-repeat;
|
||||
mask-size: 11px 11px;
|
||||
height: 11px;
|
||||
width: 11px
|
||||
}
|
||||
|
||||
.ads-homepage .icon-arrow-down-dark {
|
||||
@@ -504,7 +484,6 @@
|
||||
display: inline-block;
|
||||
width: 11px;
|
||||
height: 6px;
|
||||
content: "";
|
||||
transform: rotate(90deg);
|
||||
top: 14px;
|
||||
bottom: 5px;
|
||||
@@ -555,6 +534,14 @@
|
||||
grid-template-columns: repeat(2, 1fr)
|
||||
}
|
||||
|
||||
.ads_homepage .dropdown_btn_container {
|
||||
margin: 10px 10px 10px 0;
|
||||
}
|
||||
|
||||
.ads_homepage.XS:not(.SM) .dropdown_btn_container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ads-homepage.XS.SM.MD.LG.XL .extension-pack-container {
|
||||
grid-template-columns: repeat(8, 1fr)
|
||||
}
|
||||
@@ -574,12 +561,12 @@
|
||||
|
||||
.ads-homepage .tile:not(.extension):not(.extension-pack) {
|
||||
border: 1px solid;
|
||||
border-radius: 4px
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ads-homepage .tile.extension-pack {
|
||||
border: 1px solid;
|
||||
border-radius: 4px
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ads-homepage .extension-list {
|
||||
@@ -588,17 +575,17 @@
|
||||
|
||||
.ads-homepage.XS.SM.MD.LG.XL .extension-list {
|
||||
grid-column: 5/span 4;
|
||||
grid-row: 1/span 4
|
||||
grid-row: 1/span 4;
|
||||
}
|
||||
|
||||
.ads-homepage .extension-header, .ads-homepage .extension-pack-extension-list-header {
|
||||
font-weight: 600;
|
||||
font-size: 1.33em
|
||||
font-size: 1.33em;
|
||||
}
|
||||
|
||||
.ads-homepage .tile {
|
||||
transition: all .5s ease;
|
||||
border-radius: 4px
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ads-homepage .tile:hover:not(.no-hover) {
|
||||
@@ -1342,7 +1329,7 @@
|
||||
font-size: 1.16em;
|
||||
font-family: Segoe UI, Frutiger, Frutiger Linotype, Dejavu Sans, Helvetica Neue, Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
padding: 10px 0 10px;
|
||||
padding: 10px 15px 10px 0;
|
||||
}
|
||||
|
||||
.ads-homepage .guided-tour-banner b {
|
||||
|
||||
@@ -45,13 +45,12 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { addStandardDisposableListener, EventHelper } from 'vs/base/browser/dom';
|
||||
import { GuidedTour } from 'sql/workbench/contrib/welcome/page/browser/gettingStartedTour';
|
||||
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
const configurationKey = 'workbench.startupEditor';
|
||||
const oldConfigurationKey = 'workbench.welcome.enabled';
|
||||
const telemetryFrom = 'welcomePage';
|
||||
@@ -137,6 +136,7 @@ function isGuidedTourEnabled(configurationService: IConfigurationService): boole
|
||||
|
||||
export class WelcomePageAction extends Action {
|
||||
|
||||
|
||||
public static readonly ID = 'workbench.action.showWelcomePage';
|
||||
public static readonly LABEL = localize('welcomePage', "Welcome");
|
||||
|
||||
@@ -191,9 +191,9 @@ const extensionPackExtensions: ExtensionPackExtensions[] = [
|
||||
];
|
||||
|
||||
const extensions: ExtensionSuggestion[] = [
|
||||
{ name: localize('welcomePage.powershell', "Powershell"), id: 'microsoft.powershell', description: localize('welcomePage.powershellDescription', "Write and execute PowerShell scripts using Azure Data Studio's rich query editor"), icon: 'https://raw.githubusercontent.com/PowerShell/vscode-powershell/master/images/PowerShell_icon.png', link: `command:azdata.extension.open?{"id":"microsoft.powershell"}` },
|
||||
{ name: localize('welcomePage.powershell', "Powershell"), id: 'microsoft.powershell', description: localize('welcomePage.powershellDescription', "Write and execute PowerShell scripts using Azure Data Studio's rich query editor"), icon: require.toUrl('./../../media/icon_powershell.png'), link: `command:azdata.extension.open?{"id":"microsoft.powershell"}` },
|
||||
{ name: localize('welcomePage.dataVirtualization', "Data Virtualization"), id: 'microsoft.datavirtualization', description: localize('welcomePage.dataVirtualizationDescription', "Virtualize data with SQL Server 2019 and create external tables using interactive wizards"), icon: require.toUrl('./../../media/defaultExtensionIcon.svg'), link: `command:azdata.extension.open?{"id":"microsoft.datavirtualization"}` },
|
||||
{ name: localize('welcomePage.PostgreSQL', "PostgreSQL"), id: 'microsoft.azuredatastudio-postgresql', description: localize('welcomePage.PostgreSQLDescription', "Connect, query, and manage Postgres databases with Azure Data Studio"), icon: 'https://raw.githubusercontent.com/Microsoft/azuredatastudio-postgresql/master/images/extension-icon.png', link: `command:azdata.extension.open?{"id":"microsoft.azuredatastudio-postgresql"}` },
|
||||
{ name: localize('welcomePage.PostgreSQL', "PostgreSQL"), id: 'microsoft.azuredatastudio-postgresql', description: localize('welcomePage.PostgreSQLDescription', "Connect, query, and manage Postgres databases with Azure Data Studio"), icon: require.toUrl('./../../media/icon_postgre_sql.png'), link: `command:azdata.extension.open?{"id":"microsoft.azuredatastudio-postgresql"}` },
|
||||
];
|
||||
|
||||
const extensionPackStrings = {
|
||||
@@ -228,7 +228,9 @@ class WelcomePage extends Disposable {
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IFileService fileService: IFileService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IWorkbenchLayoutService protected layoutService: IWorkbenchLayoutService) {
|
||||
@IWorkbenchLayoutService protected layoutService: IWorkbenchLayoutService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
) {
|
||||
super();
|
||||
this._register(lifecycleService.onShutdown(() => this.dispose()));
|
||||
const recentlyOpened = this.workspacesService.getRecentlyOpened();
|
||||
@@ -317,7 +319,7 @@ class WelcomePage extends Disposable {
|
||||
while (ul.firstChild) {
|
||||
ul.removeChild(ul.firstChild);
|
||||
}
|
||||
await this.mapListEntries(workspacesToShow, fileService);
|
||||
await this.mapListEntries(workspacesToShow, fileService, container);
|
||||
};
|
||||
await updateEntries();
|
||||
this._register(this.labelService.onDidChangeFormatters(updateEntries));
|
||||
@@ -334,11 +336,76 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
}
|
||||
}));
|
||||
this.createButtons();
|
||||
this.createDropDown();
|
||||
this.createWidePreviewToolTip();
|
||||
this.createPreviewModal();
|
||||
}
|
||||
|
||||
private createButtons(): void {
|
||||
const container = document.querySelector('.ads-homepage .hero');
|
||||
const dropdownButtonContainer = document.querySelector('#dropdown-btn-container') as HTMLElement;
|
||||
const dropdownUl = document.createElement('ul');
|
||||
const i = document.createElement('div');
|
||||
const nav = document.createElement('nav');
|
||||
const newText = localize('welcomePage.new', "New");
|
||||
let dropdownBtn = this._register(new Button(dropdownButtonContainer));
|
||||
dropdownBtn.label = newText;
|
||||
|
||||
const iconClassList = ['twisties', 'codicon', 'codicon-chevron-right'];
|
||||
|
||||
i.classList.add(...iconClassList);
|
||||
const openFileCopy = localize('welcomePage.openFile', "Open file");
|
||||
dropdownUl.classList.add('dropdown-content');
|
||||
dropdownUl.setAttribute('aria-hidden', 'true');
|
||||
dropdownUl.setAttribute('aria-label', 'submenu');
|
||||
dropdownUl.setAttribute('role', 'menu');
|
||||
dropdownUl.setAttribute('aria-labelledby', 'dropdown-btn');
|
||||
dropdownUl.id = 'dropdown';
|
||||
dropdownUl.innerHTML =
|
||||
`<li role="none"><a role="menuitem" tabIndex="-1" class="move" href="command:registeredServers.addConnection">${(localize('welcomePage.newConnection', "New connection"))} </a></li>
|
||||
<li role="none"><a role="menuitem" tabIndex="-1" class="move" href="command:workbench.action.files.newUntitledFile">${(localize('welcomePage.newQuery', "New query"))}</a></li>
|
||||
<li role="none"><a role="menuitem" tabIndex="-1" class="move" href="command:notebook.command.new">${(localize('welcomePage.newNotebook', "New notebook"))}</a></li>
|
||||
<li role="none"><a role="menuitem" tabIndex="-1" class="move" href="command:azdata.resource.deploy">${(localize('welcomePage.deployServer', "Deploy a Server"))}</a></li>
|
||||
<li role="none" id="dropdown-mac-only"><a role="menuitem" tabIndex="-1" class="move mac-only" href="command:workbench.action.files.openLocalFileFolder">${openFileCopy}</a></li>
|
||||
<li role="none" id="dropdown-windows-linux-only"><a role="menuitem" tabIndex="-1" class="move windows-only linux-only" href="command:workbench.action.files.openFile">${openFileCopy}</a></li`;
|
||||
const getDropdownBtn = container.querySelector('#dropdown-btn-container .monaco-button') as HTMLElement;
|
||||
getDropdownBtn.id = 'dropdown-btn';
|
||||
getDropdownBtn.setAttribute('role', 'navigation');
|
||||
getDropdownBtn.setAttribute('aria-haspopup', 'true');
|
||||
getDropdownBtn.setAttribute('aria-controls', 'dropdown');
|
||||
nav.setAttribute('role', 'navigation');
|
||||
nav.classList.add('dropdown-nav');
|
||||
dropdownUl.classList.add('dropdown');
|
||||
getDropdownBtn.id = 'dropdown-btn';
|
||||
getDropdownBtn.appendChild(i);
|
||||
nav.appendChild(dropdownUl);
|
||||
dropdownButtonContainer.appendChild(nav);
|
||||
const fileBtnWindowsClasses = ['windows-only', 'linux-only', 'btn-secondary'];
|
||||
const fileBtnMacClasses = ['mac-only', 'btn-secondary'];
|
||||
|
||||
const fileBtnContainer = container.querySelector('#open-file-btn-container') as HTMLElement;
|
||||
const openFileText = openFileCopy;
|
||||
let openFileButton = this._register(new Button(fileBtnContainer));
|
||||
openFileButton.label = openFileText;
|
||||
const getNewFileBtn = container.querySelector('#open-file-btn-container .monaco-button') as HTMLAnchorElement;
|
||||
const body = document.querySelector('body');
|
||||
|
||||
if (body.classList.contains('windows') || body.classList.contains('linux')) {
|
||||
getNewFileBtn.classList.add(...fileBtnWindowsClasses);
|
||||
openFileButton.onDidClick(async () => {
|
||||
await this.commandService.executeCommand('workbench.action.files.openFile');
|
||||
}
|
||||
);
|
||||
} else if (body.classList.contains('mac')) {
|
||||
getNewFileBtn.classList.add(...fileBtnMacClasses);
|
||||
openFileButton.onDidClick(async () => {
|
||||
await this.commandService.executeCommand('workbench.action.files.openLocalFileFolder');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private enableGuidedTour(): void {
|
||||
const guidedTour = this.instantiationService.createInstance(GuidedTour);
|
||||
const adsHomepage = document.querySelector('.ads-homepage');
|
||||
@@ -375,6 +442,7 @@ class WelcomePage extends Disposable {
|
||||
guidedTour.create();
|
||||
});
|
||||
|
||||
|
||||
removeTourBtn.addEventListener('click', (e: MouseEvent) => {
|
||||
this.configurationService.updateValue(configurationKey, 'welcomePage', ConfigurationTarget.USER);
|
||||
guidedTourNotificationContainer.classList.add('hide');
|
||||
@@ -390,10 +458,11 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
|
||||
private createWidePreviewToolTip(): void {
|
||||
const previewLink = document.querySelector('#tool-tip-container-wide') as HTMLElement;
|
||||
const tooltip = document.querySelector('#tooltip-text-wide') as HTMLElement;
|
||||
const previewModalBody = document.querySelector('.preview-tooltip-body') as HTMLElement;
|
||||
const previewModalHeader = document.querySelector('.preview-tooltip-header') as HTMLElement;
|
||||
const container = document.querySelector('.ads-homepage .tool-tip');
|
||||
const previewLink = container.querySelector('#tool-tip-container-wide') as HTMLElement;
|
||||
const tooltip = container.querySelector('#tooltip-text-wide') as HTMLElement;
|
||||
const previewModalBody = container.querySelector('.preview-tooltip-body') as HTMLElement;
|
||||
const previewModalHeader = container.querySelector('.preview-tooltip-header') as HTMLElement;
|
||||
addStandardDisposableListener(previewLink, 'mouseover', () => {
|
||||
tooltip.setAttribute('aria-hidden', 'true');
|
||||
tooltip.classList.toggle('show');
|
||||
@@ -431,6 +500,7 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('click', (event) => {
|
||||
const target = event.target as HTMLTextAreaElement;
|
||||
if (!target.matches('.tooltip')) {
|
||||
@@ -442,8 +512,9 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
|
||||
private createDropDown(): void {
|
||||
const dropdownBtn = document.querySelector('#dropdown-btn') as HTMLElement;
|
||||
const dropdown = document.querySelector('#dropdown') as HTMLInputElement;
|
||||
const container = document.querySelector('.ads-homepage .hero');
|
||||
const dropdownBtn = container.querySelector('#dropdown-btn') as HTMLElement;
|
||||
const dropdown = container.querySelector('#dropdown') as HTMLInputElement;
|
||||
addStandardDisposableListener(dropdownBtn, 'click', () => {
|
||||
dropdown.classList.toggle('show');
|
||||
});
|
||||
@@ -466,24 +537,25 @@ class WelcomePage extends Disposable {
|
||||
|
||||
const body = document.querySelector('body');
|
||||
if (body.classList.contains('windows') || body.classList.contains('linux')) {
|
||||
const macOnly = document.querySelector('#dropdown-mac-only');
|
||||
const macOnly = container.querySelector('#dropdown-mac-only');
|
||||
macOnly.remove();
|
||||
} else if (body.classList.contains('mac')) {
|
||||
const windowsLinuxOnly = document.querySelector('#dropdown-windows-linux-only');
|
||||
const windowsLinuxOnly = container.querySelector('#dropdown-windows-linux-only');
|
||||
windowsLinuxOnly.remove();
|
||||
}
|
||||
window.addEventListener('click', (event) => {
|
||||
const target = event.target as HTMLTextAreaElement;
|
||||
if (!target.matches('.dropdown')) {
|
||||
if (!target.matches('#dropdown-btn')) {
|
||||
if (dropdown.classList.contains('show')) {
|
||||
dropdown.classList.remove('show');
|
||||
dropdown.classList.toggle('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addStandardDisposableListener(dropdown, 'keydown', event => {
|
||||
const dropdownLastElement = document.querySelector('#dropdown').lastElementChild.children[0] as HTMLInputElement;
|
||||
const dropdownFirstElement = document.querySelector('#dropdown').firstElementChild.children[0] as HTMLInputElement;
|
||||
const container = document.querySelector('.ads-homepage .hero');
|
||||
const dropdownLastElement = container.querySelector('#dropdown').lastElementChild.children[0] as HTMLInputElement;
|
||||
const dropdownFirstElement = container.querySelector('#dropdown').firstElementChild.children[0] as HTMLInputElement;
|
||||
if (event.equals(KeyCode.Tab)) {
|
||||
EventHelper.stop(event);
|
||||
return;
|
||||
@@ -492,7 +564,7 @@ class WelcomePage extends Disposable {
|
||||
if (event.target === dropdownFirstElement) {
|
||||
dropdownLastElement.focus();
|
||||
} else {
|
||||
const movePrev = <HTMLElement>document.querySelector('.move:focus').parentElement.previousElementSibling.children[0] as HTMLElement;
|
||||
const movePrev = <HTMLElement>container.querySelector('.move:focus').parentElement.previousElementSibling.children[0] as HTMLElement;
|
||||
movePrev.focus();
|
||||
}
|
||||
}
|
||||
@@ -500,7 +572,7 @@ class WelcomePage extends Disposable {
|
||||
if (event.target === dropdownLastElement) {
|
||||
dropdownFirstElement.focus();
|
||||
} else {
|
||||
const moveNext = <HTMLElement>document.querySelector('.move:focus').parentElement.nextElementSibling.children[0] as HTMLElement;
|
||||
const moveNext = <HTMLElement>container.querySelector('.move:focus').parentElement.nextElementSibling.children[0] as HTMLElement;
|
||||
moveNext.focus();
|
||||
}
|
||||
}
|
||||
@@ -508,13 +580,15 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
|
||||
private createPreviewModal(): void {
|
||||
const modal = document.querySelector('#preview-modal') as HTMLElement;
|
||||
const btn = document.querySelector('#tool-tip-container-narrow') as HTMLElement;
|
||||
const span = document.querySelector('.close-icon') as HTMLElement;
|
||||
const previewModalHeader = document.querySelector('.preview-modal-header') as HTMLElement;
|
||||
const container = document.querySelector('.ads-homepage');
|
||||
const modal = container.querySelector('#preview-modal') as HTMLElement;
|
||||
const btn = container.querySelector('#tool-tip-container-narrow') as HTMLElement;
|
||||
const span = container.querySelector('.close-icon') as HTMLElement;
|
||||
const previewModalHeader = container.querySelector('.preview-modal-header') as HTMLElement;
|
||||
btn.addEventListener('click', function () {
|
||||
modal.classList.toggle('show');
|
||||
});
|
||||
|
||||
span.addEventListener('click', function () {
|
||||
modal.classList.remove('show');
|
||||
});
|
||||
@@ -548,10 +622,9 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modal.addEventListener('keydown', function (e: KeyboardEvent) {
|
||||
const previewModalBody = document.querySelector('.preview-modal-body') as HTMLElement;
|
||||
const previewModalHeader = document.querySelector('.preview-modal-header') as HTMLElement;
|
||||
const previewModalBody = container.querySelector('.preview-modal-body') as HTMLElement;
|
||||
const previewModalHeader = container.querySelector('.preview-modal-header') as HTMLElement;
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
|
||||
if (event.equals(KeyCode.Tab)) {
|
||||
@@ -566,7 +639,7 @@ class WelcomePage extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private async createListEntries(fileService: IFileService, fullPath: URI, windowOpenable: IWindowOpenable, relativePath: string): Promise<HTMLElement[]> {
|
||||
private async createListEntries(container: HTMLElement, fileService: IFileService, fullPath: URI, windowOpenable: IWindowOpenable, relativePath: string): Promise<HTMLElement[]> {
|
||||
let result: HTMLElement[] = [];
|
||||
const value = await fileService.resolve(fullPath);
|
||||
let date = new Date(value.mtime);
|
||||
@@ -578,12 +651,13 @@ class WelcomePage extends Disposable {
|
||||
const icon = document.createElement('i');
|
||||
const a = document.createElement('a');
|
||||
const span = document.createElement('span');
|
||||
const ul = document.querySelector('.recent ul');
|
||||
const ul = container.querySelector('.list');
|
||||
icon.title = relativePath;
|
||||
a.innerText = name;
|
||||
a.title = relativePath;
|
||||
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
|
||||
a.href = 'javascript:void(0)';
|
||||
|
||||
a.addEventListener('click', e => {
|
||||
this.telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', {
|
||||
id: 'openRecentFolder',
|
||||
@@ -606,7 +680,7 @@ class WelcomePage extends Disposable {
|
||||
return result;
|
||||
}
|
||||
|
||||
private async mapListEntries(recents: (IRecentWorkspace | IRecentFolder)[], fileService: IFileService): Promise<HTMLElement[]> {
|
||||
private async mapListEntries(recents: (IRecentWorkspace | IRecentFolder)[], fileService: IFileService, container: HTMLElement): Promise<HTMLElement[]> {
|
||||
const result: HTMLElement[] = [];
|
||||
for (let i = 0; i < recents.length; i++) {
|
||||
const recent = recents[i];
|
||||
@@ -621,7 +695,7 @@ class WelcomePage extends Disposable {
|
||||
relativePath = recent.label || this.labelService.getWorkspaceLabel(recent.workspace, { verbose: true });
|
||||
windowOpenable = { workspaceUri: recent.workspace.configPath };
|
||||
}
|
||||
const elements = await this.createListEntries(fileService, fullPath, windowOpenable, relativePath);
|
||||
const elements = await this.createListEntries(container, fileService, fullPath, windowOpenable, relativePath);
|
||||
result.push(...elements);
|
||||
}
|
||||
return result;
|
||||
@@ -662,33 +736,46 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
|
||||
private addExtensionPack(container: HTMLElement, anchorSelector: string): void {
|
||||
const btnContainer = container.querySelector(anchorSelector);
|
||||
const btnContainer = container.querySelector(anchorSelector) as HTMLElement;
|
||||
|
||||
if (btnContainer) {
|
||||
extensionPacks.forEach((extension, i) => {
|
||||
const a = document.createElement('a');
|
||||
const classes = ['btn', 'btn-secondary', 'a-self-end', 'flex', 'flex-a-center', 'flex-j-center'];
|
||||
const btn = document.createElement('button');
|
||||
const description = document.querySelector('.extension-pack-body');
|
||||
const header = document.querySelector('.extension-pack-header');
|
||||
a.classList.add(...classes);
|
||||
a.innerText = localize('welcomePage.install', "Install");
|
||||
a.title = extension.title || (extension.isKeymap ? localize('welcomePage.installKeymap', "Install {0} keymap", extension.name) : localize('welcomePage.installExtensionPack', "Install additional support for {0}", extension.name));
|
||||
a.classList.add('installExtension');
|
||||
a.setAttribute('data-extension', extension.id);
|
||||
a.href = 'javascript:void(0)';
|
||||
a.addEventListener('click', e => {
|
||||
extensionPacks.forEach((extension) => {
|
||||
const installText = localize('welcomePage.install', "Install");
|
||||
let dropdownBtn = this._register(new Button(btnContainer));
|
||||
dropdownBtn.label = installText;
|
||||
const classes = ['btn', 'btn-secondary'];
|
||||
const getDropdownBtn = container.querySelector('.extensionPack .monaco-button:first-of-type') as HTMLAnchorElement;
|
||||
getDropdownBtn.id = 'dropdown-btn';
|
||||
getDropdownBtn.classList.add(...classes);
|
||||
getDropdownBtn.title = extension.title || (extension.isKeymap ? localize('welcomePage.installKeymap', "Install {0} keymap", extension.name) : localize('welcomePage.installExtensionPack', "Install additional support for {0}", extension.name));
|
||||
getDropdownBtn.setAttribute('aria-haspopup', 'true');
|
||||
getDropdownBtn.setAttribute('aria-controls', 'dropdown');
|
||||
getDropdownBtn.id = 'dropdown-btn';
|
||||
getDropdownBtn.classList.add('installExtension');
|
||||
getDropdownBtn.setAttribute('data-extension', extension.id);
|
||||
getDropdownBtn.href = 'javascript:void(0)';
|
||||
|
||||
getDropdownBtn.addEventListener('click', e => {
|
||||
this.installExtension(extension);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
btnContainer.appendChild(a);
|
||||
btn.innerText = localize('welcomePage.installed', "Installed");
|
||||
btn.title = extension.isKeymap ? localize('welcomePage.installedKeymap', "{0} keymap is already installed", extension.name) : localize('welcomePage.installedExtensionPack', "{0} support is already installed", extension.name);
|
||||
btn.classList.add('enabledExtension');
|
||||
btn.classList.add(...classes);
|
||||
btn.setAttribute('disabled', 'true');
|
||||
btn.setAttribute('data-extension', extension.id);
|
||||
btnContainer.appendChild(btn);
|
||||
|
||||
|
||||
const description = container.querySelector('.extension-pack-body');
|
||||
const header = container.querySelector('.extension-pack-header');
|
||||
|
||||
const installedText = localize('welcomePage.installed', "Installed");
|
||||
let installedButton = new Button(btnContainer);
|
||||
installedButton.label = installedText;
|
||||
installedButton.enabled = false;
|
||||
const getInstalledButton = container.querySelector('.extensionPack .monaco-button:nth-of-type(2)') as HTMLAnchorElement;
|
||||
|
||||
getInstalledButton.innerText = localize('welcomePage.installed', "Installed");
|
||||
getInstalledButton.title = extension.isKeymap ? localize('welcomePage.installedKeymap', "{0} keymap is already installed", extension.name) : localize('welcomePage.installedExtensionPack', "{0} support is already installed", extension.name);
|
||||
getInstalledButton.classList.add('enabledExtension');
|
||||
getInstalledButton.classList.add(...classes);
|
||||
getInstalledButton.setAttribute('data-extension', extension.id);
|
||||
description.innerHTML = extension.description;
|
||||
header.innerHTML = extension.name;
|
||||
this.addExtensionPackList(container, '.extension-pack-extension-list');
|
||||
@@ -923,6 +1010,7 @@ registerThemingParticipant((theme, collector) => {
|
||||
const tileBackgroundColor = theme.getColor(inputBackground);
|
||||
if (tileBackgroundColor) {
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .tile:not(.extension):not(.extension-pack) { background-color: ${tileBackgroundColor}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .btn-secondary .monaco-button { background-color: ${tileBackgroundColor} !important; }`);
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .tool-tip .tool-tip-text { background-color: ${tileBackgroundColor}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .modal-content { background-color: ${tileBackgroundColor}; }`);
|
||||
}
|
||||
@@ -955,7 +1043,7 @@ registerThemingParticipant((theme, collector) => {
|
||||
}
|
||||
const buttonSecondaryBackgroundColor = theme.getColor(buttonSecondaryBackground);
|
||||
if (buttonSecondaryBackgroundColor) {
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .btn-secondary { background-color: ${buttonSecondaryBackgroundColor};}`);
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .btn-secondary { background-color: ${buttonSecondaryBackgroundColor} !important;}`);
|
||||
}
|
||||
const buttonSecondaryBorderColor = theme.getColor(buttonSecondaryBorder);
|
||||
if (buttonSecondaryBorderColor) {
|
||||
@@ -963,7 +1051,7 @@ registerThemingParticipant((theme, collector) => {
|
||||
}
|
||||
const buttonSecondaryColor = theme.getColor(buttonSecondary);
|
||||
if (buttonSecondaryColor) {
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .btn-secondary { color: ${buttonSecondaryColor};}`);
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePageContainer .btn-secondary { color: ${buttonSecondaryColor} !important;}`);
|
||||
}
|
||||
const buttonSecondaryHover = theme.getColor(buttonSecondaryHoverColor);
|
||||
if (buttonSecondaryColor) {
|
||||
@@ -1037,6 +1125,7 @@ registerThemingParticipant((theme, collector) => {
|
||||
const link = theme.getColor(textLinkForeground);
|
||||
if (link) {
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePage a { color: ${link}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.editor > .content .welcomePage .btn-primary .monaco-button { border: 1px solid ${link}; }`);
|
||||
}
|
||||
const activeLink = theme.getColor(textLinkActiveForeground);
|
||||
if (activeLink) {
|
||||
|
||||
Reference in New Issue
Block a user