浏览代码

[ui] Vue 3 - Migrated VariableSubstitution components

sreenaths 4 年之前
父节点
当前提交
39d087bc1c

+ 131 - 108
desktop/core/src/desktop/js/apps/editor/components/variableSubstitution/VariableSubstitution.vue

@@ -32,13 +32,11 @@
 </template>
 
 <script lang="ts">
+  import { defineComponent, PropType } from 'vue';
+
   import { cloneDeep } from 'lodash';
-  import Vue from 'vue';
-  import Component from 'vue-class-component';
-  import { Prop, Watch } from 'vue-property-decorator';
 
   import { Variable, VariableIndex, VariableOption } from './types';
-  import './VariableSubstitution.scss';
   import { IdentifierLocation } from 'parse/types';
   import DataCatalogEntry, { FieldSourceMeta } from 'catalog/DataCatalogEntry';
   import { noop } from 'utils/hueUtils';
@@ -117,124 +115,149 @@
     } catch (err) {}
   };
 
-  @Component
-  export default class VariableSubstitution extends Vue {
-    @Prop({ required: false, default: {} })
-    initialVariables?: { [name: string]: Variable };
-    @Prop()
-    locations?: IdentifierLocation[];
+  export default defineComponent({
+    props: {
+      initialVariables: {
+        type: Object as PropType<{ [name: string]: Variable }>,
+        required: false,
+        default: {}
+      },
+      locations: {
+        type: Object as PropType<IdentifierLocation[]>,
+        required: false,
+        default: undefined
+      }
+    },
 
-    knownVariables: { [name: string]: KnownVariable } = {};
+    emits: ['variables-changed'],
 
-    get activeVariables(): Variable[] {
-      const active = Object.values(this.knownVariables).filter(variable => variable.active);
-      active.sort((a, b) => a.index - b.index);
-      return active;
-    }
+    data(): {
+      knownVariables: { [name: string]: KnownVariable };
+    } {
+      return {
+        knownVariables: {}
+      };
+    },
 
-    mounted(): void {
-      if (this.initialVariables) {
-        Object.values(this.initialVariables).forEach((variable, index) => {
-          const cloned = <KnownVariable>cloneDeep(variable);
-          cloned.active = true;
-          cloned.index = index;
-          this.$set(this.knownVariables, cloned.name, cloned);
-        });
+    computed: {
+      activeVariables(): Variable[] {
+        const active = Object.values(this.knownVariables).filter(variable => variable.active);
+        active.sort((a, b) => a.index - b.index);
+        return active;
       }
-    }
+    },
 
-    @Watch('activeVariables')
-    notifyVariableChange(): void {
-      this.$emit(
-        'variables-changed',
-        this.activeVariables.reduce((result, variable) => {
-          result[variable.name] = variable;
-          return result;
-        }, <VariableIndex>{})
-      );
-    }
+    watch: {
+      activeVariables(): void {
+        this.$emit(
+          'variables-changed',
+          this.activeVariables.reduce((result, variable) => {
+            result[variable.name] = variable;
+            return result;
+          }, <VariableIndex>{})
+        );
+      },
+      locations(locations?: IdentifierLocation[]): void {
+        const toDeactivate = new Set<string>(Object.keys(this.knownVariables));
 
-    @Watch('locations', { immediate: true })
-    updateFromLocations(locations?: IdentifierLocation[]): void {
-      const toDeactivate = new Set<string>(Object.keys(this.knownVariables));
-
-      if (locations) {
-        locations
-          .filter(location => location.type === 'variable' && location.value)
-          .forEach(location => {
-            const match = location.value && location.value.match(LOCATION_VALUE_REGEX);
-            if (!match) {
-              return;
-            }
-
-            const name = match[1];
-            let variable = this.knownVariables[name];
-            if (variable) {
-              toDeactivate.delete(variable.name);
-              if (!variable.active) {
-                this.$set(variable, 'active', true);
+        if (locations) {
+          locations
+            .filter(location => location.type === 'variable' && location.value)
+            .forEach(location => {
+              const match = location.value && location.value.match(LOCATION_VALUE_REGEX);
+              if (!match) {
+                return;
               }
-            } else {
-              variable = {
-                meta: { type: 'text', placeholder: '', options: [] },
-                sample: [],
-                sampleUser: [],
-                step: '',
-                type: 'text',
-                value: '',
-                name: name,
-                active: true,
-                index: Object.keys(this.knownVariables).length + 1
-              };
-              this.$set(this.knownVariables, name, variable);
-            }
-
-            // Case for ${name=1} or ${name=a,b,c}
-            if (match[2]) {
-              const optionStrings = match[2].split(',');
-
-              // When it's just one option it's a placeholder only
-              if (optionStrings.length === 1) {
-                const option = parseOption(optionStrings[0]);
-                if (variable.meta.placeholder !== option.value) {
-                  this.$set(variable.meta, 'placeholder', option.value);
+
+              const name = match[1];
+              let variable = this.knownVariables[name];
+              if (variable) {
+                toDeactivate.delete(variable.name);
+                if (!variable.active) {
+                  variable.active = true;
+                  this.$forceUpdate();
                 }
-                variable.meta.options = [];
               } else {
-                variable.type = 'select';
-                variable.meta.placeholder = '';
-                variable.meta.options = optionStrings.map(parseOption);
+                variable = {
+                  meta: { type: 'text', placeholder: '', options: [] },
+                  sample: [],
+                  sampleUser: [],
+                  step: '',
+                  type: 'text',
+                  value: '',
+                  name: name,
+                  active: true,
+                  index: Object.keys(this.knownVariables).length + 1
+                };
+                this.knownVariables[name] = variable;
+                this.$forceUpdate();
               }
-            } else {
-              if (variable.type === 'select') {
-                // Revert to last known type if options are removed
-                if (variable.catalogEntry) {
-                  updateFromDataCatalog(variable, variable.catalogEntry);
+
+              // Case for ${name=1} or ${name=a,b,c}
+              if (match[2]) {
+                const optionStrings = match[2].split(',');
+
+                // When it's just one option it's a placeholder only
+                if (optionStrings.length === 1) {
+                  const option = parseOption(optionStrings[0]);
+                  if (variable.meta.placeholder !== option.value) {
+                    variable.meta.placeholder = option.value;
+                    this.$forceUpdate();
+                  }
+                  variable.meta.options = [];
                 } else {
-                  variable.type = 'text';
+                  variable.type = 'select';
+                  variable.meta.placeholder = '';
+                  variable.meta.options = optionStrings.map(parseOption);
+                }
+              } else {
+                if (variable.type === 'select') {
+                  // Revert to last known type if options are removed
+                  if (variable.catalogEntry) {
+                    updateFromDataCatalog(variable, variable.catalogEntry);
+                  } else {
+                    variable.type = 'text';
+                  }
                 }
+                variable.meta.placeholder = '';
+                variable.meta.options = [];
               }
-              variable.meta.placeholder = '';
-              variable.meta.options = [];
-            }
-
-            if (location.colRef && location.resolveCatalogEntry) {
-              location
-                .resolveCatalogEntry()
-                .then(async entry => {
-                  await updateFromDataCatalog(variable, entry);
-                })
-                .catch(noop);
-            }
-          });
-      }
 
-      toDeactivate.forEach(name => {
-        const variable = this.knownVariables[name];
-        if (variable) {
-          this.$set(variable, 'active', false);
+              if (location.colRef && location.resolveCatalogEntry) {
+                location
+                  .resolveCatalogEntry()
+                  .then(async entry => {
+                    await updateFromDataCatalog(variable, entry);
+                  })
+                  .catch(noop);
+              }
+            });
         }
-      });
+
+        toDeactivate.forEach(name => {
+          const variable = this.knownVariables[name];
+          if (variable) {
+            variable.active = false;
+            this.$forceUpdate();
+          }
+        });
+      }
+    },
+
+    mounted(): void {
+      if (this.initialVariables) {
+        Object.values(this.initialVariables).forEach((variable, index) => {
+          const cloned = <KnownVariable>cloneDeep(variable);
+          cloned.active = true;
+          cloned.index = index;
+          this.knownVariables[cloned.name] = cloned;
+          this.$forceUpdate();
+        });
+      }
     }
-  }
+  });
 </script>
+
+<style lang="scss">
+  @import './VariableSubstitution.scss';
+</style>

+ 38 - 18
desktop/core/src/desktop/js/apps/editor/components/variableSubstitution/VariableSubstitutionKoBridge.vue

@@ -26,10 +26,9 @@
 </template>
 
 <script lang="ts">
-  import Vue from 'vue';
-  import Component from 'vue-class-component';
-  import { Prop } from 'vue-property-decorator';
-  import { wrap } from 'vue/webComponentWrapper';
+  import { defineComponent, PropType } from 'vue';
+
+  import { wrap } from 'vue/webComponentWrap';
 
   import { Variable } from './types';
   import VariableSubstitution from './VariableSubstitution.vue';
@@ -37,16 +36,33 @@
   import { IdentifierLocation } from 'parse/types';
   import { POST_FROM_LOCATION_WORKER_EVENT } from 'sql/sqlWorkerHandler';
 
-  @Component({
-    components: { VariableSubstitution }
-  })
-  export default class VariableSubstitutionKoBridge extends Vue {
-    @Prop()
-    initialVariables?: Variable[];
+  const VariableSubstitutionKoBridge = defineComponent({
+    components: {
+      VariableSubstitution
+    },
+
+    props: {
+      initialVariables: {
+        type: Object as PropType<Variable[]>,
+        default: undefined
+      }
+    },
 
-    locations: IdentifierLocation[] = [];
+    setup(): {
+      subTracker: SubscriptionTracker;
+    } {
+      return {
+        subTracker: new SubscriptionTracker()
+      };
+    },
 
-    subTracker = new SubscriptionTracker();
+    data(): {
+      locations: IdentifierLocation[];
+    } {
+      return {
+        locations: []
+      };
+    },
 
     mounted(): void {
       this.subTracker.subscribe(
@@ -57,15 +73,19 @@
           }
         }
       );
-    }
+    },
 
-    onVariablesChanged(variables: Variable[]): void {
-      this.$el.dispatchEvent(
-        new CustomEvent<Variable[]>('variables-changed', { bubbles: true, detail: variables })
-      );
+    methods: {
+      onVariablesChanged(variables: Variable[]): void {
+        this.$el.dispatchEvent(
+          new CustomEvent<Variable[]>('variables-changed', { bubbles: true, detail: variables })
+        );
+      }
     }
-  }
+  });
 
   export const COMPONENT_NAME = 'variable-substitution-ko-bridge';
   wrap(COMPONENT_NAME, VariableSubstitutionKoBridge);
+
+  export default VariableSubstitutionKoBridge;
 </script>