Convert from Polymer to Lit
Change-Id: Iede750ec006911b12df7bb85ab1d453c3ebf8821
diff --git a/BUILD b/BUILD
index cacb69a..274216d 100644
--- a/BUILD
+++ b/BUILD
@@ -6,7 +6,6 @@
"PLUGIN_TEST_DEPS",
"gerrit_plugin",
)
-load("//tools/bzl:js.bzl", "gerrit_js_bundle")
LFS_DEPS = [
"@jgit//org.eclipse.jgit.lfs.server:jgit-lfs-server",
@@ -39,17 +38,11 @@
"Gerrit-SshModule: com.googlesource.gerrit.plugins.lfs.SshModule",
"Gerrit-InitStep: com.googlesource.gerrit.plugins.lfs.InitLfs",
],
- resource_jars = [":gr-lfs"],
+ resource_jars = ["//plugins/lfs/web:lfs"],
resources = glob(["src/main/resources/**/*"]),
deps = LFS_DEPS,
)
-gerrit_js_bundle(
- name = "gr-lfs",
- srcs = glob(["gr-lfs/*.js"]),
- entry_point = "gr-lfs/plugin.js",
-)
-
junit_tests(
name = "lfs_tests",
srcs = glob(["src/test/java/**/*.java"]),
diff --git a/gr-lfs/gr-lfs-project-info.js b/gr-lfs/gr-lfs-project-info.js
deleted file mode 100644
index 980ce20..0000000
--- a/gr-lfs/gr-lfs-project-info.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {htmlTemplate} from './gr-lfs-project-info_html.js';
-
-class GrLfsProjectInfo extends Polymer.Element {
- static get is() {
- return 'gr-lfs-project-info';
- }
-
- static get template() {
- return htmlTemplate;
- }
-
- static get properties() {
- return {
- repoName: String,
- _appliedConfig: Object,
- };
- }
-
- connectedCallback() {
- super.connectedCallback();
-
- this._getPreferences();
- }
-
- _getPreferences() {
- let encodedRepoName = encodeURIComponent(this.repoName);
- return this.plugin.restApi('/projects/')
- .get(`${encodedRepoName}/${this.plugin.getPluginName()}~lfs:config-project`)
- .then(config => {
- if (!config || Object.entries(config).length === 0) {
- this.$.lfsProjectInfo.hidden = true;
- return;
- }
-
- this._appliedConfig = config
- })
- }
-}
-
-customElements.define(GrLfsProjectInfo.is, GrLfsProjectInfo);
diff --git a/gr-lfs/gr-lfs-project-info_html.js b/gr-lfs/gr-lfs-project-info_html.js
deleted file mode 100644
index 953d594..0000000
--- a/gr-lfs/gr-lfs-project-info_html.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @license
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-export const htmlTemplate = Polymer.html`
-<style include="shared-styles"></style>
-<style include="gr-form-styles"></style>
-<style>
- .sectionTitle {
- padding-top: 2em;
- }
-</style>
-<fieldset id="lfsProjectInfo" class="gr-form-styles">
- <h2 class="sectionTitle">LFS Info</h2>
- <section>
- <span class="title">Enabled</span>
- <span class="value">[[_appliedConfig.enabled]]</span>
- </section>
- <section>
- <span class="title">Max Object Size</span>
- <span class="value">[[_appliedConfig.max_object_size]]</span>
- </section>
- <section>
- <span class="title">Read Only</span>
- <span class="value">[[_appliedConfig.read_only]]</span>
- </section>
- <section hidden="[[!_appliedConfig.backend]]">
- <span class="title">Backend</span>
- <span class="value">[[_appliedConfig.backend]]</span>
- </section>
-</fieldset>`;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java
index 640704b..146ba44 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java
@@ -62,7 +62,7 @@
populateRepository(backend);
}
- DynamicSet.bind(binder(), WebUiPlugin.class).toInstance(new JavaScriptPlugin("gr-lfs.js"));
+ DynamicSet.bind(binder(), WebUiPlugin.class).toInstance(new JavaScriptPlugin("lfs.js"));
}
private void populateRepository(LfsBackend backend) {
diff --git a/web/BUILD b/web/BUILD
new file mode 100644
index 0000000..8e9b27a
--- /dev/null
+++ b/web/BUILD
@@ -0,0 +1,42 @@
+load("//tools/js:eslint.bzl", "plugin_eslint")
+load("//tools/bzl:js.bzl", "gerrit_js_bundle")
+load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project")
+
+package_group(
+ name = "visibility",
+ packages = ["//plugins/lfs/..."],
+)
+
+package(default_visibility = [":visibility"])
+
+ts_config(
+ name = "tsconfig",
+ src = "tsconfig.json",
+ deps = [
+ "//plugins:tsconfig-plugins-base.json",
+ ],
+)
+
+ts_project(
+ name = "lfs-ts",
+ srcs = glob(
+ ["**/*.ts"],
+ exclude = ["**/*test*"],
+ ),
+ incremental = True,
+ out_dir = "_bazel_ts_out",
+ tsc = "//tools/node_tools:tsc-bin",
+ tsconfig = ":tsconfig",
+ deps = [
+ "@plugins_npm//@gerritcodereview/typescript-api",
+ "@plugins_npm//lit",
+ ],
+)
+
+gerrit_js_bundle(
+ name = "lfs",
+ srcs = [":lfs-ts"],
+ entry_point = "_bazel_ts_out/plugin.js",
+)
+
+plugin_eslint()
diff --git a/web/eslint.config.js b/web/eslint.config.js
new file mode 100644
index 0000000..eb9cfcc
--- /dev/null
+++ b/web/eslint.config.js
@@ -0,0 +1,18 @@
+/**
+ * @license
+ * Copyright 2025 The Android Open Source Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+const {defineConfig} = require('eslint/config');
+
+// eslint-disable-next-line no-undef
+__plugindir = 'lfs/web';
+
+const gerritEslint = require('../../eslint.config.js');
+
+module.exports = defineConfig([
+ {
+ extends: [gerritEslint],
+ },
+]);
diff --git a/web/gr-lfs.ts b/web/gr-lfs.ts
new file mode 100644
index 0000000..e112c73
--- /dev/null
+++ b/web/gr-lfs.ts
@@ -0,0 +1,126 @@
+/**
+ * @license
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {PluginApi} from '@gerritcodereview/typescript-api/plugin';
+import {css, CSSResult, html, LitElement, nothing} from 'lit';
+import {customElement, property, state} from 'lit/decorators.js';
+import '@gerritcodereview/typescript-api/gerrit';
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'gr-lfs': GrLfs;
+ }
+}
+
+@customElement('gr-lfs')
+export class GrLfs extends LitElement {
+ @property({type: Object})
+ plugin!: PluginApi;
+
+ @property({type: String}) repoName = '';
+
+ @state() private _appliedConfig?: {
+ enabled?: boolean;
+ max_object_size?: string;
+ read_only?: boolean;
+ backend?: string;
+ };
+
+ override connectedCallback() {
+ super.connectedCallback();
+ this._getPreferences();
+ }
+
+ static override get styles() {
+ return [
+ window.Gerrit?.styles.form as CSSResult,
+ css`
+ :host {
+ display: block;
+ }
+
+ .sectionTitle {
+ padding-top: 2em;
+ }
+
+ /* Placeholder: Replace these with actual shared styles or imports */
+ .gr-form-styles {
+ border: none;
+ padding: 0;
+ }
+
+ section {
+ display: flex;
+ margin-bottom: 8px;
+ }
+
+ .title {
+ font-weight: bold;
+ width: 150px;
+ }
+
+ .value {
+ flex: 1;
+ }
+ `,
+ ];
+ }
+
+ override render() {
+ const cfg = this._appliedConfig;
+ if (!cfg) return nothing;
+
+ return html`
+ <fieldset class="gr-form-styles">
+ <h2 class="sectionTitle">LFS Info</h2>
+ <section>
+ <span class="title">Enabled</span>
+ <span class="value">${cfg.enabled ?? ''}</span>
+ </section>
+ <section>
+ <span class="title">Max Object Size</span>
+ <span class="value">${cfg.max_object_size ?? ''}</span>
+ </section>
+ <section>
+ <span class="title">Read Only</span>
+ <span class="value">${cfg.read_only ?? ''}</span>
+ </section>
+ ${cfg.backend
+ ? html`
+ <section>
+ <span class="title">Backend</span>
+ <span class="value">${cfg.backend}</span>
+ </section>
+ `
+ : nothing}
+ </fieldset>
+ `;
+ }
+
+ private _getPreferences() {
+ let encodedRepoName = encodeURIComponent(this.repoName);
+ return this.plugin.restApi()
+ .get(`/projects/${encodedRepoName}/${this.plugin.getPluginName()}~lfs:config-project`)
+ .then(config => {
+ if (!config || Object.entries(config).length === 0) {
+ return;
+ }
+
+ this._appliedConfig = config
+ })
+ }
+}
diff --git a/gr-lfs/plugin.js b/web/plugin.ts
similarity index 72%
rename from gr-lfs/plugin.js
rename to web/plugin.ts
index afeacd5..04bc2ec 100644
--- a/gr-lfs/plugin.js
+++ b/web/plugin.ts
@@ -1,6 +1,6 @@
/**
* @license
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import './gr-lfs-project-info.js';
+import '@gerritcodereview/typescript-api/gerrit';
+import './gr-lfs';
-Gerrit.install(plugin => {
- plugin.registerCustomComponent(
- 'repo-config', 'gr-lfs-project-info');
+window.Gerrit?.install(plugin => {
+ plugin.registerCustomComponent('repo-config', 'gr-lfs');
});
diff --git a/web/tsconfig.json b/web/tsconfig.json
new file mode 100644
index 0000000..2df6d21
--- /dev/null
+++ b/web/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig-plugins-base.json",
+ "compilerOptions": {
+ "outDir": "../../../.ts-out/plugins/lfs" /* overridden by bazel */
+ },
+ "include": [
+ "**/*.ts"
+ ]
+}