Skip to content
Open
55 changes: 55 additions & 0 deletions .changeset/deps-list-filter-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
"@comet/cms-admin": major
"@comet/cms-api": major
"@comet/admin": minor
---

Add filtering and sorting to `DependenciesList` and `DependentsList`

Users can now filter dependencies/dependents by name, type, secondary information, and visibility, and sort by all columns. A default filter shows only visible items. The `GqlFilter` type is now exported from `@comet/admin`.

**Breaking changes:**
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deliberately didn't add these changes to the migration guide since I'm 99% sure these apis aren't used in any real project so it would just unnecessarily prolong the guide. But maybe it doesn't matter since the primary target are AI agents.
What do you think, should I add it?


**`@comet/cms-api`:** `DependencyFilter.targetGraphqlObjectType` and `DependentFilter.rootGraphqlObjectType` changed from `string` to `StringFilter`. Update any code passing a plain string to use `{ equal: "..." }` instead.

**`@comet/cms-admin`:** The GQL queries passed to `DependenciesList` and `DependentsList` must now accept `$filter` and `$sort` variables and forward them to the `dependencies`/`dependents` field. Update your queries as follows:

```graphql
# DependentsList
query MyDependents($id: ID!, $offset: Int!, $limit: Int!, $forceRefresh: Boolean = false, $filter: DependentFilter, $sort: [DependencySort!]) {
item: myEntity(id: $id) {
id
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh, filter: $filter, sort: $sort) {
nodes {
rootGraphqlObjectType
rootId
rootColumnName
jsonPath
name
secondaryInformation
visible
}
totalCount
}
}
}

# DependenciesList
query MyDependencies($id: ID!, $offset: Int!, $limit: Int!, $forceRefresh: Boolean = false, $filter: DependencyFilter, $sort: [DependencySort!]) {
item: myEntity(id: $id) {
id
dependencies(offset: $offset, limit: $limit, forceRefresh: $forceRefresh, filter: $filter, sort: $sort) {
nodes {
targetGraphqlObjectType
targetId
rootColumnName
jsonPath
name
secondaryInformation
visible
}
totalCount
}
}
}
```
24 changes: 20 additions & 4 deletions demo/admin/src/documents/pages/EditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,25 @@ interface Props {
}

const pageTreeNodeDependentsQuery = gql`
query PageTreeNodeDependents($id: ID!, $offset: Int!, $limit: Int!, $forceRefresh: Boolean = false) {
query PageTreeNodeDependents(
$id: ID!
$offset: Int!
$limit: Int!
$forceRefresh: Boolean = false
$filter: DependentFilter
$sort: [DependencySort!]
) {
item: pageTreeNode(id: $id) {
id
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh) {
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh, filter: $filter, sort: $sort) {
nodes {
rootGraphqlObjectType
rootId
rootColumnName
jsonPath
name
secondaryInformation
visible
}
totalCount
}
Expand All @@ -56,17 +64,25 @@ const pageTreeNodeDependentsQuery = gql`
`;

const pageTreeNodeDependenciesQuery = gql`
query PageTreeNodeDependencies($id: ID!, $offset: Int!, $limit: Int!, $forceRefresh: Boolean = false) {
query PageTreeNodeDependencies(
$id: ID!
$offset: Int!
$limit: Int!
$forceRefresh: Boolean = false
$filter: DependencyFilter
$sort: [DependencySort!]
) {
item: page(id: $id) {
id
dependencies(offset: $offset, limit: $limit, forceRefresh: $forceRefresh) {
dependencies(offset: $offset, limit: $limit, forceRefresh: $forceRefresh, filter: $filter, sort: $sort) {
nodes {
targetGraphqlObjectType
targetId
rootColumnName
jsonPath
name
secondaryInformation
visible
}
totalCount
}
Expand Down
44 changes: 33 additions & 11 deletions demo/api/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ type DamFile {
contentHash: String!
createdAt: DateTime!
damPath: String!
dependents(filter: DependentFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependents(filter: DependentFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
duplicates: [DamFile!]!
fileUrl: String!
folder: DamFolder
Expand Down Expand Up @@ -542,15 +542,37 @@ type Dependency {
}

input DependencyFilter {
and: [DependencyFilter!]
name: StringFilter
or: [DependencyFilter!]
rootColumnName: String
targetGraphqlObjectType: String
secondaryInformation: StringFilter
targetGraphqlObjectType: StringFilter
targetId: String
visible: BooleanFilter
}

input DependencySort {
direction: SortDirection! = ASC
field: DependencySortField!
}

enum DependencySortField {
graphqlObjectType
name
secondaryInformation
visible
}

input DependentFilter {
and: [DependentFilter!]
name: StringFilter
or: [DependentFilter!]
rootColumnName: String
rootGraphqlObjectType: String
rootGraphqlObjectType: StringFilter
rootId: String
secondaryInformation: StringFilter
visible: BooleanFilter
}

interface DocumentInterface {
Expand Down Expand Up @@ -669,7 +691,7 @@ input FolderFilterInput {
type Footer {
content: FooterContentBlockData!
createdAt: DateTime!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
id: ID!
scope: FooterScope!
updatedAt: DateTime!
Expand Down Expand Up @@ -799,7 +821,7 @@ type MainMenu {
type MainMenuItem {
content: RichTextBlockData
createdAt: DateTime!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
id: ID!
node: PageTreeNode!
updatedAt: DateTime!
Expand Down Expand Up @@ -1011,8 +1033,8 @@ type News {
content: NewsContentBlockData!
createdAt: DateTime!
date: DateTime!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependents(filter: DependentFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
dependents(filter: DependentFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
id: ID!
image: DamImageBlockData!
scope: NewsContentScope!
Expand Down Expand Up @@ -1143,7 +1165,7 @@ input OneToManyFilter {
type Page implements DocumentInterface {
content: PageContentBlockData!
createdAt: DateTime!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
id: ID!
pageTreeNode: PageTreeNode
seo: SeoBlockData!
Expand All @@ -1168,8 +1190,8 @@ input PageInput {
type PageTreeNode {
category: PageTreeNodeCategory!
childNodes: [PageTreeNode!]!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependents(filter: DependentFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
dependents(filter: DependentFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
document: PageContentUnion
documentType: String!
hideInMenu: Boolean!
Expand Down Expand Up @@ -1978,7 +2000,7 @@ type Redirect {
active: Boolean!
comment: String
createdAt: DateTime!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0): PaginatedDependencies!
dependencies(filter: DependencyFilter, forceRefresh: Boolean! = false, limit: Int! = 25, offset: Int! = 0, sort: [DependencySort!]): PaginatedDependencies!
generationType: RedirectGenerationType!
id: ID!
scope: RedirectScope!
Expand Down
5 changes: 4 additions & 1 deletion docs/docs/2-core-concepts/7-dependencies/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,17 +306,20 @@ Each component requires two props:
$offset: Int!
$limit: Int!
$forceRefresh: Boolean = false
$filter: DependentFilter
$sort: [DependencySort!]
) {
item: damFile(id: $id) {
id
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh) {
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh, filter: $filter, sort: $sort) {
nodes {
rootGraphqlObjectType
rootId
rootColumnName
jsonPath
name
secondaryInformation
visible
}
totalCount
}
Expand Down
2 changes: 1 addition & 1 deletion packages/admin/admin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export {
dataGridOneToManyColumn,
} from "./dataGrid/gridColumnTypes";
export { GridFilterButton } from "./dataGrid/GridFilterButton";
export { muiGridFilterToGql } from "./dataGrid/muiGridFilterToGql";
export { type GqlFilter, muiGridFilterToGql } from "./dataGrid/muiGridFilterToGql";
export { muiGridPagingToGql } from "./dataGrid/muiGridPagingToGql";
export { muiGridSortToGql } from "./dataGrid/muiGridSortToGql";
export { DataGridPagination, type DataGridPaginationClassKey, type DataGridPaginationProps } from "./dataGrid/pagination/DataGridPagination";
Expand Down
12 changes: 10 additions & 2 deletions packages/admin/cms-admin/src/dam/FileForm/EditFile.gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,25 @@ export const updateDamFileMutation = gql`
`;

export const damFileDependentsQuery = gql`
query DamFileDependencies($id: ID!, $offset: Int!, $limit: Int!, $forceRefresh: Boolean = false) {
query DamFileDependencies(
$id: ID!
$offset: Int!
$limit: Int!
$forceRefresh: Boolean = false
$filter: DependentFilter
$sort: [DependencySort!]
) {
item: damFile(id: $id) {
id
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh) {
dependents(offset: $offset, limit: $limit, forceRefresh: $forceRefresh, filter: $filter, sort: $sort) {
nodes {
rootGraphqlObjectType
rootId
rootColumnName
jsonPath
name
secondaryInformation
visible
}
totalCount
}
Expand Down
Loading
Loading