Browse Source

ref(js): Remove last usages of decorators (#38144)

Evan Purkhiser 2 years ago
parent
commit
f5d4cdeb0a
4 changed files with 41 additions and 71 deletions
  1. 0 4
      babel.config.ts
  2. 0 1
      package.json
  3. 37 30
      static/app/components/forms/model.tsx
  4. 4 36
      yarn.lock

+ 0 - 4
babel.config.ts

@@ -36,10 +36,6 @@ const config: TransformOptions = {
   plugins: [
     '@emotion/babel-plugin',
     '@babel/plugin-transform-runtime',
-    // NOTE: The order of the decorator and class-property plugins is important
-    // here. Decorators must be processed first before class properties, see:
-    // https://babeljs.io/docs/en/plugins#plugin-ordering
-    ['@babel/plugin-proposal-decorators', {legacy: true}],
     '@babel/plugin-proposal-class-properties',
   ],
   env: {

+ 0 - 1
package.json

@@ -8,7 +8,6 @@
   },
   "dependencies": {
     "@babel/core": "~7.18.5",
-    "@babel/plugin-proposal-decorators": "~7.18.2",
     "@babel/plugin-transform-react-jsx": "^7.17.12",
     "@babel/plugin-transform-runtime": "~7.18.5",
     "@babel/preset-env": "~7.18.2",

+ 37 - 30
static/app/components/forms/model.tsx

@@ -48,19 +48,19 @@ class FormModel {
    * Note we don't keep error in `this.fieldState` so that we can easily
    * See if the form is in an "error" state with the `isError` getter
    */
-  @observable errors = new Map();
+  errors = new Map();
 
   /**
    * State of individual fields
    *
    * Map of field name -> object
    */
-  @observable fieldState = new Map();
+  fieldState = new Map();
 
   /**
    * State of the form as a whole
    */
-  @observable formState: FormState | undefined;
+  formState: FormState | undefined;
 
   /**
    * Holds field properties as declared in <Form>
@@ -86,7 +86,40 @@ class FormModel {
   options: FormOptions;
 
   constructor({initialData, apiOptions, ...options}: OptionsWithInitial = {}) {
-    makeObservable(this);
+    makeObservable(this, {
+      fields: observable,
+      errors: observable,
+      fieldState: observable,
+      formState: observable,
+
+      isError: computed,
+      isSaving: computed,
+      formData: computed,
+      formChanged: computed,
+
+      resetForm: action,
+      setFieldDescriptor: action,
+      removeField: action,
+      setValue: action,
+      validateField: action,
+      updateShowSaveState: action,
+      updateShowReturnButtonState: action,
+      undo: action,
+      saveForm: action,
+      saveField: action,
+      saveFieldRequest: action,
+      handleBlurField: action,
+      setFormSaving: action,
+      handleSaveField: action,
+      handleCancelSaveField: action,
+      setFieldState: action,
+      setSaving: action,
+      setError: action,
+      validateForm: action,
+      handleErrorResponse: action,
+      submitSuccess: action,
+      submitError: action,
+    });
 
     this.options = options ?? {};
 
@@ -106,7 +139,6 @@ class FormModel {
     this.resetForm();
   }
 
-  @action
   resetForm() {
     this.fields.clear();
     this.errors.clear();
@@ -118,24 +150,20 @@ class FormModel {
   /**
    * Deep equality comparison between last saved state and current fields state
    */
-  @computed
   get formChanged() {
     return !isEqual(this.initialData, Object.fromEntries(this.fields.toJSON()));
   }
 
-  @computed
   get formData() {
     return this.fields;
   }
 
   /** Is form saving */
-  @computed
   get isSaving() {
     return this.formState === FormState.SAVING;
   }
 
   /** Does form have any errors */
-  @computed
   get isError() {
     return !!this.errors.size;
   }
@@ -162,7 +190,6 @@ class FormModel {
   /**
    * Set field properties
    */
-  @action
   setFieldDescriptor(id: string, props) {
     // TODO(TS): add type to props
     this.fieldDescriptor.set(id, props);
@@ -191,7 +218,6 @@ class FormModel {
   /**
    * Remove a field from the descriptor map and errors.
    */
-  @action
   removeField(id: string) {
     this.fieldDescriptor.delete(id);
     this.errors.delete(id);
@@ -304,7 +330,6 @@ class FormModel {
    * Set the value of the form field
    * if quiet is true, we skip callbacks, validations
    */
-  @action
   setValue(id: string, value: FieldValue, {quiet}: {quiet?: boolean} = {}) {
     const fieldDescriptor = this.fieldDescriptor.get(id);
     let finalValue = value;
@@ -327,7 +352,6 @@ class FormModel {
     this.updateShowReturnButtonState(id, finalValue);
   }
 
-  @action
   validateField(id: string) {
     const validate = this.getDescriptor(id, 'validate');
     let errors: any[] = [];
@@ -350,7 +374,6 @@ class FormModel {
     return undefined;
   }
 
-  @action
   updateShowSaveState(id: string, value: FieldValue) {
     const isValueChanged = value !== this.initialData[id];
     // Update field state to "show save" if save on blur is disabled for this field
@@ -366,7 +389,6 @@ class FormModel {
     this.setFieldState(id, 'showSave', isValueChanged);
   }
 
-  @action
   updateShowReturnButtonState(id: string, value: FieldValue) {
     const isValueChanged = value !== this.initialData[id];
     const shouldShowReturnButton = this.getDescriptor(id, 'showReturnButton');
@@ -385,7 +407,6 @@ class FormModel {
   /**
    * Changes form values to previous saved state
    */
-  @action
   undo() {
     // Always have initial data snapshot
     if (this.snapshots.length < 2) {
@@ -401,7 +422,6 @@ class FormModel {
   /**
    * Attempts to save entire form to server and saves a snapshot for undos
    */
-  @action
   saveForm() {
     if (!this.validateForm()) {
       return null;
@@ -446,7 +466,6 @@ class FormModel {
    * Calls submit handlers.
    * TODO(billy): This should return a promise that resolves (instead of null)
    */
-  @action
   saveField(id: string, currentValue: FieldValue) {
     const oldValue = this.initialData[id];
     const savePromise = this.saveFieldRequest(id, currentValue);
@@ -488,7 +507,6 @@ class FormModel {
    * If successful then: 1) reset save state, 2) update `initialData`, 3) save snapshot
    * If failed then: 1) reset save state, 2) add error state
    */
-  @action
   saveFieldRequest(id: string, currentValue: FieldValue) {
     const initialValue = this.initialData[id];
 
@@ -602,7 +620,6 @@ class FormModel {
    *
    * If `saveOnBlur` is set then call `saveField` and handle form callbacks accordingly
    */
-  @action
   handleBlurField(id: string, currentValue: FieldValue) {
     // Nothing to do if `saveOnBlur` is not on
     if (!this.options.saveOnBlur) {
@@ -618,7 +635,6 @@ class FormModel {
     return this.saveField(id, currentValue);
   }
 
-  @action
   setFormSaving() {
     this.formState = FormState.SAVING;
   }
@@ -626,7 +642,6 @@ class FormModel {
   /**
    * This is called when a field does not saveOnBlur and has an individual "Save" button
    */
-  @action
   handleSaveField(id: string, currentValue: FieldValue) {
     const savePromise = this.saveField(id, currentValue);
 
@@ -642,13 +657,11 @@ class FormModel {
   /**
    * Cancel "Save Field" state and revert form value back to initial value
    */
-  @action
   handleCancelSaveField(id: string) {
     this.setValue(id, this.initialData[id]);
     this.setFieldState(id, 'showSave', false);
   }
 
-  @action
   setFieldState(id: string, key: string, value: FieldValue) {
     const state = {
       ...(this.fieldState.get(id) || {}),
@@ -660,7 +673,6 @@ class FormModel {
   /**
    * Set "saving" state for field
    */
-  @action
   setSaving(id: string, value: FieldValue) {
     // When saving, reset error state
     this.setError(id, false);
@@ -671,7 +683,6 @@ class FormModel {
   /**
    * Set "error" state for field
    */
-  @action
   setError(id: string, error: boolean | string) {
     // Note we don't keep error in `this.fieldState` so that we can easily
     // See if the form is in an "error" state with the `isError` getter
@@ -690,14 +701,12 @@ class FormModel {
   /**
    * Returns true if there are no errors
    */
-  @action
   validateForm(): boolean {
     Array.from(this.fieldDescriptor.keys()).forEach(id => !this.validateField(id));
 
     return !this.isError;
   }
 
-  @action
   handleErrorResponse({responseJSON: resp}: {responseJSON?: any} = {}) {
     if (!resp) {
       return;
@@ -720,14 +729,12 @@ class FormModel {
     });
   }
 
-  @action
   submitSuccess(data: Record<string, FieldValue>) {
     // update initial data
     this.formState = FormState.READY;
     this.initialData = data;
   }
 
-  @action
   submitError(err: {responseJSON?: any}) {
     this.formState = FormState.ERROR;
     this.formErrors = this.mapFormErrors(err.responseJSON);

+ 4 - 36
yarn.lock

@@ -449,7 +449,7 @@
     "@babel/helper-plugin-utils" "^7.17.12"
     "@babel/plugin-syntax-class-static-block" "^7.14.5"
 
-"@babel/plugin-proposal-decorators@^7.12.12", "@babel/plugin-proposal-decorators@~7.18.2":
+"@babel/plugin-proposal-decorators@^7.12.12":
   version "7.18.2"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.2.tgz#dbe4086d2d42db489399783c3aa9272e9700afd4"
   integrity sha512-kbDISufFOxeczi0v4NQP3p5kIeW6izn/6klfWBrIIdGZZe4UpHR+QU03FAoWjGGd9SUXAwbw2pup1kaL4OQsJQ==
@@ -2253,7 +2253,7 @@
     "@sentry/utils" "7.11.0"
     tslib "^1.9.3"
 
-"@sentry/core@7.11.0":
+"@sentry/core@7.11.0", "@sentry/core@^7.7.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.11.0.tgz#c1ff437e77ce4e6047240a020dcec279a0be55a9"
   integrity sha512-W4/Klb5CbpH8C/bvRAsNx0w6I7XoIMf8US79aSAwykhQRrhGSo7bwKOk1dPEMbEg6jbNWDNeTGnZUeYrDNkpUw==
@@ -2263,16 +2263,6 @@
     "@sentry/utils" "7.11.0"
     tslib "^1.9.3"
 
-"@sentry/core@^7.7.0":
-  version "7.7.0"
-  resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.7.0.tgz#1a2d477897552d179380f7c54c7d81a4e98ea29a"
-  integrity sha512-Z15ACiuiFINFcK4gbMrnejLn4AVjKBPJOWKrrmpIe8mh+Y9diOuswt5mMUABs+jhpZvqht3PBLLGBL0WMsYMYA==
-  dependencies:
-    "@sentry/hub" "7.7.0"
-    "@sentry/types" "7.7.0"
-    "@sentry/utils" "7.7.0"
-    tslib "^1.9.3"
-
 "@sentry/hub@7.11.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.11.0.tgz#94801dfc5b07660a463a3eeb66b2bc210d4cb10b"
@@ -2282,15 +2272,6 @@
     "@sentry/utils" "7.11.0"
     tslib "^1.9.3"
 
-"@sentry/hub@7.7.0":
-  version "7.7.0"
-  resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.7.0.tgz#9ad3471cf5ecaf1a9d3a3a04ca2515ffec9e2c09"
-  integrity sha512-6gydK234+a0nKhBRDdIJ7Dp42CaiW2juTiHegUVDq+482balVzbZyEAmESCmuzKJhx5BhlCElVxs/cci1NjMpg==
-  dependencies:
-    "@sentry/types" "7.7.0"
-    "@sentry/utils" "7.7.0"
-    tslib "^1.9.3"
-
 "@sentry/integrations@7.11.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.11.0.tgz#dce90d546c681ce9ba32c083777e51eb5bfc9869"
@@ -2352,17 +2333,12 @@
     "@sentry/utils" "7.11.0"
     tslib "^1.9.3"
 
-"@sentry/types@7.11.0":
+"@sentry/types@7.11.0", "@sentry/types@^7.7.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.11.0.tgz#d66101924f8a5f0c347f448dd34bb9d7aa84ae41"
   integrity sha512-0xhfH9nHi68fstZpEGBS/q7a4hRRb99shh2EmP6KSM+eGkjLsr89XXBoI0NZzoHDsu0WsM9Ygpdu9wuXXBJ8CQ==
 
-"@sentry/types@7.7.0", "@sentry/types@^7.7.0":
-  version "7.7.0"
-  resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.7.0.tgz#dd6bd3d119d7efea0e85dbaa4b17de1c22b63c7a"
-  integrity sha512-4x8O7uerSGLnYC10krHl9t8h7xXHn5FextqKYbTCXCnx2hC8D+9lz8wcbQAFo0d97wiUYqI8opmEgFVGx7c5hQ==
-
-"@sentry/utils@7.11.0":
+"@sentry/utils@7.11.0", "@sentry/utils@^7.7.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.11.0.tgz#41ae6d0644d7e00b7f302f02e81296a3d49d97d6"
   integrity sha512-c24q0JGxphvrwHQ7TJNH30bmLzGc3VeD8idtM5pcakmrZbOtXtL+HGoLIxd6YAyNNh3frKdqFHJnaQ3lN6gv3g==
@@ -2370,14 +2346,6 @@
     "@sentry/types" "7.11.0"
     tslib "^1.9.3"
 
-"@sentry/utils@7.7.0", "@sentry/utils@^7.7.0":
-  version "7.7.0"
-  resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.7.0.tgz#013e3097c4268a76de578494c7df999635fb0ad4"
-  integrity sha512-fD+ROSFpeJlK7bEvUT2LOW7QqgjBpXJwVISKZ0P2fuzclRC3KoB2pbZgBM4PXMMTiSzRGWhvfRRjBiBvQJBBJQ==
-  dependencies:
-    "@sentry/types" "7.7.0"
-    tslib "^1.9.3"
-
 "@sinclair/typebox@^0.23.3":
   version "0.23.5"
   resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d"