mirror of
https://github.com/logseq/logseq.git
synced 2026-05-28 14:39:48 +00:00
Merge 'master' into enhance/i18n
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
[frontend.components.settings :as settings]
|
||||
[frontend.components.svg :as svg]
|
||||
[frontend.config :as config]
|
||||
[frontend.context.i18n :refer [t]]
|
||||
[frontend.context.i18n :as i18n :refer [t]]
|
||||
[frontend.db :as db]
|
||||
[frontend.handler :as handler]
|
||||
[frontend.handler.db-based.rtc-flows :as rtc-flows]
|
||||
@@ -351,11 +351,25 @@
|
||||
(ldb/page? page) (:block/parent page))
|
||||
[:div.ls-block-breadcrumb
|
||||
[:div.text-sm
|
||||
(component-block/breadcrumb {}
|
||||
(component-block/breadcrumb {}
|
||||
(state/get-current-repo)
|
||||
(:block/uuid page)
|
||||
{:header? true})]])))
|
||||
|
||||
(rum/defc search-index-progress < rum/reactive
|
||||
[]
|
||||
(let [current-repo (state/get-current-repo)
|
||||
{:keys [running? repo progress]} (or (state/sub :search/index-build) {})
|
||||
progress' (-> (or progress 0)
|
||||
(max 0)
|
||||
(min 100))]
|
||||
(when (and running? (= repo current-repo))
|
||||
[:div.search-index-progress
|
||||
[ui/loading ""]
|
||||
[:span.search-index-progress__text (t :search/index-progress progress')]
|
||||
[:div.search-index-progress__bar
|
||||
[:div.search-index-progress__bar-fill {:style {:width (str progress' "%")}}]]])))
|
||||
|
||||
(rum/defc ^:large-vars/cleanup-todo header-aux < rum/reactive
|
||||
[{:keys [current-repo default-home new-block-mode]}]
|
||||
(let [electron-mac? (and util/mac? (util/electron?))
|
||||
@@ -419,6 +433,7 @@
|
||||
(rtc-indicator/downloading-detail))
|
||||
(when (user-handler/logged-in?)
|
||||
(rtc-indicator/uploading-detail))
|
||||
(search-index-progress)
|
||||
|
||||
(when (and (not= (state/get-current-route) :home)
|
||||
(not custom-home-page?))
|
||||
|
||||
@@ -341,4 +341,24 @@ html.is-zoomed-native-ios {
|
||||
max-width: 34ch;
|
||||
}
|
||||
}
|
||||
|
||||
.search-index-progress {
|
||||
@apply flex items-center gap-2 rounded px-2 py-1 text-xs opacity-90;
|
||||
-webkit-app-region: no-drag;
|
||||
background-color: var(--ls-tertiary-background-color);
|
||||
}
|
||||
|
||||
.search-index-progress__text {
|
||||
@apply whitespace-nowrap;
|
||||
}
|
||||
|
||||
.search-index-progress__bar {
|
||||
@apply h-1 w-16 overflow-hidden rounded;
|
||||
background-color: var(--ls-quaternary-background-color);
|
||||
}
|
||||
|
||||
.search-index-progress__bar-fill {
|
||||
@apply h-full transition-all duration-200;
|
||||
background-color: var(--ls-link-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,7 +1034,7 @@
|
||||
(ui/icon "alert-triangle")]]
|
||||
[:div.mt-3.text-center.sm:mt-0.sm:ml-4.sm:text-left
|
||||
[:h3#modal-headline.text-lg.leading-6.font-medium
|
||||
(t :page.delete/confirm-title)]]]
|
||||
(t :page.delete/batch-confirm-title)]]]
|
||||
|
||||
[:ol.p-2.pt-4
|
||||
(for [page-item pages]
|
||||
|
||||
@@ -72,7 +72,9 @@
|
||||
{:title [:h3.text-lg.leading-6.font-medium.flex.gap-2.items-center
|
||||
[:span.top-1.relative
|
||||
(shui/tabler-icon "alert-triangle")]
|
||||
(t :page.delete/confirm-title)]
|
||||
(if (or (ldb/class? page) (ldb/property? page))
|
||||
(t :page.delete/permanent-confirm-title)
|
||||
(t :page.delete/confirm-title))]
|
||||
:content [:p.opacity-60 (str "- " (:block/title page))]
|
||||
:outside-cancel? true
|
||||
:cancel-label (t :ui/cancel)
|
||||
|
||||
@@ -1597,9 +1597,10 @@
|
||||
[:pre (pr-str opts)]))
|
||||
|
||||
(rum/defc renderer-resolver < rum/static
|
||||
[key']
|
||||
(when-let [[pid key] (some-> key' (string/split "."))]
|
||||
(let [[renderer set-renderer!] (rum/use-state nil)]
|
||||
[nskey']
|
||||
(when-let [pid (some-> nskey' (namespace))]
|
||||
(let [key (name nskey')
|
||||
[renderer set-renderer!] (rum/use-state nil)]
|
||||
|
||||
(hooks/use-effect!
|
||||
(fn []
|
||||
@@ -1607,10 +1608,10 @@
|
||||
(when-let [renderer (plugin-handler/resolve-hosted-render pid key :sidebar)]
|
||||
(let [r (bean/->clj renderer)
|
||||
title (:title r)]
|
||||
(when-let [^js dom (and title (js/document.getElementById key'))]
|
||||
(when-let [^js dom (and title (js/document.getElementById nskey'))]
|
||||
(set! (. dom -textContent) title))
|
||||
(set-renderer! r)))
|
||||
(catch js/Error e (js/console.error "Failed to resolve renderer:" key' e))))
|
||||
(catch js/Error e (js/console.error "Failed to resolve renderer:" nskey' e))))
|
||||
[pid key])
|
||||
|
||||
(when renderer
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.route :as route-handler]
|
||||
[frontend.handler.ui :as ui-handler]
|
||||
[frontend.handler.plugin :as plugin-handler]
|
||||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.undo-redo.debug-ui :as undo-redo-debug-ui]
|
||||
@@ -432,6 +433,20 @@
|
||||
:tabIndex "0"
|
||||
:data-expanded sidebar-open?}]))
|
||||
|
||||
(rum/defc plugin-renderer-menu-items
|
||||
[renderers]
|
||||
(for [r renderers]
|
||||
(shui/dropdown-menu-item
|
||||
{:on-click #(state/sidebar-add-block!
|
||||
(state/get-current-repo)
|
||||
(keyword (:pid r) (:key r))
|
||||
:plugin
|
||||
)}
|
||||
[:div.flex.items-center
|
||||
{:title (str (:pid r))}
|
||||
[:span.pr-1.flex.items-center (shui/tabler-icon "puzzle")]
|
||||
[:strong (:title r)]])))
|
||||
|
||||
(rum/defcs sidebar-inner <
|
||||
(rum/local false ::anim-finished?)
|
||||
{:will-mount (fn [state]
|
||||
@@ -446,7 +461,21 @@
|
||||
[:div.cp__right-sidebar-scrollable
|
||||
{:on-drag-over util/stop}
|
||||
[:div.cp__right-sidebar-topbar.flex.flex-row.justify-between.items-center
|
||||
[:div.cp__right-sidebar-settings.hide-scrollbar.gap-0 {:key "right-sidebar-settings"}
|
||||
[:div.cp__right-sidebar-settings.hide-scrollbar.gap-1 {:key "right-sidebar-settings"}
|
||||
;; sidebar renderers from plugins
|
||||
(when-let [renderers (and config/lsp-enabled?
|
||||
(some->> (plugin-handler/get-hosted-renderers)
|
||||
(filter #(= (:type %) "sidebar"))
|
||||
(seq)))]
|
||||
[:div.text-sm
|
||||
[:button.button.cp__right-sidebar-settings-btn
|
||||
{:on-click (fn [e]
|
||||
(shui/popup-show! e
|
||||
(plugin-renderer-menu-items renderers)
|
||||
{:as-dropdown? true
|
||||
:content-props {:on-click (fn [] (shui/popup-hide!))}}))}
|
||||
[:span.nu.flex.items-center.opacity-80 (shui/tabler-icon "cube-plus")]]])
|
||||
|
||||
[:div.text-sm
|
||||
[:button.button.cp__right-sidebar-settings-btn {:on-click (fn [_e]
|
||||
(state/sidebar-add-block! repo "contents" :contents))}
|
||||
|
||||
@@ -63,6 +63,12 @@
|
||||
[error]
|
||||
(string/includes? (or (ex-message error) (str error)) "decrypt-aes-key"))
|
||||
|
||||
(defn- <build-search-index!
|
||||
[repo]
|
||||
(-> (state/<invoke-db-worker :thread-api/search-build-blocks-indice-in-worker repo)
|
||||
(p/catch (fn [error]
|
||||
(js/console.error "Search index build error:" error)))))
|
||||
|
||||
(defn- schedule-search-index-build!
|
||||
[repo]
|
||||
(when-let [timeout-id @*search-index-build-timeout]
|
||||
@@ -77,9 +83,7 @@
|
||||
(state/input-idle? repo :diff 5000)
|
||||
(do
|
||||
(reset! *search-index-build-timeout nil)
|
||||
(-> (state/<invoke-db-worker :thread-api/search-build-blocks-indice-in-worker repo)
|
||||
(p/catch (fn [error]
|
||||
(js/console.error "Search index build error:" error)))))
|
||||
(<build-search-index! repo))
|
||||
|
||||
:else
|
||||
(schedule-search-index-build! repo)))
|
||||
@@ -111,7 +115,7 @@
|
||||
(p/do!
|
||||
(p/delay 5000)
|
||||
(p/let [repo (state/get-current-repo)
|
||||
_ (state/<invoke-db-worker :thread-api/search-build-blocks-indice-in-worker repo)]
|
||||
_ (<build-search-index! repo)]
|
||||
(when state/lsp-enabled?
|
||||
(doseq [service (state/get-all-plugin-services-with-type :search)]
|
||||
(search-plugin/call-service! service "search:rebuildPagesIndice" {})
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
(uuid? x) (str x)
|
||||
:else x)) input))))
|
||||
|
||||
(defn- normalize-user-key-without-ns
|
||||
[k]
|
||||
(some-> k (name)
|
||||
(string/replace "/" "$")
|
||||
(string/replace " " "_")
|
||||
(string/replace #"^[:_\s]+" "")))
|
||||
|
||||
(defn invoke-exported-api
|
||||
[type & args]
|
||||
(try
|
||||
@@ -528,7 +535,7 @@
|
||||
(defn- create-local-renderer-register
|
||||
[type *providers]
|
||||
(fn [pid key {subs' :subs :keys [render] :as opts}]
|
||||
(when-let [key (and key (keyword key))]
|
||||
(when-let [key (some-> key (normalize-user-key-without-ns) (keyword))]
|
||||
(register-plugin-resources pid type
|
||||
(merge opts {:key key :subs subs' :render render}))
|
||||
(swap! *providers conj pid)
|
||||
@@ -539,7 +546,7 @@
|
||||
([type *providers many?]
|
||||
(fn [key]
|
||||
(when (seq @*providers)
|
||||
(if key
|
||||
(if-let [key (some-> key (normalize-user-key-without-ns) (keyword))]
|
||||
(when-let [rs (->> @*providers
|
||||
(map (fn [pid] (state/get-plugin-resource pid type key)))
|
||||
(remove nil?)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns frontend.modules.outliner.op
|
||||
"Build outliner ops"
|
||||
(:require [datascript.impl.entity :as de]
|
||||
[frontend.db.utils :as db-utils]
|
||||
[frontend.handler.user :as user-handler]))
|
||||
|
||||
(defn- current-user-delete-opts
|
||||
@@ -30,9 +31,21 @@
|
||||
(map? block-or-id)
|
||||
(:block/uuid block-or-id)
|
||||
|
||||
(number? block-or-id)
|
||||
(:block/uuid (db-utils/entity block-or-id))
|
||||
|
||||
:else
|
||||
block-or-id))
|
||||
|
||||
(defn- ->property-id
|
||||
[property-id]
|
||||
(cond
|
||||
(number? property-id)
|
||||
(:db/ident (db-utils/entity property-id))
|
||||
|
||||
:else
|
||||
property-id))
|
||||
|
||||
(defn save-block!
|
||||
[block & {:as opts}]
|
||||
(op-transact!
|
||||
@@ -83,67 +96,67 @@
|
||||
(defn upsert-property!
|
||||
[property-id schema property-opts]
|
||||
(op-transact!
|
||||
[:upsert-property [property-id schema property-opts]]))
|
||||
[:upsert-property [(->property-id property-id) schema property-opts]]))
|
||||
|
||||
(defn set-block-property!
|
||||
[block-eid property-id value]
|
||||
(op-transact!
|
||||
[:set-block-property [(->block-id block-eid) property-id value]]))
|
||||
[:set-block-property [(->block-id block-eid) (->property-id property-id) value]]))
|
||||
|
||||
(defn remove-block-property!
|
||||
[block-eid property-id]
|
||||
(op-transact!
|
||||
[:remove-block-property [(->block-id block-eid) property-id]]))
|
||||
[:remove-block-property [(->block-id block-eid) (->property-id property-id)]]))
|
||||
|
||||
(defn delete-property-value!
|
||||
[block-eid property-id property-value]
|
||||
(op-transact!
|
||||
[:delete-property-value [(->block-id block-eid) property-id property-value]]))
|
||||
[:delete-property-value [(->block-id block-eid) (->property-id property-id) property-value]]))
|
||||
|
||||
(defn batch-delete-property-value!
|
||||
[block-eids property-id property-value]
|
||||
(op-transact!
|
||||
[:batch-delete-property-value [(mapv ->block-id block-eids) property-id property-value]]))
|
||||
[:batch-delete-property-value [(mapv ->block-id block-eids) (->property-id property-id) property-value]]))
|
||||
|
||||
(defn create-property-text-block!
|
||||
[block-id property-id value opts]
|
||||
(op-transact!
|
||||
[:create-property-text-block [(->block-id block-id) property-id value opts]]))
|
||||
[:create-property-text-block [(->block-id block-id) (->property-id property-id) value opts]]))
|
||||
|
||||
(defn batch-set-property!
|
||||
[block-ids property-id value opts]
|
||||
(op-transact!
|
||||
[:batch-set-property [(mapv ->block-id block-ids) property-id value opts]]))
|
||||
[:batch-set-property [(mapv ->block-id block-ids) (->property-id property-id) value opts]]))
|
||||
|
||||
(defn batch-remove-property!
|
||||
[block-ids property-id]
|
||||
(op-transact!
|
||||
[:batch-remove-property [(mapv ->block-id block-ids) property-id]]))
|
||||
[:batch-remove-property [(mapv ->block-id block-ids) (->property-id property-id)]]))
|
||||
|
||||
(defn class-add-property!
|
||||
[class-id property-id]
|
||||
(op-transact!
|
||||
[:class-add-property [(->block-id class-id) property-id]]))
|
||||
[:class-add-property [(->block-id class-id) (->property-id property-id)]]))
|
||||
|
||||
(defn class-remove-property!
|
||||
[class-id property-id]
|
||||
(op-transact!
|
||||
[:class-remove-property [(->block-id class-id) property-id]]))
|
||||
[:class-remove-property [(->block-id class-id) (->property-id property-id)]]))
|
||||
|
||||
(defn upsert-closed-value!
|
||||
[property-id closed-value-config]
|
||||
(op-transact!
|
||||
[:upsert-closed-value [property-id closed-value-config]]))
|
||||
[:upsert-closed-value [(->property-id property-id) closed-value-config]]))
|
||||
|
||||
(defn delete-closed-value!
|
||||
[property-id value-block-id]
|
||||
(op-transact!
|
||||
[:delete-closed-value [property-id (->block-id value-block-id)]]))
|
||||
[:delete-closed-value [(->property-id property-id) (->block-id value-block-id)]]))
|
||||
|
||||
(defn add-existing-values-to-closed-values!
|
||||
[property-id values]
|
||||
(op-transact!
|
||||
[:add-existing-values-to-closed-values [property-id values]]))
|
||||
[:add-existing-values-to-closed-values [(->property-id property-id) values]]))
|
||||
|
||||
(defn toggle-reaction!
|
||||
[target-uuid emoji-id user-uuid]
|
||||
|
||||
@@ -22,6 +22,38 @@
|
||||
[repo diff]
|
||||
(state/input-idle? repo :diff diff))
|
||||
|
||||
(def-thread-api :thread-api/search-index-build-progress
|
||||
[repo {:keys [status progress processed total]}]
|
||||
(let [prev-state (get @state/state :search/index-build)
|
||||
current-repo (state/get-current-repo)
|
||||
visible-repo? (or (= repo current-repo)
|
||||
(= repo (:repo prev-state)))]
|
||||
(when visible-repo?
|
||||
(case status
|
||||
:idle
|
||||
(state/set-state! :search/index-build
|
||||
(assoc (or prev-state {})
|
||||
:running? false
|
||||
:repo repo))
|
||||
|
||||
:running
|
||||
(state/set-state! :search/index-build
|
||||
{:running? true
|
||||
:repo repo
|
||||
:progress (or progress 0)
|
||||
:processed (or processed 0)
|
||||
:total (or total 0)})
|
||||
|
||||
:completed
|
||||
(state/set-state! :search/index-build
|
||||
{:running? false
|
||||
:repo repo
|
||||
:progress (or progress 0)
|
||||
:processed (or processed 0)
|
||||
:total (or total 0)})
|
||||
nil))
|
||||
nil))
|
||||
|
||||
(defn- ask-persist-permission!
|
||||
[]
|
||||
(p/let [persistent? (.persist js/navigator.storage)]
|
||||
|
||||
@@ -112,6 +112,11 @@
|
||||
:search/result nil
|
||||
:search/graph-filters []
|
||||
:search/engines {}
|
||||
:search/index-build {:running? false
|
||||
:repo nil
|
||||
:progress 0
|
||||
:processed 0
|
||||
:total 0}
|
||||
|
||||
;; modals
|
||||
:modal/dropdowns {}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
Bump to force a rebuild when the index format changes."
|
||||
1)
|
||||
|
||||
(def ^:private search-index-build-batch-size 200)
|
||||
(def ^:private search-index-build-batch-size 5000)
|
||||
(def ^:private search-index-build-time-budget-ms 8)
|
||||
(def ^:private search-index-build-idle-diff-ms 1000)
|
||||
(def ^:private search-index-build-pause-ms 300)
|
||||
@@ -500,6 +500,11 @@
|
||||
:repo repo
|
||||
:build-id build-id}))))
|
||||
|
||||
(defn- report-search-index-progress!
|
||||
[repo payload]
|
||||
(-> (worker-state/<invoke-main-thread :thread-api/search-index-build-progress repo payload)
|
||||
(p/catch (fn [_error] nil))))
|
||||
|
||||
(comment
|
||||
(def-thread-api :thread-api/get-version
|
||||
[]
|
||||
@@ -892,25 +897,51 @@
|
||||
[repo search-db conn build-id]
|
||||
(ensure-active-search-index-build! repo build-id)
|
||||
(search/truncate-table! search-db)
|
||||
(let [db @conn]
|
||||
(p/loop [remaining (seq (d/datoms db :avet :block/uuid))]
|
||||
(ensure-active-search-index-build! repo build-id)
|
||||
(p/let [_ (<wait-for-search-index-idle! repo build-id)]
|
||||
(if (seq remaining)
|
||||
(let [[batch remaining'] (take-block-datoms-batch remaining
|
||||
search-index-build-batch-size
|
||||
search-index-build-time-budget-ms)
|
||||
indexed (->> batch
|
||||
(keep #(d/entity db (:e %)))
|
||||
(remove search/hidden-entity?)
|
||||
(keep search/block->index))]
|
||||
(when (seq indexed)
|
||||
(search/upsert-blocks! search-db (bean/->js indexed)))
|
||||
(p/let [_ (js/Promise. (fn [resolve] (js/setTimeout resolve 0)))]
|
||||
(p/recur remaining')))
|
||||
(do
|
||||
(ensure-active-search-index-build! repo build-id)
|
||||
(.exec search-db (str "PRAGMA user_version = " search-db-version))))))))
|
||||
(let [db @conn
|
||||
datoms (d/datoms db :avet :block/uuid)
|
||||
total (count datoms)]
|
||||
(p/do!
|
||||
(report-search-index-progress! repo {:build-id build-id
|
||||
:status :running
|
||||
:progress 0
|
||||
:processed 0
|
||||
:total total})
|
||||
(<wait-for-search-index-idle! repo build-id)
|
||||
(p/loop [remaining (seq datoms)
|
||||
processed 0
|
||||
last-progress 0]
|
||||
(ensure-active-search-index-build! repo build-id)
|
||||
(if (seq remaining)
|
||||
(let [[batch remaining'] (take-block-datoms-batch remaining
|
||||
search-index-build-batch-size
|
||||
search-index-build-time-budget-ms)
|
||||
processed' (+ processed (count batch))
|
||||
indexed (->> batch
|
||||
(keep #(d/entity db (:e %)))
|
||||
(remove search/hidden-entity?)
|
||||
(keep search/block->index))
|
||||
progress (if (zero? total)
|
||||
100
|
||||
(min 100 (int (* 100 (/ processed' total)))))
|
||||
should-report? (> progress last-progress)]
|
||||
(when (seq indexed)
|
||||
(search/upsert-blocks! search-db (bean/->js indexed)))
|
||||
(when should-report?
|
||||
(report-search-index-progress! repo {:build-id build-id
|
||||
:status :running
|
||||
:progress progress
|
||||
:processed processed'
|
||||
:total total}))
|
||||
(p/let [_ (js/Promise. (fn [resolve] (js/setTimeout resolve 0)))]
|
||||
(p/recur remaining' processed' (if should-report? progress last-progress))))
|
||||
(do
|
||||
(ensure-active-search-index-build! repo build-id)
|
||||
(.exec search-db (str "PRAGMA user_version = " search-db-version))
|
||||
(report-search-index-progress! repo {:build-id build-id
|
||||
:status :completed
|
||||
:progress 100
|
||||
:processed total
|
||||
:total total})))))))
|
||||
|
||||
(def-thread-api :thread-api/search-build-blocks-indice-in-worker
|
||||
[repo & [force?]]
|
||||
@@ -928,6 +959,9 @@
|
||||
(when-not (= :search/stale-index-build (:type (ex-data error)))
|
||||
(throw error))))
|
||||
(p/finally (fn []
|
||||
(when (= build-id (get @*search-index-build-ids repo))
|
||||
(report-search-index-progress! repo {:build-id build-id
|
||||
:status :idle}))
|
||||
(clear-search-index-build! repo build-id)))))))))))
|
||||
|
||||
(def-thread-api :thread-api/search-build-pages-indice
|
||||
|
||||
@@ -102,21 +102,43 @@ DROP TRIGGER IF EXISTS blocks_au;
|
||||
(str "(" (->> (map (fn [id] (str "'" id "'")) ids)
|
||||
(string/join ", ")) ")"))
|
||||
|
||||
(def ^:private upsert-blocks-batch-size 2000)
|
||||
|
||||
(def ^:private upsert-blocks-sql
|
||||
(memoize
|
||||
(fn [row-count]
|
||||
(str "INSERT INTO blocks (id, title, page) VALUES "
|
||||
(string/join ", " (repeat row-count "(?, ?, ?)"))
|
||||
" ON CONFLICT (id) DO UPDATE SET (title, page) = (excluded.title, excluded.page)"))))
|
||||
|
||||
(defn- valid-upsert-block?
|
||||
[item]
|
||||
(and (common-util/uuid-string? (.-id item))
|
||||
(common-util/uuid-string? (.-page item))))
|
||||
|
||||
(defn- throw-upsert-blocks-error!
|
||||
[item]
|
||||
(js/console.error "Upsert blocks wrong data: ")
|
||||
(js/console.dir item)
|
||||
(throw (ex-info "Search upsert-blocks wrong data: "
|
||||
(bean/->clj item))))
|
||||
|
||||
(defn- upsert-bind-params
|
||||
[batch]
|
||||
(into-array
|
||||
(mapcat (fn [item]
|
||||
[(.-id item) (.-title item) (.-page item)])
|
||||
batch)))
|
||||
|
||||
(defn upsert-blocks!
|
||||
[^Object db blocks]
|
||||
(.transaction db (fn [tx]
|
||||
(doseq [item blocks]
|
||||
(if (and (common-util/uuid-string? (.-id item))
|
||||
(common-util/uuid-string? (.-page item)))
|
||||
(.exec tx #js {:sql "INSERT INTO blocks (id, title, page) VALUES ($id, $title, $page) ON CONFLICT (id) DO UPDATE SET (title, page) = ($title, $page)"
|
||||
:bind #js {:$id (.-id item)
|
||||
:$title (.-title item)
|
||||
:$page (.-page item)}})
|
||||
(do
|
||||
(js/console.error "Upsert blocks wrong data: ")
|
||||
(js/console.dir item)
|
||||
(throw (ex-info "Search upsert-blocks wrong data: "
|
||||
(bean/->clj item)))))))))
|
||||
(doseq [batch (partition-all upsert-blocks-batch-size blocks)]
|
||||
(doseq [item blocks]
|
||||
(when-not (valid-upsert-block? item)
|
||||
(throw-upsert-blocks-error! item)))
|
||||
(.exec tx #js {:sql (upsert-blocks-sql (count batch))
|
||||
:bind (upsert-bind-params batch)})))))
|
||||
|
||||
(defn delete-blocks!
|
||||
[db ids]
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "'n Bladsy met die naam \"{1}\" bestaan reeds."
|
||||
:page.convert/tag-to-page-has-children "Tag heeft onderliggende elementen en kan nie worden geconverteerd"
|
||||
|
||||
:page.delete/batch-confirm-title "Is jy seker jy wil hierdie bladsye uitvee? Eienskappe en etikette sal permanent uitgevee word en bladsye sal na Herwinning geskuif word."
|
||||
:page.delete/confirm-title "Is jy seker jy wil hierdie bladsy uitvee?"
|
||||
:page.delete/permanent-confirm-title "Is jy seker jy wil hierdie bladsy permanent uitvee?"
|
||||
:page.delete/success "Bladsy \"{1}\" is suksesvol uitgevee!"
|
||||
:page.delete/total "Totaal: {1}"
|
||||
:page.delete/warning "Die inhoud van hierdie bladsye is uitgevee, maar kon nie uitgevee word nie: {1}. Sien javascript-konsole vir meer besonderhede."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Leë invoer"
|
||||
:search/full-text-placeholder "Voltekssoektog"
|
||||
:search/index-progress "Indekseer {1}%"
|
||||
:search/indices-rebuilt-success "Soekindekse is suksesvol herbou!"
|
||||
:search/no-result "Geen resultate nie"
|
||||
:search/result-count "{1} resultate"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "توجد صفحة بالاسم \"{1}\" بالفعل."
|
||||
:page.convert/tag-to-page-has-children "الوسم له عناصر فرعية ولا يمكن تحويله"
|
||||
|
||||
:page.delete/batch-confirm-title "هل أنت متأكد أنك تريد حذف هذه الصفحات؟ سيتم حذف الخصائص والوسوم نهائياً وستُنقل الصفحات إلى سلة المحذوفات."
|
||||
:page.delete/confirm-title "هل أنت متأكد أنك تريد حذف هذه الصفحة؟"
|
||||
:page.delete/permanent-confirm-title "هل أنت متأكد أنك تريد حذف هذه الصفحة نهائياً؟"
|
||||
:page.delete/success "تم حذف الصفحة «{1}» بنجاح!"
|
||||
:page.delete/total "الإجمالي: {1}"
|
||||
:page.delete/warning "تم حذف محتواها من هذه الصفحات ولكن تعذر حذفها: {1}. راجع وحدة تحكم جافا سكريبت لمزيد من التفاصيل."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "إدخال فارغ"
|
||||
:search/full-text-placeholder "بحث في النص الكامل"
|
||||
:search/index-progress "جارٍ فهرسة {1}%"
|
||||
:search/indices-rebuilt-success "تم إعادة بناء فهارس البحث بنجاح!"
|
||||
:search/no-result "لا توجد نتائج"
|
||||
:search/result-count "{1} نتيجة"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Ja existeix una pàgina amb el nom \"{1}\"."
|
||||
:page.convert/tag-to-page-has-children "L'etiqueta té fills i no es pot convertir"
|
||||
|
||||
:page.delete/batch-confirm-title "Esteu segur que voleu suprimir aquestes pàgines? Les propietats i les etiquetes se suprimiran permanentment i les pàgines es mouran a la Paperera."
|
||||
:page.delete/confirm-title "Esteu segur que voleu suprimir aquesta pàgina?"
|
||||
:page.delete/permanent-confirm-title "Esteu segur que voleu suprimir permanentment aquesta pàgina?"
|
||||
:page.delete/success "La pàgina \"{1}\" s'ha suprimit correctament!"
|
||||
:page.delete/total "Total: {1}"
|
||||
:page.delete/warning "S'ha suprimit el contingut d'aquestes pàgines, però no s'han pogut suprimir: {1}. Vegeu la consola javascript per a més detalls."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Entrada buida"
|
||||
:search/full-text-placeholder "Cerca de text complet"
|
||||
:search/index-progress "Indexant {1}%"
|
||||
:search/indices-rebuilt-success "Índexs de recerca reconstruïts correctament!"
|
||||
:search/no-result "Sense resultats"
|
||||
:search/result-count "{1} resultats"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Stránka s názvem „{1}“ již existuje."
|
||||
:page.convert/tag-to-page-has-children "Štítek má podřízené prvky a nelze ho převést"
|
||||
|
||||
:page.delete/batch-confirm-title "Opravdu chcete smazat tyto stránky? Vlastnosti a štítky budou trvale smazány a stránky budou přesunuty do Koše."
|
||||
:page.delete/confirm-title "Opravdu chcete smazat tuto stránku?"
|
||||
:page.delete/permanent-confirm-title "Opravdu chcete trvale smazat tuto stránku?"
|
||||
:page.delete/success "Stránka „{1}“ byla úspěšně smazána!"
|
||||
:page.delete/total "Celkem: {1}"
|
||||
:page.delete/warning "Obsah těchto stránek byl smazán, ale nepodařilo se je smazat: {1}. Další podrobnosti naleznete v konzole javascript."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Prázdný vstup"
|
||||
:search/full-text-placeholder "Fulltextové vyhledávání"
|
||||
:search/index-progress "Indexování {1} %"
|
||||
:search/indices-rebuilt-success "Indexy vyhledávání byly úspěšně znovu vytvořeny!"
|
||||
:search/no-result "Žádné výsledky"
|
||||
:search/result-count "{1} výsledků"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Eine Seite mit dem Namen „{1}“ existiert bereits."
|
||||
:page.convert/tag-to-page-has-children "Tag mit Unterelementen kann nicht konvertiert werden"
|
||||
|
||||
:page.delete/batch-confirm-title "Diese Seiten wirklich entfernen? Eigenschaften und Tags werden dauerhaft gelöscht und Seiten werden in den Papierkorb verschoben."
|
||||
:page.delete/confirm-title "Diese Seite wirklich entfernen?"
|
||||
:page.delete/permanent-confirm-title "Diese Seite wirklich dauerhaft entfernen?"
|
||||
:page.delete/success "Seite „{1}“ wurde erfolgreich gelöscht!"
|
||||
:page.delete/total "Gesamt: {1}"
|
||||
:page.delete/warning "Der Inhalt dieser Seiten wurde gelöscht, konnte aber nicht gelöscht werden: {1}. Weitere Informationen finden Sie in der Javascript-Konsole."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Leere Eingabe"
|
||||
:search/full-text-placeholder "Volltextsuche"
|
||||
:search/index-progress "Indexierung {1} %"
|
||||
:search/indices-rebuilt-success "Suchindizes erfolgreich neu aufgebaut!"
|
||||
:search/no-result "Keine übereinstimmenden Treffer"
|
||||
:search/result-count "{1} Ergebnisse"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "A page with the name \"{1}\" already exists."
|
||||
:page.convert/tag-to-page-has-children "This tag cannot be converted because it has tag children. All tag children must be removed or converted before converting this tag."
|
||||
|
||||
:page.delete/batch-confirm-title "Are you sure you want to delete these pages? Properties and tags will be permanently deleted and pages will be moved to Recycle."
|
||||
:page.delete/confirm-title "Are you sure you want to delete this page?"
|
||||
:page.delete/permanent-confirm-title "Are you sure you want to permanently delete this page?"
|
||||
:page.delete/success "Page \"{1}\" was deleted successfully!"
|
||||
:page.delete/total "Total: {1}"
|
||||
:page.delete/warning "These pages had their content deleted but were unable to be deleted: {1}. See javascript console for more details."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Blank input"
|
||||
:search/full-text-placeholder "Full text search"
|
||||
:search/index-progress "Indexing {1}%"
|
||||
:search/indices-rebuilt-success "Search indices rebuilt successfully!"
|
||||
:search/no-result "No matched result"
|
||||
:search/result-count (fn [n] (str n (if (> n 1) " results" " result")))
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Ya existe una página con el nombre \"{1}\"."
|
||||
:page.convert/tag-to-page-has-children "La etiqueta tiene elementos hijos y no se puede convertir"
|
||||
|
||||
:page.delete/batch-confirm-title "¿Está seguro de que desea eliminar estas páginas? Las propiedades y etiquetas se eliminarán permanentemente y las páginas se moverán a la Papelera."
|
||||
:page.delete/confirm-title "¿Está seguro de que desea eliminar esta página?"
|
||||
:page.delete/permanent-confirm-title "¿Está seguro de que desea eliminar permanentemente esta página?"
|
||||
:page.delete/success "¡La página \"{1}\" se eliminó correctamente!"
|
||||
:page.delete/total "Total: {1}"
|
||||
:page.delete/warning "Se eliminó el contenido de estas páginas pero no se pudo eliminar: {1}. Consulte la consola de JavaScript para obtener más detalles."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Entrada vacía"
|
||||
:search/full-text-placeholder "Búsqueda de texto completo"
|
||||
:search/index-progress "Indexando {1}%"
|
||||
:search/indices-rebuilt-success "¡Índices de búsqueda reconstruidos exitosamente!"
|
||||
:search/no-result "Sin resultados que coincidan"
|
||||
:search/result-count "{1} resultados"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "صفحه ای با نام \"{1}\" از قبل وجود دارد."
|
||||
:page.convert/tag-to-page-has-children "برچسب دارای فرزندان است و نمیتوان تبدیل کرد"
|
||||
|
||||
:page.delete/batch-confirm-title "آیا مطمئن هستید که میخواهید این صفحات را حذف کنید؟ ویژگیها و برچسبها برای همیشه حذف میشوند و صفحهها به سطل بازیافت منتقل میشوند."
|
||||
:page.delete/confirm-title "آیا مطمئن هستید که می خواهید این صفحه را حذف کنید؟"
|
||||
:page.delete/permanent-confirm-title "آیا مطمئن هستید که میخواهید این صفحه را برای همیشه حذف کنید؟"
|
||||
:page.delete/success "صفحه «{1}» با موفقیت حذف شد!"
|
||||
:page.delete/total "مجموع: {1}"
|
||||
:page.delete/warning "محتوای این صفحات حذف شد اما حذف نشدند: {1}. برای جزئیات بیشتر به کنسول جاوا اسکریپت مراجعه کنید."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "ورودی خالی"
|
||||
:search/full-text-placeholder "جستجوی متن کامل"
|
||||
:search/index-progress "در حال ایندکسگذاری {1}٪"
|
||||
:search/indices-rebuilt-success "فهرسهای جستجو با موفقیت بازسازی شدند!"
|
||||
:search/no-result "نتیجهای یافت نشد"
|
||||
:search/result-count "{1} نتیجه"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Une page portant le nom « {1} » existe déjà."
|
||||
:page.convert/tag-to-page-has-children "Le tag a des éléments enfants et ne peut pas être converti"
|
||||
|
||||
:page.delete/batch-confirm-title "Etes-vous sûr de vouloir supprimer ces pages ? Les propriétés et les tags seront supprimés définitivement et les pages seront déplacées dans la Corbeille."
|
||||
:page.delete/confirm-title "Etes-vous sûr de vouloir supprimer cette page ?"
|
||||
:page.delete/permanent-confirm-title "Etes-vous sûr de vouloir supprimer définitivement cette page ?"
|
||||
:page.delete/success "La page « {1} » a été supprimée avec succès !"
|
||||
:page.delete/total "Total : {1}"
|
||||
:page.delete/warning "Le contenu de ces pages a été supprimé mais n'a pas pu être supprimé : {1}. Voir la console javascript pour plus de détails."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Entrée vide"
|
||||
:search/full-text-placeholder "Recherche en texte intégral"
|
||||
:search/index-progress "Indexation {1} %"
|
||||
:search/indices-rebuilt-success "Les indices de recherche ont été reconstruits avec succès !"
|
||||
:search/no-result "Aucun résultat correspondant"
|
||||
:search/result-count "{1} résultats"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Halaman dengan nama \"{1}\" sudah ada."
|
||||
:page.convert/tag-to-page-has-children "Tag memiliki anak dan tidak bisa diubah"
|
||||
|
||||
:page.delete/batch-confirm-title "Apakah Anda yakin ingin menghapus halaman-halaman ini? Properti dan tag akan dihapus secara permanen dan halaman akan dipindahkan ke Tempat Sampah."
|
||||
:page.delete/confirm-title "Apakah Anda yakin ingin menghapus halaman ini?"
|
||||
:page.delete/permanent-confirm-title "Apakah Anda yakin ingin menghapus halaman ini secara permanen?"
|
||||
:page.delete/success "Halaman \"{1}\" berhasil dihapus!"
|
||||
:page.delete/total "Total: {1}"
|
||||
:page.delete/warning "Halaman-halaman ini telah dihapus isinya tetapi tidak dapat dihapus: {1}. Lihat konsol javascript untuk detail selengkapnya."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Input kosong"
|
||||
:search/full-text-placeholder "Pencarian teks lengkap"
|
||||
:search/index-progress "Mengindeks {1}%"
|
||||
:search/indices-rebuilt-success "Indeks pencarian berhasil dibangun kembali!"
|
||||
:search/no-result "Tidak ada hasil yang cocok"
|
||||
:search/result-count "{1} hasil"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Esiste già una pagina con il nome \"{1}\"."
|
||||
:page.convert/tag-to-page-has-children "Il tag ha elementi figli e non può essere convertito"
|
||||
|
||||
:page.delete/batch-confirm-title "Sei sicuro di voler eliminare queste pagine? Proprietà e tag saranno eliminati definitivamente e le pagine verranno spostate nel Cestino."
|
||||
:page.delete/confirm-title "Sei sicuro di voler eliminare questa pagina?"
|
||||
:page.delete/permanent-confirm-title "Sei sicuro di voler eliminare definitivamente questa pagina?"
|
||||
:page.delete/success "La pagina \"{1}\" è stata eliminata con successo!"
|
||||
:page.delete/total "Totale: {1}"
|
||||
:page.delete/warning "I contenuti di queste pagine sono stati eliminati ma non è stato possibile eliminarli: {1}. Vedi la console JavaScript per maggiori dettagli."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Input vuoto"
|
||||
:search/full-text-placeholder "Ricerca full text"
|
||||
:search/index-progress "Indicizzazione {1}%"
|
||||
:search/indices-rebuilt-success "Indici di ricerca ricostruiti con successo!"
|
||||
:search/no-result "Nessun risultato"
|
||||
:search/result-count "{1} risultati"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "「{1}」という名前のページはすでに存在します。"
|
||||
:page.convert/tag-to-page-has-children "子要素を持つタグは変換できません"
|
||||
|
||||
:page.delete/batch-confirm-title "これらのページを削除してもよろしいですか?プロパティとタグは完全に削除され、ページはごみ箱に移動されます。"
|
||||
:page.delete/confirm-title "このページを削除してもよろしいですか?"
|
||||
:page.delete/permanent-confirm-title "このページを完全に削除してもよろしいですか?"
|
||||
:page.delete/success "ページ「{1}」は正常に削除されました。"
|
||||
:page.delete/total "合計: {1}"
|
||||
:page.delete/warning "これらのページのコンテンツは削除されましたが、削除できませんでした: {1}。詳細については、JavaScript コンソールを参照してください。"
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "空の入力"
|
||||
:search/full-text-placeholder "全文検索"
|
||||
:search/index-progress "索引作成中 {1}%"
|
||||
:search/indices-rebuilt-success "検索インデックスが正常に再構築されました!"
|
||||
:search/no-result "結果なし"
|
||||
:search/result-count "{1} 件の結果"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "이름이 \"{1}\"인 페이지가 이미 존재합니다."
|
||||
:page.convert/tag-to-page-has-children "자식 요소가 있는 태그는 변환할 수 없습니다"
|
||||
|
||||
:page.delete/batch-confirm-title "이 페이지들을 삭제하시겠습니까? 속성과 태그는 영구적으로 삭제되고 페이지는 휴지통으로 이동됩니다."
|
||||
:page.delete/confirm-title "이 페이지를 삭제하시겠습니까?"
|
||||
:page.delete/permanent-confirm-title "이 페이지를 영구적으로 삭제하시겠습니까?"
|
||||
:page.delete/success "페이지 \"{1}\"이(가) 성공적으로 삭제되었습니다!"
|
||||
:page.delete/total "합계: {1}"
|
||||
:page.delete/warning "다음 페이지의 콘텐츠가 삭제되었지만 삭제할 수 없습니다. {1}. 자세한 내용은 자바스크립트 콘솔을 참조하세요."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "빈 입력"
|
||||
:search/full-text-placeholder "전문 검색"
|
||||
:search/index-progress "인덱싱 {1}%"
|
||||
:search/indices-rebuilt-success "검색 인덱스가 성공적으로 재구성되었습니다!"
|
||||
:search/no-result "결과 없음"
|
||||
:search/result-count "{1}개 결과"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "En side med navnet \"{1}\" eksisterer allerede."
|
||||
:page.convert/tag-to-page-has-children "Tagg har underordnede elementer og kan ikke konverteres"
|
||||
|
||||
:page.delete/batch-confirm-title "Er du sikker på at du vil slette disse sidene? Egenskaper og tagger blir slettet permanent, og sidene blir flyttet til Papirkurv."
|
||||
:page.delete/confirm-title "Er du sikker på at du vil slette denne siden?"
|
||||
:page.delete/permanent-confirm-title "Er du sikker på at du vil slette denne siden permanent?"
|
||||
:page.delete/success "Side \"{1}\" ble slettet!"
|
||||
:page.delete/total "Totalt: {1}"
|
||||
:page.delete/warning "Innholdet på disse sidene ble slettet, men kunne ikke slettes: {1}. Se javascript-konsollen for mer informasjon."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Tom inndata"
|
||||
:search/full-text-placeholder "Fulltekstsøk"
|
||||
:search/index-progress "Indekserer {1} %"
|
||||
:search/indices-rebuilt-success "Søkeindekser bygget på nytt!"
|
||||
:search/no-result "Ingen resultater"
|
||||
:search/result-count "{1} resultater"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Er bestaat al een pagina met de naam \"{1}\"."
|
||||
:page.convert/tag-to-page-has-children "Tag heeft onderliggende elementen en kan niet worden geconverteerd"
|
||||
|
||||
:page.delete/batch-confirm-title "Weet u zeker dat u deze pagina's wilt verwijderen? Eigenschappen en tags worden permanent verwijderd en pagina's worden naar de Prullenbak verplaatst."
|
||||
:page.delete/confirm-title "Weet u zeker dat u deze pagina wilt verwijderen?"
|
||||
:page.delete/permanent-confirm-title "Weet u zeker dat u deze pagina permanent wilt verwijderen?"
|
||||
:page.delete/success "Pagina \"{1}\" is succesvol verwijderd!"
|
||||
:page.delete/total "Totaal: {1}"
|
||||
:page.delete/warning "Van deze pagina's is de inhoud verwijderd, maar deze kon niet worden verwijderd: {1}. Zie JavaScript-console voor meer details."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Lege invoer"
|
||||
:search/full-text-placeholder "Zoeken in volledige tekst"
|
||||
:search/index-progress "Indexeren {1}%"
|
||||
:search/indices-rebuilt-success "Zoekindexen zijn opnieuw opgebouwd!"
|
||||
:search/no-result "Geen resultaten"
|
||||
:search/result-count "{1} resultaten"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Strona o nazwie „{1}” już istnieje."
|
||||
:page.convert/tag-to-page-has-children "Tag ma elementy podrzędne i nie może być przekonwertowany"
|
||||
|
||||
:page.delete/batch-confirm-title "Czy na pewno chcesz usunąć te strony? Właściwości i tagi zostaną trwale usunięte, a strony trafią do Kosza."
|
||||
:page.delete/confirm-title "Czy na pewno chcesz usunąć tę stronę?"
|
||||
:page.delete/permanent-confirm-title "Czy na pewno chcesz trwale usunąć tę stronę?"
|
||||
:page.delete/success "Strona „{1}” została pomyślnie usunięta!"
|
||||
:page.delete/total "Łącznie: {1}"
|
||||
:page.delete/warning "Treść tych stron została usunięta, ale nie udało się ich usunąć: {1}. Więcej szczegółów znajdziesz w konsoli JavaScript."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Puste wejście"
|
||||
:search/full-text-placeholder "Wyszukiwanie pełnotekstowe"
|
||||
:search/index-progress "Indeksowanie {1}%"
|
||||
:search/indices-rebuilt-success "Indeksy wyszukiwania zostały pomyślnie przebudowane!"
|
||||
:search/no-result "Brak wyników"
|
||||
:search/result-count "{1} wyników"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Já existe uma página com o nome \"{1}\"."
|
||||
:page.convert/tag-to-page-has-children "A tag possui filhos e não pode ser convertida"
|
||||
|
||||
:page.delete/batch-confirm-title "Tem certeza de que deseja excluir estas páginas? Propriedades e tags serão excluídas permanentemente e as páginas serão movidas para a Lixeira."
|
||||
:page.delete/confirm-title "Tem certeza de que deseja excluir esta página?"
|
||||
:page.delete/permanent-confirm-title "Tem certeza de que deseja excluir permanentemente esta página?"
|
||||
:page.delete/success "A página \"{1}\" foi excluída com sucesso!"
|
||||
:page.delete/total "Total: {1}"
|
||||
:page.delete/warning "Estas páginas tiveram seu conteúdo excluído, mas não puderam ser excluídos: {1}. Consulte o console javascript para obter mais detalhes."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Entrada vazia"
|
||||
:search/full-text-placeholder "Pesquisa de texto completo"
|
||||
:search/index-progress "Indexando {1}%"
|
||||
:search/indices-rebuilt-success "Índices de busca reconstruídos com sucesso!"
|
||||
:search/no-result "Nenhum resultado correspondente"
|
||||
:search/result-count "{1} resultados"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Já existe uma página com o nome \"{1}\"."
|
||||
:page.convert/tag-to-page-has-children "A tag possui filhos e não pode ser convertida"
|
||||
|
||||
:page.delete/batch-confirm-title "Tem a certeza de que pretende eliminar estas páginas? As propriedades e tags serão eliminadas permanentemente e as páginas serão movidas para a Reciclagem."
|
||||
:page.delete/confirm-title "Tem a certeza que pretende eliminar esta página?"
|
||||
:page.delete/permanent-confirm-title "Tem a certeza de que pretende eliminar permanentemente esta página?"
|
||||
:page.delete/success "A página \"{1}\" foi eliminada com sucesso!"
|
||||
:page.delete/total "Total: {1}"
|
||||
:page.delete/warning "Estas páginas tiveram o seu conteúdo eliminado, mas não puderam ser eliminadas: {1}. Consulte a consola javascript para obter mais detalhes."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Entrada vazia"
|
||||
:search/full-text-placeholder "Pesquisa de texto completo"
|
||||
:search/index-progress "A indexar {1}%"
|
||||
:search/indices-rebuilt-success "Índices de busca reconstruídos com sucesso!"
|
||||
:search/no-result "Sem resultados"
|
||||
:search/result-count "{1} resultados"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Страница с названием «{1}» уже существует."
|
||||
:page.convert/tag-to-page-has-children "Тег имеет дочерние элементы и не может быть преобразован"
|
||||
|
||||
:page.delete/batch-confirm-title "Вы уверены, что хотите удалить эти страницы? Свойства и теги будут удалены навсегда, а страницы будут перемещены в Корзину."
|
||||
:page.delete/confirm-title "Вы уверены, что хотите удалить эту страницу?"
|
||||
:page.delete/permanent-confirm-title "Вы уверены, что хотите удалить эту страницу навсегда?"
|
||||
:page.delete/success "Страница «{1}» успешно удалена!"
|
||||
:page.delete/total "Всего: {1}"
|
||||
:page.delete/warning "Содержимое этих страниц было удалено, но удалить их не удалось: {1}. Дополнительную информацию см. в консоли JavaScript."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Пустой ввод"
|
||||
:search/full-text-placeholder "Полнотекстовый поиск"
|
||||
:search/index-progress "Индексация {1}%"
|
||||
:search/indices-rebuilt-success "Индексы поиска успешно перестроены!"
|
||||
:search/no-result "Нет результатов"
|
||||
:search/result-count "{1} результатов"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Stránka s názvom „{1}“ už existuje."
|
||||
:page.convert/tag-to-page-has-children "Štítok má podriadené prvky a nemožno ho převést"
|
||||
|
||||
:page.delete/batch-confirm-title "Naozaj chcete odstrániť tieto stránky? Vlastnosti a tagy budú natrvalo odstránené a stránky budú presunuté do Koša."
|
||||
:page.delete/confirm-title "Naozaj chcete odstrániť túto stránku?"
|
||||
:page.delete/permanent-confirm-title "Naozaj chcete natrvalo odstrániť túto stránku?"
|
||||
:page.delete/success "Stránka „{1}“ bola úspešne odstránená!"
|
||||
:page.delete/total "Celkom: {1}"
|
||||
:page.delete/warning "Obsah týchto stránok bol odstránený, ale nebolo možné ho odstrániť: {1}. Ďalšie podrobnosti nájdete v konzole javascript."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Prázdny vstup"
|
||||
:search/full-text-placeholder "Fulltextové vyhľadávanie"
|
||||
:search/index-progress "Indexovanie {1} %"
|
||||
:search/indices-rebuilt-success "Indexy vyhľadávania boli úspešne znovu vytvorené!"
|
||||
:search/no-result "Žiadne výsledky"
|
||||
:search/result-count "{1} výsledkov"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "\"{1}\" adında bir sayfa zaten mevcut."
|
||||
:page.convert/tag-to-page-has-children "Etiketin alt öğeleri var ve dönüştürülemez"
|
||||
|
||||
:page.delete/batch-confirm-title "Bu sayfaları silmek istediğinizden emin misiniz? Özellikler ve etiketler kalıcı olarak silinecek ve sayfalar Geri Dönüşüm'e taşınacaktır."
|
||||
:page.delete/confirm-title "Bu sayfayı silmek istediğinizden emin misiniz?"
|
||||
:page.delete/permanent-confirm-title "Bu sayfayı kalıcı olarak silmek istediğinizden emin misiniz?"
|
||||
:page.delete/success "Sayfa \"{1}\" başarıyla silindi!"
|
||||
:page.delete/total "Toplam: {1}"
|
||||
:page.delete/warning "Bu sayfaların içeriği silindi ancak silinemedi: {1}. Daha fazla ayrıntı için javascript konsoluna bakın."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Boş giriş"
|
||||
:search/full-text-placeholder "Tam metin araması"
|
||||
:search/index-progress "Dizinleniyor {1}%"
|
||||
:search/indices-rebuilt-success "Arama dizinleri başarıyla yeniden oluşturuldu!"
|
||||
:search/no-result "Sonuç yok"
|
||||
:search/result-count "{1} sonuç"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "Сторінка з назвою \"{1}\" вже існує."
|
||||
:page.convert/tag-to-page-has-children "Тег имеет дочірние элементы и не может быть преобразован"
|
||||
|
||||
:page.delete/batch-confirm-title "Ви впевнені, що хочете видалити ці сторінки? Властивості й теги буде видалено назавжди, а сторінки буде переміщено до Кошика."
|
||||
:page.delete/confirm-title "Ви впевнені, що хочете видалити цю сторінку?"
|
||||
:page.delete/permanent-confirm-title "Ви впевнені, що хочете назавжди видалити цю сторінку?"
|
||||
:page.delete/success "Сторінка \"{1}\" успішно видалена!"
|
||||
:page.delete/total "Усього: {1}"
|
||||
:page.delete/warning "Вміст цих сторінок було видалено, але його не вдалося видалити: {1}. Дивіться консоль javascript для отримання додаткової інформації."
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "Порожнє введення"
|
||||
:search/full-text-placeholder "Повнотекстовий пошук"
|
||||
:search/index-progress "Індексація {1}%"
|
||||
:search/indices-rebuilt-success "Індекси пошуку успішно перебудовані!"
|
||||
:search/no-result "Немає результатів"
|
||||
:search/result-count "{1} результатів"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "页面“{1}”已存在。"
|
||||
:page.convert/tag-to-page-has-children "此标签无法转换,因为它仍有子标签。必须先移除或转换所有子标签,才能转换此标签。"
|
||||
|
||||
:page.delete/batch-confirm-title "确定要删除这些页面吗?属性和标签将被永久删除,页面将被移入回收站。"
|
||||
:page.delete/confirm-title "确认要删除此页面吗?"
|
||||
:page.delete/permanent-confirm-title "确定要永久删除此页面吗?"
|
||||
:page.delete/success "页面“{1}”已成功删除!"
|
||||
:page.delete/total "总计: {1}"
|
||||
:page.delete/warning "这些页面的内容已删除,但无法删除:{1}。有关更多详细信息,请参阅 JavaScript 控制台。"
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "空白输入"
|
||||
:search/full-text-placeholder "全文搜索"
|
||||
:search/index-progress "正在索引 {1}%"
|
||||
:search/indices-rebuilt-success "搜索索引已成功重建!"
|
||||
:search/no-result "未找到匹配项"
|
||||
:search/result-count "{1} 个结果"
|
||||
|
||||
@@ -1093,7 +1093,9 @@
|
||||
:page.convert/tag-to-page-duplicate "頁面「{1}」已存在。"
|
||||
:page.convert/tag-to-page-has-children "此標籤無法轉換,因為它仍有子標籤。必須先移除或轉換所有子標籤,才能轉換此標籤。"
|
||||
|
||||
:page.delete/batch-confirm-title "確定要刪除這些頁面嗎?屬性與標籤將被永久刪除,頁面將被移入資源回收筒。"
|
||||
:page.delete/confirm-title "確認要刪除此頁面嗎?"
|
||||
:page.delete/permanent-confirm-title "確定要永久刪除此頁面嗎?"
|
||||
:page.delete/success "頁面「{1}」已成功刪除!"
|
||||
:page.delete/total "總計: {1}"
|
||||
:page.delete/warning "這些頁面的內容已刪除,但無法刪除:{1}。有關更多詳細信息,請參閱 JavaScript 控制台。"
|
||||
@@ -1528,6 +1530,7 @@
|
||||
|
||||
:search/blank-input "空白輸入"
|
||||
:search/full-text-placeholder "全文搜尋"
|
||||
:search/index-progress "正在建立索引 {1}%"
|
||||
:search/indices-rebuilt-success "搜尋索引已成功重建!"
|
||||
:search/no-result "未找到匹配項"
|
||||
:search/result-count "{1} 個結果"
|
||||
|
||||
@@ -224,3 +224,38 @@
|
||||
(is (some? ctor))
|
||||
(is (= 1 (count result)))
|
||||
(is (= "alpha beta" (get-in result [0 :item :title])))))))
|
||||
|
||||
(deftest upsert-blocks-batches-rows-into-single-sql-statement
|
||||
(let [calls (atom [])
|
||||
tx #js {:exec (fn [opts]
|
||||
(swap! calls conj {:sql (aget opts "sql")
|
||||
:bind (js->clj (aget opts "bind"))}))}
|
||||
db #js {:transaction (fn [f] (f tx))}
|
||||
blocks (clj->js [{:id "67e55044-10b1-426f-9247-bb680e5fe0c8"
|
||||
:title "alpha"
|
||||
:page "67e55044-10b1-426f-9247-bb680e5fe0c8"}
|
||||
{:id "8f14e45f-ea6e-4be8-b53f-bf0f2ca8a5db"
|
||||
:title "beta"
|
||||
:page "8f14e45f-ea6e-4be8-b53f-bf0f2ca8a5db"}
|
||||
{:id "9d5ed678-fe57-4bcf-bf4d-6f2fd5f8995d"
|
||||
:title "gamma"
|
||||
:page "9d5ed678-fe57-4bcf-bf4d-6f2fd5f8995d"}])]
|
||||
(search/upsert-blocks! db blocks)
|
||||
(is (= 1 (count @calls)))
|
||||
(is (= "INSERT INTO blocks (id, title, page) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) ON CONFLICT (id) DO UPDATE SET (title, page) = (excluded.title, excluded.page)"
|
||||
(:sql (first @calls))))
|
||||
(is (= ["67e55044-10b1-426f-9247-bb680e5fe0c8" "alpha" "67e55044-10b1-426f-9247-bb680e5fe0c8"
|
||||
"8f14e45f-ea6e-4be8-b53f-bf0f2ca8a5db" "beta" "8f14e45f-ea6e-4be8-b53f-bf0f2ca8a5db"
|
||||
"9d5ed678-fe57-4bcf-bf4d-6f2fd5f8995d" "gamma" "9d5ed678-fe57-4bcf-bf4d-6f2fd5f8995d"]
|
||||
(:bind (first @calls))))))
|
||||
|
||||
(deftest upsert-blocks-throws-on-invalid-input
|
||||
(let [tx #js {:exec (fn [_opts] nil)}
|
||||
db #js {:transaction (fn [f] (f tx))}
|
||||
error (try
|
||||
(search/upsert-blocks! db (clj->js [{:id "not-uuid" :title "alpha" :page "not-uuid"}]))
|
||||
nil
|
||||
(catch :default e e))]
|
||||
(is (some? error))
|
||||
(is (re-find #"Search upsert-blocks wrong data"
|
||||
(or (ex-message error) (str error))))))
|
||||
|
||||
Reference in New Issue
Block a user