Skip to content

Commit 2918b33

Browse files
committed
Add parent and menu_order fields to list metadata items
Support hierarchical post types (pages, custom post types) by storing parent ID and menu order in metadata. These fields enable proper hierarchy display and ordering in the UI. Changes: - Add `parent` and `menu_order` columns to `list_metadata_items` table - Add fields to `DbListMetadataItem`, `ListMetadataItemInput`, and `EntityMetadata` - Update `fetch_posts_metadata()` to request and extract `Parent` and `MenuOrder` fields - Thread new fields through `MetadataService` read/write operations
1 parent d93a5fb commit 2918b33

File tree

7 files changed

+123
-19
lines changed

7 files changed

+123
-19
lines changed

wp_mobile/src/service/metadata.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl MetadataService {
8383
let modified_gmt = item
8484
.modified_gmt
8585
.and_then(|s| s.parse::<WpGmtDateTime>().ok());
86-
EntityMetadata::new(item.entity_id, modified_gmt)
86+
EntityMetadata::new(item.entity_id, modified_gmt, item.parent, item.menu_order)
8787
})
8888
.collect();
8989

@@ -165,6 +165,8 @@ impl MetadataService {
165165
.map(|m| ListMetadataItemInput {
166166
entity_id: m.id,
167167
modified_gmt: m.modified_gmt.as_ref().map(|dt| dt.to_string()),
168+
parent: m.parent,
169+
menu_order: m.menu_order,
168170
})
169171
.collect();
170172

@@ -186,6 +188,8 @@ impl MetadataService {
186188
.map(|m| ListMetadataItemInput {
187189
entity_id: m.id,
188190
modified_gmt: m.modified_gmt.as_ref().map(|dt| dt.to_string()),
191+
parent: m.parent,
192+
menu_order: m.menu_order,
189193
})
190194
.collect();
191195

@@ -467,9 +471,9 @@ mod tests {
467471
fn test_set_and_get_items(test_ctx: TestContext) {
468472
let key = "edit:posts:publish";
469473
let metadata = vec![
470-
EntityMetadata::new(100, None),
471-
EntityMetadata::new(200, None),
472-
EntityMetadata::new(300, None),
474+
EntityMetadata::new(100, None, None, None),
475+
EntityMetadata::new(200, None, None, None),
476+
EntityMetadata::new(300, None, None, None),
473477
];
474478

475479
test_ctx.service.set_items(key, &metadata).unwrap();
@@ -486,15 +490,21 @@ mod tests {
486490
.service
487491
.set_items(
488492
key,
489-
&[EntityMetadata::new(1, None), EntityMetadata::new(2, None)],
493+
&[
494+
EntityMetadata::new(1, None, None, None),
495+
EntityMetadata::new(2, None, None, None),
496+
],
490497
)
491498
.unwrap();
492499

493500
test_ctx
494501
.service
495502
.set_items(
496503
key,
497-
&[EntityMetadata::new(10, None), EntityMetadata::new(20, None)],
504+
&[
505+
EntityMetadata::new(10, None, None, None),
506+
EntityMetadata::new(20, None, None, None),
507+
],
498508
)
499509
.unwrap();
500510

@@ -508,14 +518,17 @@ mod tests {
508518

509519
test_ctx
510520
.service
511-
.set_items(key, &[EntityMetadata::new(1, None)])
521+
.set_items(key, &[EntityMetadata::new(1, None, None, None)])
512522
.unwrap();
513523

514524
test_ctx
515525
.service
516526
.append_items(
517527
key,
518-
&[EntityMetadata::new(2, None), EntityMetadata::new(3, None)],
528+
&[
529+
EntityMetadata::new(2, None, None, None),
530+
EntityMetadata::new(3, None, None, None),
531+
],
519532
)
520533
.unwrap();
521534

@@ -633,7 +646,7 @@ mod tests {
633646

634647
test_ctx
635648
.service
636-
.set_items(key, &[EntityMetadata::new(1, None)])
649+
.set_items(key, &[EntityMetadata::new(1, None, None, None)])
637650
.unwrap();
638651
test_ctx
639652
.service
@@ -650,8 +663,8 @@ mod tests {
650663
fn test_list_metadata_reader_trait(test_ctx: TestContext) {
651664
let key = "edit:posts:publish";
652665
let metadata = vec![
653-
EntityMetadata::new(100, None),
654-
EntityMetadata::new(200, None),
666+
EntityMetadata::new(100, None, None, None),
667+
EntityMetadata::new(200, None, None, None),
655668
];
656669

657670
test_ctx.service.set_items(key, &metadata).unwrap();

wp_mobile/src/service/posts.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ impl PostService {
180180
&[
181181
SparseAnyPostFieldWithEditContext::Id,
182182
SparseAnyPostFieldWithEditContext::ModifiedGmt,
183+
SparseAnyPostFieldWithEditContext::Parent,
184+
SparseAnyPostFieldWithEditContext::MenuOrder,
183185
],
184186
)
185187
.await?;
@@ -188,7 +190,14 @@ impl PostService {
188190
let metadata: Vec<EntityMetadata> = response
189191
.data
190192
.into_iter()
191-
.filter_map(|sparse| Some(EntityMetadata::new(sparse.id?.0, sparse.modified_gmt)))
193+
.filter_map(|sparse| {
194+
Some(EntityMetadata::new(
195+
sparse.id?.0,
196+
sparse.modified_gmt,
197+
sparse.parent.map(|p| p.0),
198+
sparse.menu_order.map(|m| m as i64),
199+
))
200+
})
192201
.collect();
193202

194203
Ok(MetadataFetchResult::new(

wp_mobile/src/sync/entity_metadata.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,41 @@ use wp_api::prelude::WpGmtDateTime;
88
/// The `modified_gmt` is optional because some entity types (e.g., Comments)
99
/// don't have this field. For those entities, staleness is determined via
1010
/// other means (e.g., `last_fetched_at` in the database).
11+
///
12+
/// For hierarchical post types (like pages), `parent` and `menu_order` are
13+
/// also stored to support proper ordering and hierarchy display.
1114
#[derive(Debug, Clone, PartialEq, Eq)]
1215
pub struct EntityMetadata {
1316
pub id: i64,
1417
pub modified_gmt: Option<WpGmtDateTime>,
18+
/// Parent entity ID (for hierarchical post types like pages)
19+
pub parent: Option<i64>,
20+
/// Menu order (for hierarchical post types)
21+
pub menu_order: Option<i64>,
1522
}
1623

1724
impl EntityMetadata {
18-
pub fn new(id: i64, modified_gmt: Option<WpGmtDateTime>) -> Self {
19-
Self { id, modified_gmt }
25+
pub fn new(
26+
id: i64,
27+
modified_gmt: Option<WpGmtDateTime>,
28+
parent: Option<i64>,
29+
menu_order: Option<i64>,
30+
) -> Self {
31+
Self {
32+
id,
33+
modified_gmt,
34+
parent,
35+
menu_order,
36+
}
2037
}
2138

2239
/// Create metadata with a known modified timestamp.
2340
pub fn with_modified(id: i64, modified_gmt: WpGmtDateTime) -> Self {
2441
Self {
2542
id,
2643
modified_gmt: Some(modified_gmt),
44+
parent: None,
45+
menu_order: None,
2746
}
2847
}
2948

@@ -34,6 +53,8 @@ impl EntityMetadata {
3453
Self {
3554
id,
3655
modified_gmt: None,
56+
parent: None,
57+
menu_order: None,
3758
}
3859
}
3960
}
@@ -45,21 +66,25 @@ mod tests {
4566
#[test]
4667
fn test_new_with_modified() {
4768
let modified = WpGmtDateTime::from_timestamp(1000);
48-
let metadata = EntityMetadata::new(42, Some(modified));
69+
let metadata = EntityMetadata::new(42, Some(modified), Some(10), Some(5));
4970

5071
assert_eq!(metadata.id, 42);
5172
assert_eq!(
5273
metadata.modified_gmt,
5374
Some(WpGmtDateTime::from_timestamp(1000))
5475
);
76+
assert_eq!(metadata.parent, Some(10));
77+
assert_eq!(metadata.menu_order, Some(5));
5578
}
5679

5780
#[test]
5881
fn test_new_without_modified() {
59-
let metadata = EntityMetadata::new(42, None);
82+
let metadata = EntityMetadata::new(42, None, None, None);
6083

6184
assert_eq!(metadata.id, 42);
6285
assert_eq!(metadata.modified_gmt, None);
86+
assert_eq!(metadata.parent, None);
87+
assert_eq!(metadata.menu_order, None);
6388
}
6489

6590
#[test]
@@ -69,6 +94,8 @@ mod tests {
6994

7095
assert_eq!(metadata.id, 42);
7196
assert!(metadata.modified_gmt.is_some());
97+
assert!(metadata.parent.is_none());
98+
assert!(metadata.menu_order.is_none());
7299
}
73100

74101
#[test]
@@ -77,5 +104,7 @@ mod tests {
77104

78105
assert_eq!(metadata.id, 42);
79106
assert!(metadata.modified_gmt.is_none());
107+
assert!(metadata.parent.is_none());
108+
assert!(metadata.menu_order.is_none());
80109
}
81110
}

wp_mobile_cache/migrations/0007-create-list-metadata-tables.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ CREATE TABLE `list_metadata_items` (
2323
`key` TEXT NOT NULL,
2424
`entity_id` INTEGER NOT NULL, -- post/comment/etc ID
2525
`modified_gmt` TEXT, -- nullable for entities without it
26+
`parent` INTEGER, -- parent post ID (for hierarchical post types like pages)
27+
`menu_order` INTEGER, -- menu order (for hierarchical post types)
2628

2729
FOREIGN KEY (db_site_id) REFERENCES db_sites(id) ON DELETE CASCADE
2830
) STRICT;

wp_mobile_cache/src/db_types/db_list_metadata.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub enum ListMetadataItemColumn {
5858
Key = 2,
5959
EntityId = 3,
6060
ModifiedGmt = 4,
61+
Parent = 5,
62+
MenuOrder = 6,
6163
}
6264

6365
impl ColumnIndex for ListMetadataItemColumn {
@@ -77,6 +79,8 @@ impl DbListMetadataItem {
7779
key: row.get_column(Col::Key)?,
7880
entity_id: row.get_column(Col::EntityId)?,
7981
modified_gmt: row.get_column(Col::ModifiedGmt)?,
82+
parent: row.get_column(Col::Parent)?,
83+
menu_order: row.get_column(Col::MenuOrder)?,
8084
})
8185
}
8286
}

wp_mobile_cache/src/list_metadata.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ pub struct DbListMetadataItem {
4242
pub entity_id: i64,
4343
/// Last modified timestamp (for staleness detection)
4444
pub modified_gmt: Option<String>,
45+
/// Parent entity ID (for hierarchical post types like pages)
46+
pub parent: Option<i64>,
47+
/// Menu order (for hierarchical post types)
48+
pub menu_order: Option<i64>,
4549
}
4650

4751
/// Represents sync state for a list metadata.

0 commit comments

Comments
 (0)