Skip to content

Commit

Permalink
Merge pull request #2392 from opral/introduce-settings-component-into…
Browse files Browse the repository at this point in the history
…-sherlock

introduce settings component in Sherlock 🕵️‍♂️
  • Loading branch information
felixhaeberle authored Apr 11, 2024
2 parents ca00e01 + e58678b commit a0f306e
Show file tree
Hide file tree
Showing 19 changed files with 385 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-parents-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"vs-code-extension": minor
---

introduce inlang settings component
7 changes: 7 additions & 0 deletions .changeset/quick-ties-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@inlang/message-lint-rule-identical-pattern": patch
"@inlang/plugin-next-intl": patch
"@inlang/plugin-i18next": patch
---

fix typo
120 changes: 120 additions & 0 deletions inlang/source-code/ide-extension/assets/settings-view.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* settings webview */

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html, body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WUI", "Ubuntu", sans-serif;
color: var(--vscode-foreground);
background-color: var(--vscode-sideBar-background);
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: text;
-webkit-user-select: text;
}

main {
padding: 20px;
}

main > h1 {
font-size: 22px;
margin-block-end: 20px;
}

inlang-settings {
/* Primary */
--inlang-color-primary: var(--vscode-button-background);
--inlang-color-neutral: var(--vscode-foreground);
/* Input */
--sl-input-background-color: var(--vscode-input-background);
--sl-input-background-color-disabled: var(--vscode-input-background);
--sl-input-border-color: var(--vscode-input-border);
--sl-input-border-color-hover: var(--vscode-input-activeBorder);
--sl-input-border-color-focus: var(--vscode-input-activeBorder);
--sl-input-border-radius: 4px;
--sl-input-border-width: 1px;
--sl-input-color: var(--vscode-input-foreground);
--sl-input-color-hover: var(--vscode-input-foreground);
--sl-input-color-focus: var(--vscode-input-foreground);
--sl-input-color-disabled: var(--vscode-disabledForeground);
--sl-input-focus-ring-color: var(--vscode-focusBorder);
--sl-input-icon-color: var(--vscode-input-foreground);
--sl-input-icon-color-hover: var(--vscode-input-foreground);
--sl-input-icon-color-focus: var(--vscode-input-foreground);
--sl-input-placeholder-color: var(--vscode-input-foreground);
--sl-input-placeholder-color-disabled: var(--vscode-disabledForeground);
/* Input Filled */
--sl-input-filled-background-color: var(--vscode-input-background);
--sl-input-filled-background-color-hover: var(--vscode-input-background);
--sl-input-filled-background-color-focus: var(--vscode-input-background);
--sl-input-filled-background-color-disabled: var(--vscode-input-background);
--sl-input-filled-color: var(--vscode-input-foreground);
--sl-input-filled-color-hover: var(--vscode-input-foreground);
--sl-input-filled-color-focus: var(--vscode-disabledForeground);
--sl-input-filled-color-disabled: var(--vscode-);
--sl-input-help-text-color: var(--vscode-descriptionForeground);
/* Focus Ring */
--sl-focus-ring-color: var(--vscode-focusBorder);
--sl-focus-ring-width: 3px;
--sl-focus-ring-offset: 1px;
/* Tooltip */
--sl-tooltip-background-color: var(--vscode-button-background);
--sl-tooltip-color: var(--vscode-button-foreground);
/* Panels */
--sl-panel-background-color: var(--vscode-sideBar-background);
--sl-panel-border-color: var(--vscode-sideBar-background);
--sl-panel-border-width: 1px;
}

inlang-settings::part(base) {
gap: 36px;
}

inlang-settings::part(module) {
gap: 28px;
}


inlang-settings::part(property-title) {
font-size: 16px;
font-weight: 600;
}

inlang-settings::part(property-paragraph) {
font-size: 14px;
color: var(--vscode-descriptionForeground);
}

inlang-settings::part(option-wrapper) {
/* FIXME after https://github.com/shoelace-style/shoelace/issues/1968 */
background-color: var(--vscode-input-background) !important;
}

inlang-settings::part(option) {
color: var(--vscode-input-foreground);
/* FIXME after https://github.com/shoelace-style/shoelace/issues/1968 */
background-color: var(--vscode-input-background) !important;
font-size: 14px;
padding: 8px 12px;
}

inlang-settings::part(button) {
color: var(--vscode-button-secondaryForeground);
background-color: var(--vscode-button-secondaryBackground);
border-color: var(--vscode-button-secondaryBackground);
}

inlang-settings::part(float) {
background-color: var(--vscode-sideBar-background);
color: var(--vscode-sideBar-foreground);
border: 1px solid var(--vscode-sideBar-border);
}
inlang-settings::part(cancel) {
background-color: var(--vscode-button-secondaryBackground);
color: var(--vscode-button-secondaryForeground);
}
15 changes: 11 additions & 4 deletions inlang/source-code/ide-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@
"title": "Open settings file",
"icon": "$(go-to-file)"
},
{
"command": "sherlock.openSettingsView",
"title": "Open settings view",
"icon": "$(settings-gear)"
},
{
"command": "sherlock.copyError",
"title": "Copy Error",
Expand All @@ -95,13 +100,13 @@
"menus": {
"view/item/context": [
{
"when": "view == projectView && viewItem == projectViewNode",
"command": "sherlock.openProject",
"when": "view == projectView",
"command": "sherlock.openSettingsFile",
"group": "navigation"
},
{
"when": "view == projectView && viewItem == projectViewNode",
"command": "sherlock.openSettingsFile",
"when": "view == projectView && viewItem == projectViewNodeSelected",
"command": "sherlock.openSettingsView",
"group": "inline"
},
{
Expand Down Expand Up @@ -157,11 +162,13 @@
"@inlang/result": "workspace:*",
"@inlang/rpc": "workspace:*",
"@inlang/sdk": "workspace:*",
"@inlang/settings-component": "workspace:*",
"@inlang/telemetry": "workspace:*",
"@lix-js/client": "workspace:*",
"@lix-js/fs": "workspace:*",
"@vitest/coverage-v8": "0.34.6",
"https-proxy-agent": "7.0.2",
"lit-html": "^3.1.2",
"require-from-string": "^2.0.2",
"throttle-debounce": "^5.0.0",
"vitest": "0.34.6"
Expand Down
18 changes: 18 additions & 0 deletions inlang/source-code/ide-extension/src/commands/openSettingsView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { commands } from "vscode"
import { telemetry } from "../services/telemetry/implementation.js"
import { settingsPanel } from "../utilities/settings/settingsView.js"
import type { ProjectViewNode } from "../utilities/project/project.js"

export const openSettingsViewCommand = {
command: "sherlock.openSettingsView",
title: "Sherlock: Open Settings View",
register: commands.registerCommand,
callback: async function (node: ProjectViewNode) {
await settingsPanel({ context: node.context })

telemetry.capture({
event: "IDE-EXTENSION Settings View opened",
})
return undefined
},
}
3 changes: 3 additions & 0 deletions inlang/source-code/ide-extension/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { copyErrorCommand } from "./commands/copyError.js"
import { previewLanguageTagCommand } from "./commands/previewLanguageTagCommand.js"
import { jumpToPositionCommand } from "./commands/jumpToPosition.js"
import { machineTranslateMessageCommand } from "./commands/machineTranslate.js"
import { openSettingsViewCommand } from "./commands/openSettingsView.js"

export const CONFIGURATION = {
EVENTS: {
Expand All @@ -18,6 +19,7 @@ export const CONFIGURATION = {
ON_DID_PROJECT_TREE_VIEW_CHANGE: new EventEmitter<ProjectViewNode | undefined>(),
ON_DID_ERROR_TREE_VIEW_CHANGE: new EventEmitter<ErrorNode | undefined>(),
ON_DID_PREVIEW_LANGUAGE_TAG_CHANGE: new EventEmitter<string>(),
ON_DID_SETTINGS_VIEW_CHANGE: new EventEmitter<void>(),
},
COMMANDS: {
EDIT_MESSAGE: editMessageCommand,
Expand All @@ -27,6 +29,7 @@ export const CONFIGURATION = {
OPEN_IN_EDITOR: openInEditorCommand,
OPEN_PROJECT: openProjectCommand,
OPEN_SETTINGS_FILE: openSettingsFileCommand,
OPEN_SETTINGS_VIEW: openSettingsViewCommand,
COPY_ERROR: copyErrorCommand,
MACHINE_TRANSLATE_MESSAGE: machineTranslateMessageCommand,
},
Expand Down
5 changes: 5 additions & 0 deletions inlang/source-code/ide-extension/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,15 @@ async function main(args: {

vscode.commands.executeCommand("setContext", "sherlock:hasProjectInWorkspace", true)

// Recommendation Banner
await recommendationBannerView(args)
// Project Listings
await projectView(args)
// Messages
await messageView(args)
// Errors
await errorView(args)
// Status Bar
await statusBar(args)

registerExtensionComponents(args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export type TelemetryEvents =
| "IDE-EXTENSION completed create config file"
| "IDE-EXTENSION loaded project"
| "IDE-EXTENSION Editor opened via tooltip"
| "IDE-EXTENSION Settings View opened"
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ export function createMessageWebviewProvider(args: {
})
)

// when settings view changes, update webview
args.context.subscriptions.push(
CONFIGURATION.EVENTS.ON_DID_SETTINGS_VIEW_CHANGE.event(() => {
updateMessages()
})
)

const updateWebviewContent = async () => {
const activeEditor = vscode.window.activeTextEditor
const fileContent = activeEditor ? activeEditor.document.getText() : ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,9 @@ vi.mock("@lix-js/client", () => ({
findRepoRoot: vi.fn(),
}))

beforeEach(() => {
// Reset all mocks before each test
vi.clearAllMocks()
})

describe("createProjectViewNodes", () => {
const mockContext = {} as vscode.ExtensionContext

beforeEach(() => {
vi.resetAllMocks()
})
Expand All @@ -123,7 +120,7 @@ describe("createProjectViewNodes", () => {
selectedProjectPath: "/path/to/project2",
})

const nodes = createProjectViewNodes()
const nodes = createProjectViewNodes({ context: mockContext })
expect(nodes.length).toBe(2)
expect(nodes[0]?.label).toBe("to/project1")
expect(nodes[1]?.isSelected).toBe(true)
Expand All @@ -135,7 +132,7 @@ describe("createProjectViewNodes", () => {
projectsInWorkspace: [],
selectedProjectPath: "/path/to/project2",
})
const nodes = createProjectViewNodes()
const nodes = createProjectViewNodes({ context: mockContext })
expect(nodes).toEqual([])
})

Expand All @@ -149,18 +146,21 @@ describe("createProjectViewNodes", () => {
],
selectedProjectPath: "/path/to/project2",
})
const nodes = createProjectViewNodes()
const nodes = createProjectViewNodes({ context: mockContext })
expect(nodes.some((node) => node.label === "")).toBe(true)
})
})

describe("getTreeItem", () => {
const mockContext = {} as vscode.ExtensionContext

it("should return a TreeItem for a given ProjectViewNode", () => {
const node: ProjectViewNode = {
label: "TestProject",
path: "/path/to/testproject",
isSelected: true,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
context: mockContext,
}
const workspaceFolder = {
uri: {
Expand All @@ -179,12 +179,15 @@ describe("getTreeItem", () => {
})

describe("handleTreeSelection", () => {
const mockContext = {} as vscode.ExtensionContext

it("should handle tree selection and update state", async () => {
const selectedNode: ProjectViewNode = {
label: "SelectedProject",
path: "/path/to/selected",
isSelected: true,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
context: mockContext,
}
const nodeishFs = {} as NodeishFilesystem
const workspaceFolder = {
Expand Down Expand Up @@ -213,6 +216,7 @@ describe("handleTreeSelection", () => {
path: "/path/to/selected",
isSelected: true,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
context: mockContext,
}
const nodeishFs = {} as NodeishFilesystem
const workspaceFolder = {
Expand All @@ -236,11 +240,14 @@ describe("handleTreeSelection", () => {
})

it("should handle error when project loading fails", async () => {
const mockContext = {} as vscode.ExtensionContext

const selectedNode: ProjectViewNode = {
label: "selected/project.inlang",
path: "/path/to/selected/project.inlang",
isSelected: true,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
context: mockContext,
}
const nodeishFs = {} as NodeishFilesystem
const workspaceFolder = {
Expand All @@ -262,14 +269,20 @@ describe("handleTreeSelection", () => {
})

describe("createTreeDataProvider", () => {
const mockContext = {} as vscode.ExtensionContext

it("should create a TreeDataProvider", () => {
const nodeishFs = {} as NodeishFilesystem
const workspaceFolder = {
uri: {
fsPath: "/path/to/workspace",
},
} as vscode.WorkspaceFolder
const treeDataProvider = createTreeDataProvider({ nodeishFs, workspaceFolder })
const treeDataProvider = createTreeDataProvider({
nodeishFs,
workspaceFolder,
context: mockContext,
})
expect(treeDataProvider).toBeDefined()
expect(treeDataProvider.getTreeItem).toBeInstanceOf(Function)
expect(treeDataProvider.getChildren).toBeInstanceOf(Function)
Expand Down
Loading

0 comments on commit a0f306e

Please sign in to comment.