-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
feat: allow changing property type #12047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
d9279b9 to
70af283
Compare
|
@tiensonqin l'll add rtc e2e tests soon (tomorrow) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces functionality to allow changing property types by creating a new property when the type changes and marking the old property as deprecated. The feature ensures data integrity by removing old property values while preserving pages and closed values, and includes a new :logseq.property/deprecated? property to track deprecated properties.
- Adds property type change functionality that creates new properties instead of modifying existing ones
- Implements property deprecation system with cleanup of old property data
- Updates UI to handle deprecated properties and provide appropriate visual indicators
Reviewed Changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
deps/outliner/src/logseq/outliner/property.cljs |
Core logic for property type changes, creating new properties and deprecating old ones |
deps/db/src/logseq/db/frontend/property.cljs |
Adds deprecated property detection function |
src/main/frontend/components/property/config.cljs |
Updates property configuration UI to handle type changes |
src/main/frontend/components/property.cljs |
Filters deprecated properties from display |
src/main/frontend/components/page.cljs |
Shows deprecation warning on property pages |
deps/db/src/logseq/db/frontend/db.cljs |
Excludes deprecated properties from all properties queries |
src/main/frontend/worker/search.cljs |
Excludes deprecated properties from search indexing |
src/main/frontend/worker/embedding.cljs |
Excludes deprecated properties from embedding |
deps/outliner/test/logseq/outliner/property_test.cljs |
Updates tests for new property type change behavior |
clj-e2e/test/logseq/e2e/property_basic_test.clj |
Adds E2E tests for property type changes |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| (parse-double v) | ||
| v)] | ||
| (find-or-create-property-value conn property-id v'))))) | ||
| (if (= :logseq.property/empty-placeholder v) |
Copilot
AI
Aug 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The early return for :logseq.property/empty-placeholder should be properly indented and the rest of the function body should be wrapped in the else clause for better readability.
| (exit-edit) | ||
| (when (w/visible? "div[data-radix-popper-content-wrapper]") | ||
| (when (.isVisible (.first (w/-query "div[data-radix-popper-content-wrapper]"))) | ||
| (k/esc))) |
Copilot
AI
Aug 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using .first on a query result without checking if the collection is empty could throw an exception. The original w/visible? function likely handles empty collections safely.
| (k/esc)) | ||
| (exit-edit) | ||
| (when (w/visible? "div[data-radix-popper-content-wrapper]") | ||
| (when (.isVisible (.first (w/-query "div[data-radix-popper-content-wrapper]"))) |
Copilot
AI
Aug 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using .first on a query result without checking if the collection is empty could throw an exception. The original w/visible? function likely handles empty collections safely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tiensonqin Great to see users will be able to change the property type. Only had time to skim code so left some comments. Also one question: Is there a way for us to debug the previous idents of a property type change? Could be useful to have if these changes cause bugs later or if users want to know how their property has changed
| (assoc :db/valueType :db.type/ref))] | ||
| (and new-type old-ref-type? (not ref-type?)) | ||
| (conj [:db/retract (:db/id property) :db/valueType])))) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of change in this heavily used ns which could cause critical bugs. Would be nice if more of it was tested e.g. retraction. I could try to do this next week if no one else does
| :logseq.property/public? {:title "Property public?" | ||
| :schema {:type :checkbox | ||
| :hide? true}} | ||
| :logseq.property/deprecated? {:title "Property already deprecated?" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| :logseq.property/deprecated? {:title "Property already deprecated?" | |
| :logseq.property/deprecated? {:title "Property deprecated?" |
| (get-in built-in-properties [db-ident :schema :type]))) | ||
|
|
||
| (defn deprecated? | ||
| "Whether the property has been deprecated" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be used later for deprecating other built-in entities like pages or classes? If so, it would be worth generalizing the description and arg
| (when (or (map? page) (de/entity? page)) | ||
| (:logseq.property/hide? page)))))) | ||
| (or (:logseq.property/hide? page) | ||
| (:logseq.property/deprecated? page))))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be worth grepping all uses of :logseq.property/hide? and see if deprecated? belongs there as well
| (route-handler/redirect-to-page! (:block/uuid new-property))) | ||
| ;; set value to empty | ||
| (when owner-block | ||
| (db-property-handler/set-block-property! (:db/id owner-block) (:db/ident new-property) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the property type changes, what happens to all previous uses of the property? Do they become read-only or deleted? Do the results of some property queries change? Could be useful to display a confirmation dialog explaining what will happen so users understand and confirm they want the change
|
I tested some behaviors related to this PR and found some issues:
|
This PR allows to change user property's type to any other type.
How it works:
Changing property type will create a new property and mark the old one as
deprecated.It also remove old property kvs, history blocks and value blocks that're not pages or closed values.
New property:
:logseq.property/deprecated?Screenshot:
