diff --git a/src/main/frontend/components/property.cljs b/src/main/frontend/components/property.cljs index 531a8da4b..f49281e92 100644 --- a/src/main/frontend/components/property.cljs +++ b/src/main/frontend/components/property.cljs @@ -14,10 +14,8 @@ [frontend.db :as db] [frontend.db-mixins :as db-mixins] [frontend.db.async :as db-async] - [frontend.db.model :as model] [frontend.handler.db-based.property :as db-property-handler] [frontend.handler.notification :as notification] - [frontend.handler.page :as page-handler] [frontend.handler.route :as route-handler] [frontend.mixins :as mixins] [frontend.modules.shortcut.core :as shortcut] @@ -34,80 +32,6 @@ [promesa.core :as p] [rum.core :as rum])) -(defn- (rum/deref *ref) - (.click)))) - [default-open?]) - (let [schema-classes (:property/schema.classes property)] - [:div.flex.flex-1.col-span-3 - (let [content-fn - (fn [{:keys [id]}] - (let [toggle-fn #(do - (when (fn? on-hide) (on-hide)) - (shui/popup-hide! id)) - classes (model/get-all-classes (state/get-current-repo) {:except-root-class? true}) - options (map (fn [class] - {:label (:block/title class) - :value (:block/uuid class)}) - classes) - options (if no-class? - (cons {:label "Skip choosing tag" - :value :no-tag} - options) - options) - opts {:items options - :input-default-placeholder (if multiple-choices? "Choose tags" "Choose tag") - :dropdown? false - :close-modal? false - :multiple-choices? multiple-choices? - :selected-choices (map :block/uuid schema-classes) - :extract-fn :label - :extract-chosen-fn :value - :show-new-when-not-exact-match? true - :input-opts {:on-key-down - (fn [e] - (case (util/ekey e) - "Escape" - (do - (util/stop e) - (toggle-fn)) - nil))} - :on-chosen (fn [value select?] - (if (= value :no-tag) - (toggle-fn) - (p/let [result (> db-property/db-attribute-properties - (map db-property/built-in-properties) - (keep #(when (get block (:attribute %)) (:title %))) - set) + (map db-property/built-in-properties) + (keep #(when (get block (:attribute %)) (:title %))) + set) exclude-properties (fn [m] (or (and (not page?) (contains? existing-tag-alias (:block/title m))) ;; Filters out properties from being in wrong :view-context - (and (not page?) (= :page (get-in m [:block/schema :view-context]))) - (and page? (= :block (get-in m [:block/schema :view-context]))))) + (and (not page?) (= :page (get-in m [:block/schema :view-context]))) + (and page? (= :block (get-in m [:block/schema :view-context]))))) property (rum/react *property) property-key (rum/react *property-key)] [:div.ls-property-input.flex.flex-1.flex-row.items-center.flex-wrap.gap-1 @@ -422,20 +346,20 @@ (cond @*show-new-property-config? (property-type-select property (merge opts - {:*property *property - :*property-name *property-key - :*property-schema *property-schema - :default-open? true - :block block - :*show-new-property-config? *show-new-property-config? - :*show-class-select? *show-class-select?})) + {:*property *property + :*property-name *property-key + :*property-schema *property-schema + :default-open? true + :block block + :*show-new-property-config? *show-new-property-config? + :*show-class-select? *show-class-select?})) (and property @*show-class-select?) - (class-select property (assoc opts - :on-hide #(reset! *show-class-select? false) - :multiple-choices? false - :default-open? true - :no-class? true)) + (property-config/class-select property (assoc opts + :on-hide #(reset! *show-class-select? false) + :multiple-choices? false + :default-open? true + :no-class? true)) :else (when (and property (not class-schema?)) @@ -446,7 +370,7 @@ (fn [e] ;; `Backspace` to close property popup and back to editing the current block (when (and (= (util/ekey e) "Backspace") - (= "" (.-value (.-target e)))) + (= "" (.-value (.-target e)))) (util/stop e) (shui/popup-hide!)))}] (property-select exclude-properties {:on-chosen on-chosen diff --git a/src/main/frontend/components/property/config.cljs b/src/main/frontend/components/property/config.cljs index 4817adfc6..d09c66f01 100644 --- a/src/main/frontend/components/property/config.cljs +++ b/src/main/frontend/components/property/config.cljs @@ -21,7 +21,13 @@ [promesa.core :as p] [goog.dom :as gdom] [rum.core :as rum] - [frontend.db-mixins :as db-mixins])) + [frontend.db-mixins :as db-mixins] + [frontend.components.property.value :as pv] + [frontend.components.select :as select] + [frontend.db.model :as model] + [frontend.handler.page :as page-handler] + [frontend.ui :as ui] + [frontend.components.svg :as svg])) (defn- re-init-commands! "Update commands after task status and priority's closed values has been changed" @@ -64,6 +70,81 @@ (:db/id property) :logseq.property/description description)))) +(defn- (rum/deref *ref) + (.click)))) + [default-open?]) + (let [schema-classes (:property/schema.classes property)] + [:div.flex.flex-1.col-span-3 + (let [content-fn + (fn [{:keys [id]}] + (let [toggle-fn #(do + (when (fn? on-hide) (on-hide)) + (shui/popup-hide! id)) + classes (model/get-all-classes (state/get-current-repo) {:except-root-class? true}) + options (map (fn [class] + {:label (:block/title class) + :value (:block/uuid class)}) + classes) + options (if no-class? + (cons {:label "Skip choosing tag" + :value :no-tag} + options) + options) + opts {:items options + :input-default-placeholder (if multiple-choices? "Choose tags" "Choose tag") + :dropdown? false + :close-modal? false + :multiple-choices? multiple-choices? + :selected-choices (map :block/uuid schema-classes) + :extract-fn :label + :extract-chosen-fn :value + :show-new-when-not-exact-match? true + :input-opts {:on-key-down + (fn [e] + (case (util/ekey e) + "Escape" + (do + (util/stop e) + (toggle-fn)) + nil))} + :on-chosen (fn [value select?] + (if (= value :no-tag) + (toggle-fn) + (p/let [result ( icon (name) (shui/tabler-icon)) + (some-> icon (name) (shui/tabler-icon {:size 14 + :style {:margin-top "-1"}})) [:span title]] (if (fn? desc) (desc) (if (boolean? toggle-checked?) @@ -403,16 +485,31 @@ built-in? (ldb/built-in? property) disabled? (or built-in? config/publishing?)] [:<> - (dropdown-editor-menuitem {:icon :edit :title "Property name" :desc [:span.flex.items-center.gap-1 icon title] + (dropdown-editor-menuitem {:icon :pencil :title "Property name" :desc [:span.flex.items-center.gap-1 icon title] :submenu-content (fn [ops] (name-edit-pane property (assoc ops :disabled? disabled?)))}) (let [disabled? (or (ldb/built-in? property) (and property-type (seq values)))] (dropdown-editor-menuitem {:icon :hash :title "Property type" - :desc (str property-type-label') + :desc (if disabled? + (ui/tippy {:html [:div.w-96 + "The type of this property is locked once you start using it. This is to make sure all your existing information stays correct if the property type is changed later. To unlock, all uses of a property must be deleted."] + :class "tippy-hover ml-2" + :interactive true + :disabled false} + (str property-type-label')) + (str property-type-label')) :disabled? disabled? :submenu-content (fn [ops] (property-type-sub-pane property ops))})) + (when (= property-type :node) + (dropdown-editor-menuitem {:icon :hash + :title "Specify node tags" + :desc "" + :submenu-content (fn [_ops] + [:div.px-4 + (class-select property {:default-open? false})])})) + (when enable-closed-values? (empty? (:property/schema.classes property)) (let [values (:property/closed-values property)] (dropdown-editor-menuitem {:icon :list :title "Available choices" @@ -448,8 +545,8 @@ (when owner-block (dropdown-editor-menuitem - {:id :remove-property :icon :square-x :title "Delete property" :desc "" :disabled? false - :item-props {:class "opacity-60 focus:opacity-100 focus:!text-red-rx-09" + {:id :remove-property :icon :x :title "Remove property" :desc "" :disabled? false + :item-props {:class "opacity-60 focus:!text-red-rx-09 focus:opacity-100" :on-select (fn [^js e] (util/stop e) (-> (p/do!