1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 window.SelectOrAutocomplete = {
6 view: function(vnode) {
12 value: vnode.attrs.value
15 oncreate: function(vnode) {
16 $(vnode.dom).selectize({
22 create: vnode.attrs.create ? function(input) {
25 items: [vnode.attrs.value()],
26 options: vnode.attrs.options.map(function(option) {
27 return {value: option}
29 onChange: function(val) {
30 vnode.attrs.value(val)
36 window.TagEditorRow = {
37 view: function(vnode) {
40 if (vnode.attrs.name() in vnode.attrs.vocabulary().types &&
41 'options' in vnode.attrs.vocabulary().types[vnode.attrs.name()]) {
42 valueOpts = vnode.attrs.vocabulary().types[vnode.attrs.name()].options
44 valueOpts.push(vnode.attrs.value())
49 vnode.attrs.editMode &&
50 m('div.text-center', m('a.btn.btn-default.btn-sm', {
54 onclick: function(e) { vnode.attrs.removeTag() }
55 }, m('i.fa.fa-fw.fa-trash-o'))),
59 vnode.attrs.editMode ?
60 m("div", {key: 'name-'+vnode.attrs.name()},[m(SelectOrAutocomplete, {
61 options: (vnode.attrs.name() in vnode.attrs.vocabulary().types)
62 ? Object.keys(vnode.attrs.vocabulary().types)
63 : Object.keys(vnode.attrs.vocabulary().types).concat(vnode.attrs.name()),
64 value: vnode.attrs.name,
65 create: vnode.attrs.vocabulary().strict
70 vnode.attrs.editMode ?
71 m("div", {key: 'value-'+vnode.attrs.name()}, [m(SelectOrAutocomplete, {
73 value: vnode.attrs.value,
74 create: (vnode.attrs.name() in vnode.attrs.vocabulary().types)
75 ? (vnode.attrs.vocabulary().types[vnode.attrs.name()].type == 'text') ||
76 vnode.attrs.vocabulary().types[vnode.attrs.name()].overridable || false
77 : true, // If tag not in vocabulary, we should accept any value
85 window.TagEditorTable = {
86 view: function(vnode) {
87 return m("table.table.table-condensed", {
91 m("col", {width:"5%"}),
92 m("col", {width:"25%"}),
93 m("col", {width:"70%"}),
103 vnode.attrs.tags.length > 0
104 ? vnode.attrs.tags.map(function(tag, idx) {
105 return m(TagEditorRow, {
107 removeTag: function() {
108 vnode.attrs.tags.splice(idx, 1)
109 vnode.attrs.dirty(true)
111 editMode: vnode.attrs.editMode,
114 vocabulary: vnode.attrs.vocabulary
117 : m("tr", m("td[colspan=3]", m("center","(no tags)")))
123 window.TagEditorApp = {
124 appendTag: function(vnode, name, value) {
125 var tag = {name: m.stream(name), value: m.stream(value)}
126 tag.name.map(vnode.state.dirty)
127 tag.value.map(vnode.state.dirty)
128 tag.name.map(m.redraw)
129 vnode.state.tags.push(tag)
131 oninit: function(vnode) {
132 vnode.state.sessionDB = new SessionDB()
134 vnode.state.vocabulary = m.stream({"strict":false, "types":{}})
135 m.request('/vocabulary.json').then(vnode.state.vocabulary)
136 vnode.state.editMode = vnode.attrs.targetEditable
137 vnode.state.tags = []
138 vnode.state.dirty = m.stream(false)
139 vnode.state.dirty.map(m.redraw)
140 vnode.state.objPath = '/arvados/v1/'+vnode.attrs.targetController+'/'+vnode.attrs.targetUuid
142 vnode.state.sessionDB.request(
143 vnode.state.sessionDB.loadLocal(),
144 '/arvados/v1/'+vnode.attrs.targetController,
147 filters: JSON.stringify([['uuid', '=', vnode.attrs.targetUuid]]),
148 select: JSON.stringify(['properties'])
150 }).then(function(obj) {
151 if (obj.items.length == 1) {
153 Object.keys(o.properties).forEach(function(k) {
154 vnode.state.appendTag(vnode, k, o.properties[k])
156 // Data synced with server, so dirty state should be false
157 vnode.state.dirty(false)
162 view: function(vnode) {
164 vnode.state.editMode &&
166 m("a.btn.btn-primary.btn-sm"+(vnode.state.dirty() ? '' : '.disabled'), {
170 onclick: function(e) {
172 vnode.state.tags.forEach(function(t) {
173 tags[t.name()] = t.value()
175 vnode.state.sessionDB.request(
176 vnode.state.sessionDB.loadLocal(),
177 vnode.state.objPath, {
179 data: {properties: JSON.stringify(tags)}
182 vnode.state.dirty(false)
185 }, vnode.state.dirty() ? ' Save changes ' : ' Saved ')
189 editMode: vnode.state.editMode,
190 tags: vnode.state.tags,
191 vocabulary: vnode.state.vocabulary,
192 dirty: vnode.state.dirty
194 vnode.state.editMode &&
197 m("a.btn.btn-primary.btn-sm", {
198 onclick: function(e) {
199 vnode.state.appendTag(vnode, 'new tag', 'new value')
202 m("i.glyphicon.glyphicon-plus"),