14738: Enhances code readability when concatenating strings.
[arvados.git] / apps / workbench / app / assets / javascripts / components / edit_tags.js
index dbbce15490afe859a1432405f67687030edbdc27..e7083b1451c004fd27985f4fce3f7ccd118c6f07 100644 (file)
@@ -18,11 +18,6 @@ window.SimpleInput = {
             },
         }, vnode.attrs.value)
     },
-    oncreate: function(vnode) {
-        if (vnode.attrs.setFocus) {
-            vnode.dom.focus()
-        }
-    }
 }
 
 window.SelectOrAutocomplete = {
@@ -37,17 +32,21 @@ window.SelectOrAutocomplete = {
         }, vnode.attrs.value)
     },
     oncreate: function(vnode) {
-        var awesomplete = new Awesomplete(vnode.dom, {
+        vnode.state.awesomplete = new Awesomplete(vnode.dom, {
             list: vnode.attrs.options,
             minChars: 0,
+            maxItems: 1000000,
             autoFirst: true,
+            sort: false,
         })
+        vnode.state.create = vnode.attrs.create
+        vnode.state.options = vnode.attrs.options
         // Option is selected from the list.
         $(vnode.dom).on('awesomplete-selectcomplete', function(event) {
             vnode.attrs.value(this.value)
         })
         $(vnode.dom).on('change', function(event) {
-            if (!vnode.attrs.create && !(this.value in vnode.attrs.options)) {
+            if (!vnode.state.create && !(this.value in vnode.state.options)) {
                 this.value = vnode.attrs.value()
             } else {
                 if (vnode.attrs.value() !== this.value) {
@@ -56,17 +55,17 @@ window.SelectOrAutocomplete = {
             }
         })
         $(vnode.dom).on('focusin', function(event) {
-            // Open list when focusing on empty strict fields
-            if (!vnode.attrs.create && this.value === '') {
-                // minChars = 0 && evaluate() makes the list open without
-                // input events
-                awesomplete.evaluate()
+            if (this.value === '') {
+                vnode.state.awesomplete.evaluate()
+                vnode.state.awesomplete.open()
             }
         })
-        if (vnode.attrs.setFocus) {
-            $(vnode.dom).focus()
-        }
-    }
+    },
+    onupdate: function(vnode) {
+        vnode.state.awesomplete.list = vnode.attrs.options
+        vnode.state.create = vnode.attrs.create
+        vnode.state.options = vnode.attrs.options
+    },
 }
 
 window.TagEditorRow = {
@@ -102,14 +101,13 @@ window.TagEditorRow = {
             // Tag key
             m("td", [
                 vnode.attrs.editMode ?
-                m("div", [
+                m("div", {key: 'key'}, [
                     m(inputComponent, {
                         options: nameOpts,
                         value: vnode.attrs.name,
                         // Allow any tag name unless "strict" is set to true.
                         create: !vnode.attrs.vocabulary().strict,
                         placeholder: 'key',
-                        setFocus: false
                     })
                 ])
                 : vnode.attrs.name
@@ -117,7 +115,7 @@ window.TagEditorRow = {
             // Tag value
             m("td", [
                 vnode.attrs.editMode ?
-                m("div", {key: 'value-'+vnode.attrs.name()}, [
+                m("div", {key: 'value'}, [
                     m(inputComponent, {
                         options: valueOpts,
                         value: vnode.attrs.value,
@@ -129,8 +127,6 @@ window.TagEditorRow = {
                             || !vnode.attrs.vocabulary().tags[vnode.attrs.name()].values
                             || vnode.attrs.vocabulary().tags[vnode.attrs.name()].values.length === 0
                             || !vnode.attrs.vocabulary().tags[vnode.attrs.name()].strict,
-                        // Focus on tag value field when new tag name is set
-                        setFocus: vnode.attrs.name() !== '' && vnode.attrs.value() === ''
                     })
                 ])
                 : vnode.attrs.value
@@ -158,7 +154,7 @@ window.TagEditorTable = {
                 vnode.attrs.tags.length > 0
                 ? vnode.attrs.tags.map(function(tag, idx) {
                     return m(TagEditorRow, {
-                        key: idx,
+                        key: tag.rowKey,
                         removeTag: function() {
                             vnode.attrs.tags.splice(idx, 1)
                             vnode.attrs.dirty(true)
@@ -175,37 +171,32 @@ window.TagEditorTable = {
     }
 }
 
+var uniqueID = 1
+
 window.TagEditorApp = {
     appendTag: function(vnode, name, value) {
-        var tag = {name: m.stream(name), value: m.stream(value)}
+        var tag = {name: m.stream(name), value: m.stream(value), rowKey: uniqueID++}
         vnode.state.tags.push(tag)
         // Set dirty flag when any of name/value changes to non empty string
-        tag.name.map(function(v) {
-            if (v !== '') {
-                vnode.state.dirty(true)
-            }
-        })
-        tag.value.map(function(v) {
-            if (v !== '') {
-                vnode.state.dirty(true)
-            }
-        })
+        tag.name.map(function() { vnode.state.dirty(true) })
+        tag.value.map(function() { vnode.state.dirty(true) })
         tag.name.map(m.redraw)
     },
     oninit: function(vnode) {
         vnode.state.sessionDB = new SessionDB()
         // Get vocabulary
         vnode.state.vocabulary = m.stream({"strict":false, "tags":{}})
-        m.request('/vocabulary.json').then(vnode.state.vocabulary)
+        var vocabularyTimestamp = parseInt(Date.now() / 300000) // Bust cache every 5 minutes
+        m.request('/vocabulary.json?v=' + vocabularyTimestamp).then(vnode.state.vocabulary)
         vnode.state.editMode = vnode.attrs.targetEditable
         vnode.state.tags = []
         vnode.state.dirty = m.stream(false)
         vnode.state.dirty.map(m.redraw)
-        vnode.state.objPath = '/arvados/v1/'+vnode.attrs.targetController+'/'+vnode.attrs.targetUuid
+        vnode.state.objPath = 'arvados/v1/' + vnode.attrs.targetController + '/' + vnode.attrs.targetUuid
         // Get tags
         vnode.state.sessionDB.request(
             vnode.state.sessionDB.loadLocal(),
-            '/arvados/v1/'+vnode.attrs.targetController,
+            'arvados/v1/' + vnode.attrs.targetController,
             {
                 data: {
                     filters: JSON.stringify([['uuid', '=', vnode.attrs.targetUuid]]),
@@ -217,6 +208,9 @@ window.TagEditorApp = {
                     Object.keys(o.properties).forEach(function(k) {
                         vnode.state.appendTag(vnode, k, o.properties[k])
                     })
+                    if (vnode.state.editMode) {
+                        vnode.state.appendTag(vnode, '', '')
+                    }
                     // Data synced with server, so dirty state should be false
                     vnode.state.dirty(false)
                     // Add new tag row when the last one is completed
@@ -235,14 +229,15 @@ window.TagEditorApp = {
         return [
             vnode.state.editMode &&
             m("div.pull-left", [
-                m("a.btn.btn-primary.btn-sm"+(vnode.state.dirty() ? '' : '.disabled'), {
+                m("a.btn.btn-primary.btn-sm" + (vnode.state.dirty() ? '' : '.disabled'), {
                     style: {
                         margin: '10px 0px'
                     },
                     onclick: function(e) {
                         var tags = {}
                         vnode.state.tags.forEach(function(t) {
-                            if (t.name() != '' && t.value() != '') {
+                            // Only ignore tags with empty key
+                            if (t.name() != '') {
                                 tags[t.name()] = t.value()
                             }
                         })
@@ -267,4 +262,4 @@ window.TagEditorApp = {
             })
         ]
     },
-}
\ No newline at end of file
+}