     (fn []
       [:div
        [notifications]
-       [:label "Search: "
-        [:input {:name "search",
-                 :type "search"
-                 :on-change (fn [e]
-                              (swap! app-state assoc :filter {:val (.-target.value e)
-                                                              :search (js->clj (.search index (.-target.value e)))}))}]]
-       [:a {:href (->> @app-state
-                       (util/state->document)
-                       (clj->js)
-                       (.stringify js/JSON)
-                       (.encodeURIComponent js/window)
-                       (str "data:text/json;charset=utf-8,"))
-            :download "warehouse_components.json"
-            }
-        [:button "Export"]]
-       [file-input "Import" (fn [e]
-                              (let [reader (js/FileReader.)
-                                    this (aget e "currentTarget")]
-                                (aset reader
-                                      "onload"
-                                      (fn [reader-event]
-                                        (->> (.-target.result reader-event)
-                                             (.parse js/JSON)
-                                             (#(js->clj % :keywordize-keys true))
-                                             (util/merge-documents (util/state->document @app-state))
-                                             (on-state-load))
-                                        (aset this "value" "")))
-                                (.readAsText reader (aget e "target" "files" "0"))))]
+       [search]
+       [export]
+       [import]
        (if (false? @adding)
          [:button {:on-click (fn [e]
                                (reset! adding true))} "Add new"])


(defn file-input [name f]
  [:button
  [:label
   [:input {:type "file"
            :on-change f}]
   name]])

(defmulti show-change-set (fn [change-set] (:type change-set)))

(defmethod show-change-set :create [change-set k]
  (def change-set-data (:data change-set))
  ^{:key k} [:ul.change-set
             (map (fn [component k]
                    ^{:key k} [:li.component

        :amount "Amount"}
       key))

(defn key->transformer [key]
  (if (= key :tags)
    #(util/array->string %)
    identity))

(defn property-view [data property]
  [:li
   [:span.label (str (key->label property) ": ")]
   [:span.value ((key->transformer property) (get data property))]])

(defn item-view [data editing]
  [:ul
   (property-view data :name)
   (property-view data :tags)
   (property-view data :amount)
   [:button {:on-click #(reset! editing true)} "Edit"]])

(defn item-edit-view [data editing k]
  (let [edited-item (atom (assoc data :tags (util/array->string (:tags data))))]
    [:form
     [form edited-item]
     [:button {:type "button"
               :on-click (fn []
                           (swap! app-state assoc-in [:components k]
                                  (assoc
                                    @edited-item
                                    :tags
                                    (util/string->array (:tags @edited-item))))
                           (reset! editing false))} "Save"]
     [:button {:type "button" :on-click #(reset! editing false)} "Cancel"]]))

(defn item [data k]
  (let [editing (atom false)]
    (fn [data k]
      [:div
       (if (false? @editing)
         (item-view data editing)
         (item-edit-view data editing k))])))

(defn get-visible-components []
  (if (clojure.string/blank? (get-in @app-state [:filter :val]))
