Fix data pages permissions handling
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<2000fd2ccfcf4b832c51ff71b0326fef>>
|
||||
* @generated SignedSource<<bfe5e85608cbcd0fd0db44ad909ac493>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -322,6 +322,32 @@ return {
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:update"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:update\")"
|
||||
},
|
||||
{
|
||||
"alias": "canDelete",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:delete"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:delete\")"
|
||||
},
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -411,16 +437,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "dbca2ff147e8b1e367a266fcf016b184",
|
||||
"cacheID": "c022cb17d3ede74899755b606ce95ba9",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DataListQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query DataListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $order: DatumOrder = null\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...DataPageFragment_25MC8O\n id\n }\n}\n\nfragment DataPageFragment_25MC8O on Organization {\n data(first: $first, after: $after, last: $last, before: $before, orderBy: $order, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n name\n dataClassification\n owner {\n fullName\n id\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
|
||||
"text": "query DataListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $order: DatumOrder = null\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...DataPageFragment_25MC8O\n id\n }\n}\n\nfragment DataPageFragment_25MC8O on Organization {\n data(first: $first, after: $after, last: $last, before: $before, orderBy: $order, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n name\n dataClassification\n owner {\n fullName\n id\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:datum:update\")\n canDelete: permission(action: \"core:datum:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5d3069a0d856613ccb854033b5b1f14e";
|
||||
(node as any).hash = "9a4453365a733d298ab9f5237fc4153b";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<9619ee8f74aea67be931f8c40a8815c8>>
|
||||
* @generated SignedSource<<213dd4c7bd0e87ba0e64fa6ce8d2c37b>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -16,6 +16,8 @@ export type DataPageFragment$data = {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly canDelete: boolean;
|
||||
readonly canUpdate: boolean;
|
||||
readonly createdAt: any;
|
||||
readonly dataClassification: DataClassification;
|
||||
readonly id: string;
|
||||
@@ -248,6 +250,32 @@ return {
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:update"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:update\")"
|
||||
},
|
||||
{
|
||||
"alias": "canDelete",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:delete"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:delete\")"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -329,6 +357,6 @@ return {
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5d3069a0d856613ccb854033b5b1f14e";
|
||||
(node as any).hash = "9a4453365a733d298ab9f5237fc4153b";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<43b67fe6155860e492f2a36543727d49>>
|
||||
* @generated SignedSource<<8106bb4a10940caebf1f523fb6136350>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -25,6 +25,8 @@ export type DatumGraphCreateMutation$data = {
|
||||
readonly createDatum: {
|
||||
readonly datumEdge: {
|
||||
readonly node: {
|
||||
readonly canDelete: boolean;
|
||||
readonly canUpdate: boolean;
|
||||
readonly createdAt: any;
|
||||
readonly dataClassification: DataClassification;
|
||||
readonly id: string;
|
||||
@@ -181,6 +183,32 @@ v5 = {
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:update"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:update\")"
|
||||
},
|
||||
{
|
||||
"alias": "canDelete",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:delete"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:delete\")"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -254,16 +282,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "23ff315b0cc090bcaca7739d945d8d1b",
|
||||
"cacheID": "37d345acfe37d5edf653d021f8aad43c",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DatumGraphCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation DatumGraphCreateMutation(\n $input: CreateDatumInput!\n) {\n createDatum(input: $input) {\n datumEdge {\n node {\n id\n name\n dataClassification\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n }\n }\n }\n}\n"
|
||||
"text": "mutation DatumGraphCreateMutation(\n $input: CreateDatumInput!\n) {\n createDatum(input: $input) {\n datumEdge {\n node {\n id\n name\n dataClassification\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:datum:update\")\n canDelete: permission(action: \"core:datum:delete\")\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "b148ef55d18d3a45c04b5072581f2285";
|
||||
(node as any).hash = "db4781176e1b58224619f8237af92716";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<7e67f2a3d41fbea46b7b8447595302a5>>
|
||||
* @generated SignedSource<<034a68d54259fb22cf2d563699ad4257>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -16,6 +16,7 @@ export type DatumGraphListQuery$variables = {
|
||||
};
|
||||
export type DatumGraphListQuery$data = {
|
||||
readonly node: {
|
||||
readonly canCreateDatum?: boolean;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"DataPageFragment">;
|
||||
};
|
||||
};
|
||||
@@ -44,30 +45,43 @@ v1 = [
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v2 = [
|
||||
v2 = {
|
||||
"alias": "canCreateDatum",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:create"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:create\")"
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "snapshotId",
|
||||
"variableName": "snapshotId"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = [
|
||||
v6 = [
|
||||
{
|
||||
"fields": (v2/*: any*/),
|
||||
"fields": (v3/*: any*/),
|
||||
"kind": "ObjectValue",
|
||||
"name": "filter"
|
||||
},
|
||||
@@ -77,7 +91,7 @@ v5 = [
|
||||
"value": 10
|
||||
}
|
||||
],
|
||||
v6 = {
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
@@ -102,8 +116,9 @@ return {
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"args": (v2/*: any*/),
|
||||
"args": (v3/*: any*/),
|
||||
"kind": "FragmentSpread",
|
||||
"name": "DataPageFragment"
|
||||
}
|
||||
@@ -132,14 +147,15 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"args": (v6/*: any*/),
|
||||
"concreteType": "DatumConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "data",
|
||||
@@ -161,8 +177,8 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v4/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v7/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -185,7 +201,7 @@ return {
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
(v4/*: any*/)
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -219,8 +235,8 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v4/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v7/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -244,7 +260,33 @@ return {
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/)
|
||||
{
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:update"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:update\")"
|
||||
},
|
||||
{
|
||||
"alias": "canDelete",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:delete"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:delete\")"
|
||||
},
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -314,7 +356,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"args": (v6/*: any*/),
|
||||
"filters": [
|
||||
"filter"
|
||||
],
|
||||
@@ -333,16 +375,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "7200b7cf37859346d740de3f96f1d443",
|
||||
"cacheID": "203f6661d76c730336cffaa96b631ab8",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DatumGraphListQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query DatumGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID = null\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...DataPageFragment_3iomuz\n }\n id\n }\n}\n\nfragment DataPageFragment_3iomuz on Organization {\n data(first: 10, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n name\n dataClassification\n owner {\n fullName\n id\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
|
||||
"text": "query DatumGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID = null\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n canCreateDatum: permission(action: \"core:datum:create\")\n ...DataPageFragment_3iomuz\n }\n id\n }\n}\n\nfragment DataPageFragment_3iomuz on Organization {\n data(first: 10, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n name\n dataClassification\n owner {\n fullName\n id\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:datum:update\")\n canDelete: permission(action: \"core:datum:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "e0782332e7e82bd1a5e7f5e40ada2dae";
|
||||
(node as any).hash = "e071e19eda0d4c105668ffd9671399bd";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<5cfbdbc980894977800a18064306f2c1>>
|
||||
* @generated SignedSource<<e2ff7cc39a32a043a4d4c2ad4dac8411>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -16,6 +16,8 @@ export type DatumGraphNodeQuery$variables = {
|
||||
};
|
||||
export type DatumGraphNodeQuery$data = {
|
||||
readonly node: {
|
||||
readonly canDelete?: boolean;
|
||||
readonly canUpdate?: boolean;
|
||||
readonly createdAt?: any;
|
||||
readonly dataClassification?: DataClassification;
|
||||
readonly id?: string;
|
||||
@@ -188,6 +190,32 @@ v10 = {
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v11 = {
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:update"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:update\")"
|
||||
},
|
||||
v12 = {
|
||||
"alias": "canDelete",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:datum:delete"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:datum:delete\")"
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
@@ -215,7 +243,9 @@ return {
|
||||
(v7/*: any*/),
|
||||
(v8/*: any*/),
|
||||
(v9/*: any*/),
|
||||
(v10/*: any*/)
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/)
|
||||
],
|
||||
"type": "Datum",
|
||||
"abstractKey": null
|
||||
@@ -259,7 +289,9 @@ return {
|
||||
(v7/*: any*/),
|
||||
(v8/*: any*/),
|
||||
(v9/*: any*/),
|
||||
(v10/*: any*/)
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/)
|
||||
],
|
||||
"type": "Datum",
|
||||
"abstractKey": null
|
||||
@@ -270,16 +302,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "6ed49a3413c0214dc95da9a422e484b4",
|
||||
"cacheID": "036588bb9b3daffb20c9d01a708976ac",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DatumGraphNodeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query DatumGraphNodeQuery(\n $dataId: ID!\n) {\n node(id: $dataId) {\n __typename\n ... on Datum {\n id\n snapshotId\n name\n dataClassification\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n organization {\n id\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n"
|
||||
"text": "query DatumGraphNodeQuery(\n $dataId: ID!\n) {\n node(id: $dataId) {\n __typename\n ... on Datum {\n id\n snapshotId\n name\n dataClassification\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n organization {\n id\n }\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:datum:update\")\n canDelete: permission(action: \"core:datum:delete\")\n }\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "2f4df20b67f8b21eda5f510f250abda1";
|
||||
(node as any).hash = "2b2e220e0bdd98bbee7ea72a00db7a61";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -8,6 +8,7 @@ export const dataQuery = graphql`
|
||||
query DatumGraphListQuery($organizationId: ID!, $snapshotId: ID = null) {
|
||||
node(id: $organizationId) {
|
||||
... on Organization {
|
||||
canCreateDatum: permission(action: "core:datum:create")
|
||||
...DataPageFragment @arguments(snapshotId: $snapshotId)
|
||||
}
|
||||
}
|
||||
@@ -41,6 +42,8 @@ export const datumNodeQuery = graphql`
|
||||
}
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "core:datum:update")
|
||||
canDelete: permission(action: "core:datum:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,6 +74,8 @@ export const createDatumMutation = graphql`
|
||||
}
|
||||
}
|
||||
createdAt
|
||||
canUpdate: permission(action: "core:datum:update")
|
||||
canDelete: permission(action: "core:datum:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +121,7 @@ export const deleteDatumMutation = graphql`
|
||||
|
||||
export const useDeleteDatum = (
|
||||
datum: { id?: string; name?: string },
|
||||
connectionId: string
|
||||
connectionId: string,
|
||||
) => {
|
||||
const [mutate] = useMutation(deleteDatumMutation);
|
||||
const confirm = useConfirm();
|
||||
@@ -139,11 +144,11 @@ export const useDeleteDatum = (
|
||||
{
|
||||
message: sprintf(
|
||||
__(
|
||||
'This will permanently delete "%s". This action cannot be undone.'
|
||||
'This will permanently delete "%s". This action cannot be undone.',
|
||||
),
|
||||
datum.name
|
||||
datum.name,
|
||||
),
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -35,8 +35,6 @@ import type {
|
||||
import type { DataListQuery } from "/__generated__/core/DataListQuery.graphql";
|
||||
import { SortableTable } from "/components/SortableTable";
|
||||
import { SnapshotBanner } from "/components/SnapshotBanner";
|
||||
import { use } from "react";
|
||||
import { PermissionsContext } from "/providers/PermissionsContext";
|
||||
|
||||
const paginatedDataFragment = graphql`
|
||||
fragment DataPageFragment on Organization
|
||||
@@ -76,6 +74,8 @@ const paginatedDataFragment = graphql`
|
||||
}
|
||||
}
|
||||
createdAt
|
||||
canUpdate: permission(action: "core:datum:update")
|
||||
canDelete: permission(action: "core:datum:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,15 +93,12 @@ export default function DataPage(props: Props) {
|
||||
const organizationId = useOrganizationId();
|
||||
const { snapshotId } = useParams<{ snapshotId?: string }>();
|
||||
const isSnapshotMode = Boolean(snapshotId);
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
const queryData = usePreloadedQuery<DatumGraphListQuery>(
|
||||
const { node: data } = usePreloadedQuery<DatumGraphListQuery>(
|
||||
dataQuery,
|
||||
props.queryRef,
|
||||
);
|
||||
|
||||
const data = queryData.node;
|
||||
|
||||
const pagination = usePaginationFragment<DataListQuery, DataPageFragment$key>(
|
||||
paginatedDataFragment,
|
||||
data,
|
||||
@@ -128,8 +125,7 @@ export default function DataPage(props: Props) {
|
||||
|
||||
const hasAnyAction =
|
||||
!isSnapshotMode &&
|
||||
(isAuthorized("Datum", "updateDatum") ||
|
||||
isAuthorized("Datum", "deleteDatum"));
|
||||
dataEntries.some(({ canDelete, canUpdate }) => canUpdate || canDelete);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
@@ -142,7 +138,7 @@ export default function DataPage(props: Props) {
|
||||
"Manage your organization's data assets and their classifications.",
|
||||
)}
|
||||
>
|
||||
{!snapshotId && isAuthorized("Organization", "createDatum") && (
|
||||
{!snapshotId && data.canCreateDatum && (
|
||||
<CreateDatumDialog
|
||||
connection={connectionId}
|
||||
organizationId={organizationId}
|
||||
@@ -193,7 +189,6 @@ function DataRow({
|
||||
const { __ } = useTranslate();
|
||||
const deleteDatum = useDeleteDatum(entry, connectionId);
|
||||
const vendors = entry.vendors?.edges.map((edge) => edge.node) ?? [];
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
const detailUrl = snapshotId
|
||||
? `/organizations/${organizationId}/snapshots/${snapshotId}/data/${entry.id}`
|
||||
: `/organizations/${organizationId}/data/${entry.id}`;
|
||||
@@ -235,7 +230,7 @@ function DataRow({
|
||||
{hasAnyAction && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<ActionDropdown>
|
||||
{isAuthorized("Datum", "deleteDatum") && (
|
||||
{entry.canDelete && (
|
||||
<DropdownItem
|
||||
onClick={deleteDatum}
|
||||
variant="danger"
|
||||
|
||||
@@ -29,8 +29,6 @@ import z from "zod";
|
||||
import { SnapshotBanner } from "/components/SnapshotBanner";
|
||||
import { validateSnapshotConsistency } from "@probo/helpers";
|
||||
import type { DatumGraphNodeQuery } from "/__generated__/core/DatumGraphNodeQuery.graphql";
|
||||
import { use } from "react";
|
||||
import { PermissionsContext } from "/providers/PermissionsContext";
|
||||
|
||||
const updateDatumSchema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
@@ -58,7 +56,6 @@ export default function DatumDetailsPage(props: Props) {
|
||||
|
||||
const { __ } = useTranslate();
|
||||
const organizationId = useOrganizationId();
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
const deleteDatum = useDeleteDatum(
|
||||
datumEntry,
|
||||
@@ -112,6 +109,8 @@ export default function DatumDetailsPage(props: Props) {
|
||||
},
|
||||
];
|
||||
|
||||
const disabled = !isSnapshotMode && datumEntry.canUpdate;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{isSnapshotMode && snapshotId && (
|
||||
@@ -124,7 +123,7 @@ export default function DatumDetailsPage(props: Props) {
|
||||
<div className="text-2xl">{datumEntry?.name}</div>
|
||||
<Badge variant="info">{datumEntry?.dataClassification}</Badge>
|
||||
</div>
|
||||
{!isSnapshotMode && isAuthorized("Datum", "deleteDatum") && (
|
||||
{!isSnapshotMode && datumEntry.canDelete && (
|
||||
<ActionDropdown variant="secondary">
|
||||
<DropdownItem
|
||||
variant="danger"
|
||||
@@ -142,7 +141,7 @@ export default function DatumDetailsPage(props: Props) {
|
||||
label={__("Name")}
|
||||
{...register("name")}
|
||||
type="text"
|
||||
disabled={isSnapshotMode}
|
||||
disabled={!disabled}
|
||||
/>
|
||||
|
||||
<ControlledField
|
||||
@@ -150,7 +149,7 @@ export default function DatumDetailsPage(props: Props) {
|
||||
name="dataClassification"
|
||||
type="select"
|
||||
label={__("Classification")}
|
||||
disabled={isSnapshotMode}
|
||||
disabled={!disabled}
|
||||
>
|
||||
<Option value="PUBLIC">{__("Public")}</Option>
|
||||
<Option value="INTERNAL">{__("Internal")}</Option>
|
||||
@@ -163,7 +162,7 @@ export default function DatumDetailsPage(props: Props) {
|
||||
control={control}
|
||||
name="ownerId"
|
||||
label={__("Owner")}
|
||||
disabled={isSnapshotMode}
|
||||
disabled={!disabled}
|
||||
/>
|
||||
|
||||
<VendorsMultiSelectField
|
||||
@@ -171,13 +170,13 @@ export default function DatumDetailsPage(props: Props) {
|
||||
control={control}
|
||||
name="vendorIds"
|
||||
label={__("Vendors")}
|
||||
disabled={isSnapshotMode}
|
||||
disabled={!disabled}
|
||||
selectedVendors={vendors}
|
||||
/>
|
||||
|
||||
{!isSnapshotMode && (
|
||||
<div className="flex justify-end">
|
||||
{formState.isDirty && isAuthorized("Datum", "updateDatum") && (
|
||||
{formState.isDirty && datumEntry.canUpdate && (
|
||||
<Button type="submit" disabled={formState.isSubmitting}>
|
||||
{formState.isSubmitting ? __("Updating...") : __("Update")}
|
||||
</Button>
|
||||
|
||||
@@ -4972,6 +4972,8 @@ type Datum implements Node
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
input DatumOrder
|
||||
|
||||
@@ -494,6 +494,7 @@ type ComplexityRoot struct {
|
||||
Name func(childComplexity int) int
|
||||
Organization func(childComplexity int) int
|
||||
Owner func(childComplexity int) int
|
||||
Permission func(childComplexity int, action string) int
|
||||
SnapshotID func(childComplexity int) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) int
|
||||
@@ -2005,6 +2006,8 @@ type DatumResolver interface {
|
||||
Owner(ctx context.Context, obj *types.Datum) (*types.People, error)
|
||||
Vendors(ctx context.Context, obj *types.Datum, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error)
|
||||
Organization(ctx context.Context, obj *types.Datum) (*types.Organization, error)
|
||||
|
||||
Permission(ctx context.Context, obj *types.Datum, action string) (bool, error)
|
||||
}
|
||||
type DatumConnectionResolver interface {
|
||||
TotalCount(ctx context.Context, obj *types.DatumConnection) (int, error)
|
||||
@@ -3709,6 +3712,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
}
|
||||
|
||||
return e.complexity.Datum.Owner(childComplexity), true
|
||||
case "Datum.permission":
|
||||
if e.complexity.Datum.Permission == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Datum_permission_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Datum.Permission(childComplexity, args["action"].(string)), true
|
||||
case "Datum.snapshotId":
|
||||
if e.complexity.Datum.SnapshotID == nil {
|
||||
break
|
||||
@@ -15314,6 +15328,8 @@ type Datum implements Node
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
input DatumOrder
|
||||
@@ -15876,6 +15892,17 @@ func (ec *executionContext) field_DataProtectionImpactAssessment_permission_args
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Datum_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||
var err error
|
||||
args := map[string]any{}
|
||||
arg0, err := graphql.ProcessArgField(ctx, rawArgs, "action", ec.unmarshalNString2string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args["action"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Datum_vendors_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||
var err error
|
||||
args := map[string]any{}
|
||||
@@ -26455,6 +26482,47 @@ func (ec *executionContext) fieldContext_Datum_updatedAt(_ context.Context, fiel
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Datum_permission(ctx context.Context, field graphql.CollectedField, obj *types.Datum) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_Datum_permission,
|
||||
func(ctx context.Context) (any, error) {
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Datum().Permission(ctx, obj, fc.Args["action"].(string))
|
||||
},
|
||||
nil,
|
||||
ec.marshalNBoolean2bool,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Datum_permission(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Datum",
|
||||
Field: field,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type Boolean does not have child fields")
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = ec.Recover(ctx, r)
|
||||
ec.Error(ctx, err)
|
||||
}
|
||||
}()
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
if fc.Args, err = ec.field_Datum_permission_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return fc, err
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _DatumConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *types.DatumConnection) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
@@ -26629,6 +26697,8 @@ func (ec *executionContext) fieldContext_DatumEdge_node(_ context.Context, field
|
||||
return ec.fieldContext_Datum_createdAt(ctx, field)
|
||||
case "updatedAt":
|
||||
return ec.fieldContext_Datum_updatedAt(ctx, field)
|
||||
case "permission":
|
||||
return ec.fieldContext_Datum_permission(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type Datum", field.Name)
|
||||
},
|
||||
@@ -53394,6 +53464,8 @@ func (ec *executionContext) fieldContext_UpdateDatumPayload_datum(_ context.Cont
|
||||
return ec.fieldContext_Datum_createdAt(ctx, field)
|
||||
case "updatedAt":
|
||||
return ec.fieldContext_Datum_updatedAt(ctx, field)
|
||||
case "permission":
|
||||
return ec.fieldContext_Datum_permission(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type Datum", field.Name)
|
||||
},
|
||||
@@ -73399,6 +73471,42 @@ func (ec *executionContext) _Datum(ctx context.Context, sel ast.SelectionSet, ob
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "permission":
|
||||
field := field
|
||||
|
||||
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._Datum_permission(ctx, field, obj)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&fs.Invalids, 1)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
if field.Deferrable != nil {
|
||||
dfs, ok := deferred[field.Deferrable.Label]
|
||||
di := 0
|
||||
if ok {
|
||||
dfs.AddField(field)
|
||||
di = len(dfs.Values) - 1
|
||||
} else {
|
||||
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
|
||||
deferred[field.Deferrable.Label] = dfs
|
||||
}
|
||||
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
|
||||
return innerFunc(ctx, dfs)
|
||||
})
|
||||
|
||||
// don't run the out.Concurrently() call below
|
||||
out.Values[i] = graphql.Null
|
||||
continue
|
||||
}
|
||||
|
||||
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
||||
@@ -79,6 +79,9 @@ func NewDatum(d *coredata.Datum) *Datum {
|
||||
Organization: &Organization{
|
||||
ID: d.OrganizationID,
|
||||
},
|
||||
Owner: &People{
|
||||
ID: d.OwnerID,
|
||||
},
|
||||
OrganizationID: d.OrganizationID,
|
||||
Name: d.Name,
|
||||
SnapshotID: d.SnapshotID,
|
||||
|
||||
@@ -702,6 +702,11 @@ func (r *datumResolver) Organization(ctx context.Context, obj *types.Datum) (*ty
|
||||
return types.NewOrganization(org), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *datumResolver) Permission(ctx context.Context, obj *types.Datum, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *datumConnectionResolver) TotalCount(ctx context.Context, obj *types.DatumConnection) (int, error) {
|
||||
r.MustAuthorize(ctx, obj.ParentID, probo.ActionDatumList)
|
||||
|
||||
Reference in New Issue
Block a user