feat(wikibase-schema-editor): add qualifiers editor#94
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis change introduces full support for editing, managing, and displaying qualifiers on statements within the Wikibase schema editor. It adds a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant WikibaseSchemaEditor
participant StatementEditor
participant QualifiersEditor
participant SchemaStore
User->>WikibaseSchemaEditor: Edit or add statement
WikibaseSchemaEditor->>StatementEditor: Pass statement (with qualifiers)
StatementEditor->>QualifiersEditor: Pass qualifiers, columns, handlers
User->>QualifiersEditor: Add/Remove/Update qualifier
QualifiersEditor-->>StatementEditor: Emit qualifier event (add/remove/update)
StatementEditor-->>WikibaseSchemaEditor: Emit updated statement (with qualifiers)
WikibaseSchemaEditor->>SchemaStore: Save/update statement with qualifiers
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🔭 Outside diff range comments (2)
frontend/src/components/WikibaseSchemaEditor.vue (1)
263-269: Direct array mutation bypasses store encapsulation.The direct mutation of
schemaStore.statements[statementIndex]bypasses the store's intended API and could cause reactivity or state management issues.Use store methods for statement updates:
- schemaStore.statements[statementIndex] = { - ...schemaStore.statements[statementIndex], - property: currentStatement.property, - value: currentStatement.value, - rank: currentStatement.rank, - qualifiers: currentStatement.qualifiers || [], - } + schemaStore.updateStatement(editingStatementId.value, { + property: currentStatement.property, + value: currentStatement.value, + rank: currentStatement.rank, + qualifiers: currentStatement.qualifiers || [], + })This requires adding an
updateStatementmethod to the schema store if it doesn't exist.frontend/src/stores/schema.store.ts (1)
3-10: Missing import for QualifierSchemaMapping and ReferenceSchemaMapping types.The file uses
QualifierSchemaMappingandReferenceSchemaMappingtypes in function signatures but doesn't import them. Based on the relevant code snippets, these types are defined in@frontend/types/wikibase-schema.Add the missing imports:
import type { StatementSchemaMapping, ColumnMapping, PropertyReference, ValueMapping, StatementRank, Label, + QualifierSchemaMapping, + ReferenceSchemaMapping, } from '@frontend/types/wikibase-schema'
🧹 Nitpick comments (2)
frontend/src/components/WikibaseSchemaEditor.vue (1)
238-251: Consider consolidating state management to avoid duplication.The dual state management approach (maintaining both
currentStatementWithQualifiersand callinginitializeStatement) creates redundancy and potential synchronization issues.Consider either:
- Fully migrating to the new state structure and updating the composable
- Or extending the existing composable to handle qualifiers directly
This would reduce complexity and eliminate the need for backward compatibility bridges.
frontend/src/components/QualifiersEditor.vue (1)
355-355: Direct mutation of reactive object property.The clear column functionality directly mutates
selectedValue.source.columnName, which works but is inconsistent with the pattern used in StatementEditor where a dedicatedhandleClearColumnmethod is used.Consider creating a dedicated method for consistency:
+const handleClearColumn = () => { + if (selectedValue.value?.type === 'column') { + selectedValue.value.source.columnName = '' + } +}Then update the template:
-@click="selectedValue.source.columnName = ''" +@click="handleClearColumn"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.kiro/specs/wikibase-schema-editor/tasks.md(1 hunks)frontend/components.d.ts(1 hunks)frontend/src/components/QualifiersEditor.vue(1 hunks)frontend/src/components/StatementEditor.vue(8 hunks)frontend/src/components/WikibaseSchemaEditor.vue(6 hunks)frontend/src/composables/useSchemaBuilder.ts(1 hunks)frontend/src/stores/__tests__/schema.store.test.ts(1 hunks)frontend/src/stores/schema.store.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
**/*.{ts,tsx,js,jsx}: Usebun <file>instead ofnode <file>orts-node <file>for running TypeScript or JavaScript files
Do not use dotenv; Bun automatically loads .env files
UseBun.serve()for HTTP servers and WebSockets instead ofexpress
Usebun:sqlitefor SQLite instead ofbetter-sqlite3
UseBun.redisfor Redis instead ofioredis
UseBun.sqlfor Postgres instead ofpgorpostgres.js
Use built-inWebSocketinstead ofws
PreferBun.fileovernode:fs's readFile/writeFile
UseBun.$(e.g.,Bun.$ls``) instead of execa for running shell commands
Files:
frontend/components.d.tsfrontend/src/composables/useSchemaBuilder.tsfrontend/src/stores/__tests__/schema.store.test.tsfrontend/src/stores/schema.store.ts
**/*.{html,ts,tsx,css}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun build <file.html|file.ts|file.css>instead ofwebpackoresbuildfor building HTML, TypeScript, or CSS files
Files:
frontend/components.d.tsfrontend/src/composables/useSchemaBuilder.tsfrontend/src/stores/__tests__/schema.store.test.tsfrontend/src/stores/schema.store.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun testinstead ofjestfor running tests
Files:
frontend/src/stores/__tests__/schema.store.test.ts
🧠 Learnings (2)
frontend/components.d.ts (11)
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Props and emits must use explicit TypeScript interfaces
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.{ts,vue} : Type safety everywhere
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Build reusable, well-structured components
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Use auto-imports for Vue, Pinia, composables, and utilities
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Use Vue 3 with Composition API and <script setup lang="ts"> in all Vue components
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Use PrimeVue as the UI library in all Vue components
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Use v-memo, shallowRef, markRaw, and Suspense for performance optimization
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.{vue,ts} : Use readonly and shallowReactive for large or expensive data
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.{vue,ts} : Use Pinia stores for global state
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.{vue,ts} : Handle errors and loading states reactively when making API calls
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.{vue,ts} : Use useApi composable (Elysia Eden) for all API calls
frontend/src/components/QualifiersEditor.vue (2)
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Use Vue 3 with Composition API and <script setup lang="ts"> in all Vue components
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.vue : Props and emits must use explicit TypeScript interfaces
🧬 Code Graph Analysis (2)
frontend/src/composables/useSchemaBuilder.ts (1)
frontend/src/types/wikibase-schema.ts (3)
QualifierSchemaMapping(141-144)ReferenceSchemaMapping(146-149)StatementSchemaMapping(109-116)
frontend/src/stores/schema.store.ts (1)
frontend/src/types/wikibase-schema.ts (2)
QualifierSchemaMapping(141-144)ReferenceSchemaMapping(146-149)
🔇 Additional comments (26)
frontend/components.d.ts (1)
34-34: LGTM! Component declaration follows established pattern.The addition of the
QualifiersEditorcomponent declaration is correctly formatted and consistent with other component declarations in this auto-generated file..kiro/specs/wikibase-schema-editor/tasks.md (1)
114-132: LGTM! Task completion tracking is accurate.The completion of tasks 19, 20, and 21 properly reflects the implementation of the qualifiers editor feature, including:
- Statement rank selection functionality
- QualifiersEditor component creation
- Qualifier value mapping implementation
This aligns well with the PR objectives addressing Tasks 20 and 21 of issue #66.
frontend/src/stores/__tests__/schema.store.test.ts (1)
360-360: LGTM! Test expectation updated correctly for expanded buildStatement signature.The test properly reflects the updated
buildStatementfunction signature that now acceptsqualifiersandreferencesparameters, maintaining accurate test coverage.frontend/src/composables/useSchemaBuilder.ts (1)
78-93: Good API extension design with backward compatibility.The function signature expansion to support qualifiers and references is well-designed:
- Maintains backward compatibility with default empty arrays
- Clean parameter assignment to the returned object
- Follows consistent naming conventions
frontend/src/components/WikibaseSchemaEditor.vue (1)
273-279: Good integration of qualifier support in statement creation.The addition of qualifiers to the
addStatementcall properly extends the functionality while providing sensible defaults.frontend/src/stores/schema.store.ts (5)
96-104: Good implementation of extended addStatement function.The function signature properly defaults the new parameters to empty arrays and correctly passes them to the buildStatement function. This maintains backward compatibility while enabling qualifier support.
124-131: LGTM! Proper implementation of updateStatementQualifiers.The function correctly finds the statement by ID, updates the qualifiers array, and marks the store as dirty. The implementation follows the established pattern used by other update functions in the store.
133-140: LGTM! Proper implementation of addQualifierToStatement.The function correctly finds the statement and appends the qualifier to the qualifiers array. State management is handled appropriately.
142-149: Good bounds checking in removeQualifierFromStatement.The function includes proper bounds checking to prevent array access errors and follows the established pattern for array modifications in the store.
213-215: Verify all new functions are properly exposed.All three new qualifier management functions are correctly included in the store's return object, making them available to components.
frontend/src/components/StatementEditor.vue (8)
8-8: Good TypeScript interface design for qualifiers support.The props interface properly includes the optional qualifiers array with correct typing, and the default value is appropriately set to an empty array.
Also applies to: 26-26
39-39: Consistent emit interface extension.The emit interface correctly includes qualifiers in the update event, maintaining type safety and consistency with the props interface.
92-96: Proper local state management for qualifiers.The temporary statement ID generation using crypto.randomUUID() is appropriate for qualifier management, and the local qualifiers state is properly initialized from props.
100-104: Good state synchronization in emitUpdate.The emit function correctly spreads the local statement and includes the current qualifiers, ensuring parent components receive complete state updates.
157-179: Well-implemented qualifier event handlers.All three qualifier handling methods properly manage the local qualifiers array and emit updates. The bounds checking in handleRemoveQualifier prevents array access errors.
198-205: Proper watcher implementation for qualifiers synchronization.The watcher correctly synchronizes local qualifiers state with prop changes, ensuring the component stays in sync with external updates. The deep watch with immediate execution is appropriate.
425-436: Good integration of QualifiersEditor component.The QualifiersEditor is properly integrated with all necessary props and event handlers. The use of tempStatementId for qualifier management is appropriate.
474-500: Excellent qualifiers preview implementation.The preview section provides clear visual feedback showing qualifier properties, values, and data types. The conditional rendering and consistent styling align well with the existing UI patterns.
frontend/src/components/QualifiersEditor.vue (8)
1-28: Excellent TypeScript interfaces and component setup.The component follows Vue 3 Composition API best practices with explicit TypeScript interfaces for props and emits. The interfaces are well-structured and type-safe, following the established patterns from the retrieved learnings.
49-66: Robust validation logic for qualifiers.The validation functions properly check for property ID format (starting with 'P') and non-empty values. The computed property
canAddQualifiercorrectly combines both validations to control the add button state.
81-93: Smart property change handling with data type suggestion.The
handlePropertyChangefunction intelligently resets the value when the property changes and auto-suggests the appropriate data type based on the property's data type. This provides good UX by reducing manual configuration.
115-131: Good integration with data type compatibility system.The
handleColumnDropfunction properly uses the existinguseDataTypeCompatibilitycomposable to suggest compatible Wikibase data types, ensuring consistency with the rest of the application.
133-143: Proper qualifier creation and emission.The
addQualifierfunction includes validation checks, creates a properly typed qualifier object, emits the event with correct parameters, and cleans up the form state. The implementation is robust and follows good practices.
198-258: Excellent qualifiers list implementation.The existing qualifiers list provides clear visual representation with property tags, value information, and data types. The layout is consistent and includes proper action buttons with tooltips.
260-396: Comprehensive add qualifier form.The form includes proper validation, clear labeling with required field indicators, consistent styling, and good user experience patterns. The conditional rendering based on state is well-implemented.
398-414: User-friendly empty state design.The empty state provides clear guidance to users about what qualifiers are and how to add them. The visual design with icons and descriptive text follows good UX practices.
| qualifiers: QualifierSchemaMapping[] = [], | ||
| references: ReferenceSchemaMapping[] = [], |
There was a problem hiding this comment.
Missing imports for new parameter types.
The function signature uses QualifierSchemaMapping and ReferenceSchemaMapping types that are not imported. This will cause TypeScript compilation errors.
Add the missing imports to the import statement:
import type {
WikibaseSchemaMapping,
ItemSchemaMapping,
TermsSchemaMapping,
StatementSchemaMapping,
+ QualifierSchemaMapping,
+ ReferenceSchemaMapping,
Label,
ColumnMapping,
PropertyReference,
ValueMapping,
StatementRank,
} from '@frontend/types/wikibase-schema'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| qualifiers: QualifierSchemaMapping[] = [], | |
| references: ReferenceSchemaMapping[] = [], | |
| import type { | |
| WikibaseSchemaMapping, | |
| ItemSchemaMapping, | |
| TermsSchemaMapping, | |
| StatementSchemaMapping, | |
| QualifierSchemaMapping, | |
| ReferenceSchemaMapping, | |
| Label, | |
| ColumnMapping, | |
| PropertyReference, | |
| ValueMapping, | |
| StatementRank, | |
| } from '@frontend/types/wikibase-schema' |
🤖 Prompt for AI Agents
In frontend/src/composables/useSchemaBuilder.ts around lines 82 to 83, the types
QualifierSchemaMapping and ReferenceSchemaMapping are used but not imported,
causing TypeScript errors. Fix this by adding import statements for these types
from their respective modules at the top of the file where other imports are
declared.
Addresses Tasks 20, 21 of #66