From 2a77cd0eda382ce79ad1c06a9f42a83dc963b013 Mon Sep 17 00:00:00 2001 From: Daniel Smith <56164590+DanielRyanSmith@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:48:14 -0400 Subject: [PATCH] Convert intent preview components to TypeScript (#4393) * convert intent components to TypeScript * lint-fix * use customElement decorator * remove eslint check for folder with no js files --- ...ontent.js => chromedash-intent-content.ts} | 32 ++++----- ...e.js => chromedash-intent-preview-page.ts} | 69 +++++++++---------- ....js => chromedash-intent-template_test.ts} | 8 ++- package.json | 4 +- 4 files changed, 52 insertions(+), 61 deletions(-) rename client-src/elements/{chromedash-intent-content.js => chromedash-intent-content.ts} (88%) rename client-src/elements/{chromedash-intent-preview-page.js => chromedash-intent-preview-page.ts} (86%) rename client-src/elements/{chromedash-intent-template_test.js => chromedash-intent-template_test.ts} (80%) diff --git a/client-src/elements/chromedash-intent-content.js b/client-src/elements/chromedash-intent-content.ts similarity index 88% rename from client-src/elements/chromedash-intent-content.js rename to client-src/elements/chromedash-intent-content.ts index 70289489..2e0a0c53 100644 --- a/client-src/elements/chromedash-intent-content.js +++ b/client-src/elements/chromedash-intent-content.ts @@ -2,22 +2,16 @@ import {LitElement, css, html, nothing} from 'lit'; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import {SHARED_STYLES} from '../css/shared-css.js'; import {showToastMessage} from './utils.js'; +import {customElement, property} from 'lit/decorators.js'; +@customElement('chromedash-intent-content') export class ChromedashIntentContent extends LitElement { - static get properties() { - return { - appTitle: {type: String}, - subject: {type: String}, - intentBody: {type: String}, - }; - } - - constructor() { - super(); - this.appTitle = ''; - this.subject = ''; - this.intentBody = ''; - } + @property({type: String}) + appTitle = ''; + @property({type: String}) + subject = ''; + @property({type: String}) + intentBody = ''; static get styles() { return [ @@ -145,13 +139,13 @@ export class ChromedashIntentContent extends LitElement { } copyIntentBodyHandler() { - const copyEmailBodyEl = this.shadowRoot.querySelector('#copy-email-body'); - const emailBodyEl = this.shadowRoot.querySelector('.email'); + const copyEmailBodyEl = this.renderRoot.querySelector('#copy-email-body'); + const emailBodyEl = this.renderRoot.querySelector('.email'); if (copyEmailBodyEl && emailBodyEl) { - window.getSelection().removeAllRanges(); + window.getSelection()?.removeAllRanges(); const range = document.createRange(); range.selectNode(emailBodyEl); - window.getSelection().addRange(range); + window.getSelection()?.addRange(range); document.execCommand('copy'); showToastMessage('Email body copied'); } @@ -193,5 +187,3 @@ export class ChromedashIntentContent extends LitElement { `; } } - -customElements.define('chromedash-intent-content', ChromedashIntentContent); diff --git a/client-src/elements/chromedash-intent-preview-page.js b/client-src/elements/chromedash-intent-preview-page.ts similarity index 86% rename from client-src/elements/chromedash-intent-preview-page.js rename to client-src/elements/chromedash-intent-preview-page.ts index 20d8ce97..e8fbfd01 100644 --- a/client-src/elements/chromedash-intent-preview-page.js +++ b/client-src/elements/chromedash-intent-preview-page.ts @@ -1,42 +1,38 @@ import {LitElement, css, html, nothing} from 'lit'; import {SHARED_STYLES} from '../css/shared-css.js'; -import {showToastMessage} from './utils'; +import {showToastMessage} from './utils.js'; import {openPostIntentDialog} from './chromedash-post-intent-dialog.js'; import { STAGE_TYPES_DEV_TRIAL, STAGE_TYPES_SHIPPING, } from './form-field-enums.js'; import './chromedash-intent-content.js'; +import {customElement, property, state} from 'lit/decorators.js'; +import {Feature, StageDict} from '../js-src/cs-client.js'; +import {GateDict} from './chromedash-gate-chip.js'; +@customElement('chromedash-intent-preview-page') class ChromedashIntentPreviewPage extends LitElement { - static get properties() { - return { - appTitle: {type: String}, - featureId: {type: Number}, - gateId: {type: Number}, - feature: {type: Object}, - stage: {type: Object}, - gate: {type: Object}, - loading: {type: Boolean}, - subject: {type: String}, - intentBody: {type: String}, - displayFeatureUnlistedWarning: {type: Boolean}, - }; - } - - constructor() { - super(); - this.appTitle = ''; - this.featureId = 0; - this.gateId = 0; - this.feature = undefined; - this.stage = undefined; - this.gate = undefined; - this.loading = true; - this.subject = ''; - this.intentBody = ''; - this.displayFeatureUnlistedWarning = false; - } + @property({type: String}) + appTitle = ''; + @property({type: Number}) + featureId = 0; + @property({type: Number}) + gateId = 0; + @state() + feature!: Feature; + @state() + stage!: StageDict; + @state() + gate!: GateDict; + @state() + loading = false; + @state() + subject = ''; + @state() + intentBody = ''; + @state() + displayFeatureUnlistedWarning = false; static get styles() { return [ @@ -98,16 +94,22 @@ class ChromedashIntentPreviewPage extends LitElement { } // Check if gate matches an extension stage. if (!this.stage) { - this.stage = stage.extensions.find( + const extensionStage = stage.extensions.find( e => e.id === this.gate.stage_id ); + if (extensionStage) { + this.stage = extensionStage; + } } } } else if (!this.gateId) { // This is a "Ready for Developer Testing" intent if no gate is supplied (0). - this.stage = this.feature.stages.find(stage => + const devTrialStage = this.feature.stages.find(stage => STAGE_TYPES_DEV_TRIAL.has(stage.stage_type) ); + if (devTrialStage) { + this.stage = devTrialStage; + } } else { throw new Error('Invalid gate ID'); } @@ -228,8 +230,3 @@ class ChromedashIntentPreviewPage extends LitElement { `; } } - -customElements.define( - 'chromedash-intent-preview-page', - ChromedashIntentPreviewPage -); diff --git a/client-src/elements/chromedash-intent-template_test.js b/client-src/elements/chromedash-intent-template_test.ts similarity index 80% rename from client-src/elements/chromedash-intent-template_test.js rename to client-src/elements/chromedash-intent-template_test.ts index 497ea640..0c18812f 100644 --- a/client-src/elements/chromedash-intent-template_test.js +++ b/client-src/elements/chromedash-intent-template_test.ts @@ -15,10 +15,12 @@ describe('chromedash-intent-content', () => { assert.exists(component); assert.instanceOf(component, ChromedashIntentContent); - const subject = component.shadowRoot.querySelector( + const subject = component.renderRoot.querySelector( '#email-subject-content' - ); - const body = component.shadowRoot.querySelector('#email-body-content'); + ) as HTMLElement; + const body = component.renderRoot.querySelector( + '#email-body-content' + ) as HTMLElement; assert.equal(body.innerText, 'A basic intent body'); assert.equal(subject.innerText, 'A fake subject'); diff --git a/package.json b/package.json index 6abf9b38..6d1fdcb6 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ "coverage": ". cs-env/bin/activate; (npm run start-emulator > /dev/null 2>&1 &); sleep 3; curl --retry 4 http://localhost:15606/ --retry-connrefused; npm run do-coverage; npm run stop-emulator", "view-coverage": "pushd htmlcov/; python3.11 -m http.server 8080; popd", "mypy": ". cs-env/bin/activate; mypy --ignore-missing-imports --exclude cs-env/ --exclude appengine_config.py --exclude gen/py/chromestatus_openapi/build/ --exclude gen/py/chromestatus_openapi/test --exclude appengine_config.py --no-namespace-packages --disable-error-code \"annotation-unchecked\" .", - "lint": "prettier client-src/js-src client-src/elements --check && eslint \"client-src/js-src/**/*.{js,ts}\" \"client-src/elements/**/*.{js,ts}\" && tsc -p tsconfig.json && lit-analyzer \"client-src/elements/chromedash-!(featurelist)*.js\"", - "lint-fix": "prettier client-src/js-src client-src/elements --write && eslint \"client-src/js-src/**/*.{js,ts}\" \"client-src/elements/**/*.{js,ts}\" --fix", + "lint": "prettier client-src/js-src client-src/elements --check && eslint \"client-src/js-src/**/*.{js,ts}\" && tsc -p tsconfig.json && lit-analyzer \"client-src/elements/chromedash-!(featurelist)*.js\"", + "lint-fix": "prettier client-src/js-src client-src/elements --write && eslint \"client-src/js-src/**/*.{js,ts}\" --fix", "presubmit": "npm test && npm run webtest && npm run lint && npm run mypy", "pylint": "pylint --output-format=parseable *py api/*py framework/*py internals/*py pages/*py", "staging": "npm run clean-setup && npm run build && ./scripts/deploy_site.sh `git describe --always --abbrev=7 --match 'NOT A TAG' --dirty='-tainted'` cr-status-staging",