mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 09:35:39 -05:00
185 lines
5.0 KiB
TypeScript
185 lines
5.0 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as azdata from 'azdata';
|
|
import * as vscode from 'vscode';
|
|
import { IconPathHelper } from '../constants/iconPathHelper';
|
|
import * as loc from '../constants/strings';
|
|
import { sendSqlMigrationActionEvent, TelemetryActions, TelemetryViews } from '../telemtery';
|
|
|
|
export class FeedbackDialog {
|
|
|
|
private static readonly DialogName: string = 'FeedbackDialog';
|
|
|
|
private _dialog!: azdata.window.Dialog;
|
|
private _buttonGroup!: azdata.FlexContainer;
|
|
private _isOpen: boolean = false;
|
|
private _feedbackRating?: number;
|
|
private _feedbackText?: string;
|
|
|
|
constructor() {
|
|
}
|
|
|
|
public async openDialog() {
|
|
if (!this._isOpen) {
|
|
this._isOpen = true;
|
|
this._dialog = azdata.window.createModelViewDialog(
|
|
'',
|
|
FeedbackDialog.DialogName,
|
|
440,
|
|
'normal',
|
|
'below');
|
|
|
|
this._dialog.registerContent(async view => {
|
|
const headingGroup = view.modelBuilder
|
|
.flexContainer()
|
|
.withItems([
|
|
view.modelBuilder
|
|
.image()
|
|
.withProperties<azdata.ImageComponentProperties>({
|
|
iconPath: IconPathHelper.sendFeedback,
|
|
iconHeight: 32,
|
|
iconWidth: 32,
|
|
height: 32,
|
|
width: 32,
|
|
})
|
|
.component(),
|
|
view.modelBuilder
|
|
.text()
|
|
.withProperties<azdata.TextComponentProperties>({
|
|
value: loc.FEEDBACK_DIALOG_HEADING,
|
|
CSSStyles: {
|
|
'margin': '0 0 0 10px',
|
|
},
|
|
})
|
|
.component(),
|
|
])
|
|
.withLayout({
|
|
width: '100%',
|
|
alignContent: 'flex-start',
|
|
flexFlow: 'row',
|
|
})
|
|
.component();
|
|
|
|
this._buttonGroup = view.modelBuilder
|
|
.flexContainer()
|
|
.withItems([
|
|
this._createFeedbackButton(view, 0, loc.FEEDBACK_DIALOG_RATING_1),
|
|
this._createFeedbackButton(view, 1, loc.FEEDBACK_DIALOG_RATING_2),
|
|
this._createFeedbackButton(view, 2, loc.FEEDBACK_DIALOG_RATING_3),
|
|
this._createFeedbackButton(view, 3, loc.FEEDBACK_DIALOG_RATING_4),
|
|
this._createFeedbackButton(view, 4, loc.FEEDBACK_DIALOG_RATING_5),
|
|
])
|
|
.withLayout({
|
|
alignContent: 'flex-start',
|
|
flexFlow: 'row',
|
|
})
|
|
.withProperties<azdata.ComponentProperties>({
|
|
display: 'inline-flex',
|
|
ariaLabel: loc.FEEDBACK_DIALOG_HEADING,
|
|
})
|
|
.component();
|
|
|
|
const feedbackInputBox = view.modelBuilder
|
|
.inputBox()
|
|
.withProperties<azdata.InputBoxProperties>({
|
|
rows: 3,
|
|
inputType: 'text',
|
|
multiline: true,
|
|
placeHolder: loc.FEEDBACK_DIALOG_PLACEHOLDER,
|
|
CSSStyles: {
|
|
'white-space': 'normal!important',
|
|
},
|
|
})
|
|
.component();
|
|
|
|
feedbackInputBox.onTextChanged(
|
|
value => this._feedbackText = value);
|
|
|
|
const formModel = view.modelBuilder
|
|
.formContainer()
|
|
.withFormItems([{
|
|
components: [
|
|
{
|
|
component: headingGroup,
|
|
},
|
|
{
|
|
component: this._buttonGroup,
|
|
},
|
|
{
|
|
component: feedbackInputBox,
|
|
}
|
|
],
|
|
title: ''
|
|
}])
|
|
.withLayout({ width: '100%' })
|
|
.component();
|
|
|
|
await view.initializeModel(formModel);
|
|
await this._buttonGroup.items[0].focus();
|
|
});
|
|
|
|
this._dialog.okButton.label = loc.FEEDBACK_DIALOG_SUBMIT_BUTTON;
|
|
this._dialog.okButton.onClick(async () => await this._execute());
|
|
|
|
this._dialog.cancelButton.label = loc.FEEDBACK_DIALOG_CANCEL_BUTTON;
|
|
this._dialog.cancelButton.onClick(() => this._cancel());
|
|
|
|
azdata.window.openDialog(this._dialog);
|
|
}
|
|
}
|
|
|
|
private async _execute() {
|
|
sendSqlMigrationActionEvent(
|
|
TelemetryViews.FeedbackDialog,
|
|
TelemetryActions.SendFeedback,
|
|
{
|
|
'FeedbackRating': this._feedbackRating?.toString() || '',
|
|
'FeedbackMessage': this._feedbackText?.substr(0, 500) || '',
|
|
});
|
|
|
|
await vscode.window.showInformationMessage(loc.FEEDBACK_DIALOG_SENT_MESSAGE);
|
|
this._isOpen = false;
|
|
}
|
|
|
|
private _cancel() {
|
|
this._isOpen = false;
|
|
}
|
|
|
|
private _createFeedbackButton(view: azdata.ModelView, index: number, ariaLabel: string): azdata.Component {
|
|
const button = view.modelBuilder
|
|
.button()
|
|
.withProperties<azdata.ButtonProperties>({
|
|
ariaLabel: ariaLabel,
|
|
height: '26px',
|
|
width: '26px',
|
|
buttonType: azdata.ButtonType.Normal,
|
|
iconHeight: '24px',
|
|
iconWidth: '24px',
|
|
iconPath: IconPathHelper.blueStar,
|
|
CSSStyles: {
|
|
'margin': '0 10px 0 0',
|
|
'padding': '0 0 0 0',
|
|
},
|
|
})
|
|
.component();
|
|
|
|
button.onDidClick(() => this._updateButtonImages(index));
|
|
|
|
return button;
|
|
}
|
|
|
|
private _updateButtonImages(index: number): void {
|
|
const items: azdata.Component[] = this._buttonGroup?.items || [];
|
|
this._feedbackRating = index;
|
|
for (let i = 0; i < items.length; i++) {
|
|
const btn = items[i] as azdata.ButtonComponent;
|
|
btn.iconPath = i <= index
|
|
? IconPathHelper.solidBlueStar
|
|
: IconPathHelper.blueStar;
|
|
}
|
|
}
|
|
}
|