Refactor policies document
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<83cc00d864e6388ef2156203499da849>>
|
||||
* @generated SignedSource<<76057cc6f78c32b15c6e580c7a0c30da>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -124,13 +124,6 @@ return {
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lastUsedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -194,12 +187,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "14e698e7b6edf0afe9cf3398986cd529",
|
||||
"cacheID": "cf6f6f621bdcb1bd24a2dd94f856729f",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "APIKeysPageQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query APIKeysPageQuery {\n viewer {\n ...PersonalAPIKeyListFragment\n id\n }\n}\n\nfragment PersonalAPIKeyListFragment on Identity {\n id\n personalAPIKeys(first: 1000) {\n edges {\n node {\n id\n name\n createdAt\n expiresAt\n lastUsedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
"text": "query APIKeysPageQuery {\n viewer {\n ...PersonalAPIKeyListFragment\n id\n }\n}\n\nfragment PersonalAPIKeyListFragment on Identity {\n id\n personalAPIKeys(first: 1000) {\n edges {\n node {\n id\n ...PersonalAPIKeyRowFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment PersonalAPIKeyRowFragment on PersonalAPIKey {\n id\n name\n createdAt\n expiresAt\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<875eae6f5455a17a1bb8e0590c7acdb0>>
|
||||
* @generated SignedSource<<faeeb8835f77a5251a0311dbac21bfde>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -12,7 +12,6 @@ import { ConcreteRequest } from 'relay-runtime';
|
||||
export type CreatePersonalAPIKeyInput = {
|
||||
expiresAt: any;
|
||||
name: string;
|
||||
organizationIds: ReadonlyArray<string>;
|
||||
};
|
||||
export type PersonalAPIKeyListCreateMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
@@ -25,7 +24,6 @@ export type PersonalAPIKeyListCreateMutation$data = {
|
||||
readonly createdAt: any;
|
||||
readonly expiresAt: any;
|
||||
readonly id: string;
|
||||
readonly lastUsedAt: any | null | undefined;
|
||||
readonly name: string;
|
||||
};
|
||||
};
|
||||
@@ -98,13 +96,6 @@ v3 = {
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lastUsedAt",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -187,16 +178,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "5b1f6109730bd9f261afd6635d568b59",
|
||||
"cacheID": "1ec09abe9f3a61e13ba2deacf1a273fb",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PersonalAPIKeyListCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation PersonalAPIKeyListCreateMutation(\n $input: CreatePersonalAPIKeyInput!\n) {\n createPersonalAPIKey(input: $input) {\n personalAPIKeyEdge {\n node {\n id\n name\n createdAt\n expiresAt\n lastUsedAt\n }\n }\n token\n }\n}\n"
|
||||
"text": "mutation PersonalAPIKeyListCreateMutation(\n $input: CreatePersonalAPIKeyInput!\n) {\n createPersonalAPIKey(input: $input) {\n personalAPIKeyEdge {\n node {\n id\n name\n createdAt\n expiresAt\n }\n }\n token\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "c7e932ad41ff2740e8687b7edb904431";
|
||||
(node as any).hash = "86df62e5e5f2d9f347f41648d7af9c32";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<e518a98137eb07e37499d945991b15ed>>
|
||||
* @generated SignedSource<<bdb7bb502fae96e1eb5b8ae644f8bebf>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -15,11 +15,8 @@ export type PersonalAPIKeyListFragment$data = {
|
||||
readonly personalAPIKeys: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly createdAt: any;
|
||||
readonly expiresAt: any;
|
||||
readonly id: string;
|
||||
readonly lastUsedAt: any | null | undefined;
|
||||
readonly name: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"PersonalAPIKeyRowFragment">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
@@ -86,32 +83,9 @@ return {
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lastUsedAt",
|
||||
"storageKey": null
|
||||
"kind": "FragmentSpread",
|
||||
"name": "PersonalAPIKeyRowFragment"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
@@ -171,6 +145,6 @@ return {
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "70fa6b4e568fc1598b8dc23a030428b5";
|
||||
(node as any).hash = "eac59db5cdb5d77813236a90e7fb4d94";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<7a6fb678e9147fd1810e02bd09d5cef1>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type RevealPersonalAPIKeyTokenInput = {
|
||||
tokenId: string;
|
||||
};
|
||||
export type PersonalAPIKeyListRevealTokenMutation$variables = {
|
||||
input: RevealPersonalAPIKeyTokenInput;
|
||||
};
|
||||
export type PersonalAPIKeyListRevealTokenMutation$data = {
|
||||
readonly revealPersonalAPIKeyToken: {
|
||||
readonly token: string;
|
||||
} | null | undefined;
|
||||
};
|
||||
export type PersonalAPIKeyListRevealTokenMutation = {
|
||||
response: PersonalAPIKeyListRevealTokenMutation$data;
|
||||
variables: PersonalAPIKeyListRevealTokenMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "RevealPersonalAPIKeyTokenPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "revealPersonalAPIKeyToken",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "token",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "PersonalAPIKeyListRevealTokenMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "PersonalAPIKeyListRevealTokenMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "25ffba7c8a69e22dcc46b56a6c8633ed",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PersonalAPIKeyListRevealTokenMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation PersonalAPIKeyListRevealTokenMutation(\n $input: RevealPersonalAPIKeyTokenInput!\n) {\n revealPersonalAPIKeyToken(input: $input) {\n token\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "7dad7ebd6e8086a01b2bac8aa80c532e";
|
||||
|
||||
export default node;
|
||||
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<84eef5bca22c2ad2b73bbe068767e35a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type RevokePersonalAPIKeyInput = {
|
||||
tokenId: string;
|
||||
};
|
||||
export type PersonalAPIKeyListRevokeMutation$variables = {
|
||||
input: RevokePersonalAPIKeyInput;
|
||||
};
|
||||
export type PersonalAPIKeyListRevokeMutation$data = {
|
||||
readonly revokePersonalAPIKey: {
|
||||
readonly success: boolean;
|
||||
} | null | undefined;
|
||||
};
|
||||
export type PersonalAPIKeyListRevokeMutation = {
|
||||
response: PersonalAPIKeyListRevokeMutation$data;
|
||||
variables: PersonalAPIKeyListRevokeMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "RevokePersonalAPIKeyPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "revokePersonalAPIKey",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "success",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "PersonalAPIKeyListRevokeMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "PersonalAPIKeyListRevokeMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "fd05bb0236b583ca54be466cffe8f45b",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PersonalAPIKeyListRevokeMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation PersonalAPIKeyListRevokeMutation(\n $input: RevokePersonalAPIKeyInput!\n) {\n revokePersonalAPIKey(input: $input) {\n success\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "34ef04d19251c479827ca5028346f65b";
|
||||
|
||||
export default node;
|
||||
101
apps/console/src/__generated__/iam/PersonalAPIKeyRowFragment.graphql.ts
generated
Normal file
101
apps/console/src/__generated__/iam/PersonalAPIKeyRowFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @generated SignedSource<<ed51014f8f35d76faaa63c10998610be>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type PersonalAPIKeyRowFragment$data = {
|
||||
readonly createdAt: any;
|
||||
readonly expiresAt: any;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly token?: string | null | undefined;
|
||||
readonly " $fragmentType": "PersonalAPIKeyRowFragment";
|
||||
};
|
||||
export type PersonalAPIKeyRowFragment$key = {
|
||||
readonly " $data"?: PersonalAPIKeyRowFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"PersonalAPIKeyRowFragment">;
|
||||
};
|
||||
|
||||
import PersonalAPIKeyRowRefetchQuery_graphql from './PersonalAPIKeyRowRefetchQuery.graphql';
|
||||
|
||||
const node: ReaderFragment = {
|
||||
"argumentDefinitions": [
|
||||
{
|
||||
"defaultValue": false,
|
||||
"kind": "LocalArgument",
|
||||
"name": "includeToken"
|
||||
}
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"refetch": {
|
||||
"connection": null,
|
||||
"fragmentPathInResult": [
|
||||
"node"
|
||||
],
|
||||
"operation": PersonalAPIKeyRowRefetchQuery_graphql,
|
||||
"identifierInfo": {
|
||||
"identifierField": "id",
|
||||
"identifierQueryVariableName": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "PersonalAPIKeyRowFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"condition": "includeToken",
|
||||
"kind": "Condition",
|
||||
"passingValue": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "token",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": "PersonalAPIKey",
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "d17db443fa203ee5f9c7d0f4576295f0";
|
||||
|
||||
export default node;
|
||||
172
apps/console/src/__generated__/iam/PersonalAPIKeyRowRefetchQuery.graphql.ts
generated
Normal file
172
apps/console/src/__generated__/iam/PersonalAPIKeyRowRefetchQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* @generated SignedSource<<2d413d4e4cf2528a45ff243c0fa733bb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type PersonalAPIKeyRowRefetchQuery$variables = {
|
||||
id: string;
|
||||
includeToken?: boolean | null | undefined;
|
||||
};
|
||||
export type PersonalAPIKeyRowRefetchQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"PersonalAPIKeyRowFragment">;
|
||||
} | null | undefined;
|
||||
};
|
||||
export type PersonalAPIKeyRowRefetchQuery = {
|
||||
response: PersonalAPIKeyRowRefetchQuery$data;
|
||||
variables: PersonalAPIKeyRowRefetchQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": false,
|
||||
"kind": "LocalArgument",
|
||||
"name": "includeToken"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "PersonalAPIKeyRowRefetchQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "includeToken",
|
||||
"variableName": "includeToken"
|
||||
}
|
||||
],
|
||||
"kind": "FragmentSpread",
|
||||
"name": "PersonalAPIKeyRowFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "PersonalAPIKeyRowRefetchQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"condition": "includeToken",
|
||||
"kind": "Condition",
|
||||
"passingValue": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "token",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": "PersonalAPIKey",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "b4732244e28d5847baaa5520a95a4cfb",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PersonalAPIKeyRowRefetchQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query PersonalAPIKeyRowRefetchQuery(\n $includeToken: Boolean = false\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...PersonalAPIKeyRowFragment_2T7Twf\n id\n }\n}\n\nfragment PersonalAPIKeyRowFragment_2T7Twf on PersonalAPIKey {\n id\n name\n createdAt\n expiresAt\n token @include(if: $includeToken)\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d17db443fa203ee5f9c7d0f4576295f0";
|
||||
|
||||
export default node;
|
||||
132
apps/console/src/__generated__/iam/PersonalAPIKeyRow_revokeMutation.graphql.ts
generated
Normal file
132
apps/console/src/__generated__/iam/PersonalAPIKeyRow_revokeMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @generated SignedSource<<64ad5ad6ff333dffc7b2d5d578028d7f>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type RevokePersonalAPIKeyInput = {
|
||||
personalAPIKeyId: string;
|
||||
};
|
||||
export type PersonalAPIKeyRow_revokeMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: RevokePersonalAPIKeyInput;
|
||||
};
|
||||
export type PersonalAPIKeyRow_revokeMutation$data = {
|
||||
readonly revokePersonalAPIKey: {
|
||||
readonly personalAPIKeyId: string;
|
||||
} | null | undefined;
|
||||
};
|
||||
export type PersonalAPIKeyRow_revokeMutation = {
|
||||
response: PersonalAPIKeyRow_revokeMutation$data;
|
||||
variables: PersonalAPIKeyRow_revokeMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "personalAPIKeyId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "PersonalAPIKeyRow_revokeMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "RevokePersonalAPIKeyPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "revokePersonalAPIKey",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "PersonalAPIKeyRow_revokeMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "RevokePersonalAPIKeyPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "revokePersonalAPIKey",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "personalAPIKeyId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "29dfd9de3537585482c2863a1d547031",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PersonalAPIKeyRow_revokeMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation PersonalAPIKeyRow_revokeMutation(\n $input: RevokePersonalAPIKeyInput!\n) {\n revokePersonalAPIKey(input: $input) {\n personalAPIKeyId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "258ca02064f55b6fd4a3630ba1f904a4";
|
||||
|
||||
export default node;
|
||||
@@ -6,10 +6,9 @@ import {
|
||||
useFragment,
|
||||
useMutation,
|
||||
} from "react-relay";
|
||||
import type { RecordSourceSelectorProxy } from "relay-runtime";
|
||||
import { z } from "zod";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { formatError, type GraphQLError } from "@probo/helpers";
|
||||
import { formatError } from "@probo/helpers";
|
||||
import {
|
||||
Breadcrumb,
|
||||
Button,
|
||||
@@ -22,15 +21,12 @@ import {
|
||||
Label,
|
||||
Option,
|
||||
Select,
|
||||
useConfirm,
|
||||
useDialogRef,
|
||||
useToast,
|
||||
} from "@probo/ui";
|
||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||
import type { PersonalAPIKeyListFragment$key } from "/__generated__/iam/PersonalAPIKeyListFragment.graphql";
|
||||
import type { PersonalAPIKeyListCreateMutation } from "/__generated__/iam/PersonalAPIKeyListCreateMutation.graphql";
|
||||
import type { PersonalAPIKeyListRevokeMutation } from "/__generated__/iam/PersonalAPIKeyListRevokeMutation.graphql";
|
||||
import type { PersonalAPIKeyListRevealTokenMutation } from "/__generated__/iam/PersonalAPIKeyListRevealTokenMutation.graphql";
|
||||
import { PersonalAPIKeysTable } from "./PersonalAPIKeysTable";
|
||||
import { PersonalAPIKeyTokenDialog } from "./PersonalAPIKeyTokenDialog";
|
||||
|
||||
@@ -44,10 +40,7 @@ const fragment = graphql`
|
||||
edges @required(action: THROW) {
|
||||
node {
|
||||
id
|
||||
name
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
...PersonalAPIKeyRowFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,7 +59,6 @@ const createMutation = graphql`
|
||||
name
|
||||
createdAt
|
||||
expiresAt
|
||||
lastUsedAt
|
||||
}
|
||||
}
|
||||
token
|
||||
@@ -74,26 +66,6 @@ const createMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
const revokeMutation = graphql`
|
||||
mutation PersonalAPIKeyListRevokeMutation(
|
||||
$input: RevokePersonalAPIKeyInput!
|
||||
) {
|
||||
revokePersonalAPIKey(input: $input) {
|
||||
success
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const revealTokenMutation = graphql`
|
||||
mutation PersonalAPIKeyListRevealTokenMutation(
|
||||
$input: RevealPersonalAPIKeyTokenInput!
|
||||
) {
|
||||
revealPersonalAPIKeyToken(input: $input) {
|
||||
token
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const createSchema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
expiresIn: z.enum(["1month", "3months", "6months", "1year"]),
|
||||
@@ -126,7 +98,6 @@ export function PersonalAPIKeyList(props: {
|
||||
const { fKey } = props;
|
||||
const { __ } = useTranslate();
|
||||
const { toast } = useToast();
|
||||
const confirm = useConfirm();
|
||||
const createDialogRef = useDialogRef();
|
||||
const tokenDialogRef = useDialogRef();
|
||||
|
||||
@@ -134,9 +105,12 @@ export function PersonalAPIKeyList(props: {
|
||||
|
||||
const viewer = useFragment(fragment, fKey);
|
||||
|
||||
const keys = viewer.personalAPIKeys.edges.map(({ node }) => node);
|
||||
const connectionID = ConnectionHandler.getConnectionID(
|
||||
viewer.id,
|
||||
"PersonalAPIKeyListFragment_personalAPIKeys"
|
||||
);
|
||||
|
||||
const { formState, handleSubmit, register, control, reset, watch } =
|
||||
const { formState, handleSubmit, register, control, reset } =
|
||||
useFormWithSchema(createSchema, {
|
||||
defaultValues: {
|
||||
name: new Date().toISOString().split("T")[0],
|
||||
@@ -144,20 +118,14 @@ export function PersonalAPIKeyList(props: {
|
||||
},
|
||||
});
|
||||
|
||||
watch();
|
||||
|
||||
const [createCommit, isCreating] =
|
||||
useMutation<PersonalAPIKeyListCreateMutation>(createMutation);
|
||||
const [revokeCommit] =
|
||||
useMutation<PersonalAPIKeyListRevokeMutation>(revokeMutation);
|
||||
const [revealTokenCommit, isRevealingToken] =
|
||||
useMutation<PersonalAPIKeyListRevealTokenMutation>(revealTokenMutation);
|
||||
|
||||
const handleCreate = (data: CreateFormData) => {
|
||||
const expiresAt = computeExpiresAt(data.expiresIn);
|
||||
const connectionID = ConnectionHandler.getConnectionID(
|
||||
viewer.id,
|
||||
"PersonalAPIKeyListFragment_personalAPIKeys",
|
||||
"PersonalAPIKeyListFragment_personalAPIKeys"
|
||||
);
|
||||
|
||||
createCommit({
|
||||
@@ -165,8 +133,6 @@ export function PersonalAPIKeyList(props: {
|
||||
input: {
|
||||
name: data.name,
|
||||
expiresAt: expiresAt.toISOString(),
|
||||
// API keys are no longer linked to organizations; keep schema compatibility.
|
||||
organizationIds: [],
|
||||
},
|
||||
connections: [connectionID],
|
||||
},
|
||||
@@ -194,116 +160,6 @@ export function PersonalAPIKeyList(props: {
|
||||
});
|
||||
};
|
||||
|
||||
const handleRevoke = (key: { id: string; name: string }) => {
|
||||
confirm(
|
||||
async () => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
revokeCommit({
|
||||
variables: {
|
||||
input: { tokenId: key.id },
|
||||
},
|
||||
updater: (store: RecordSourceSelectorProxy) => {
|
||||
const viewerRecord = store.getRoot().getLinkedRecord("viewer");
|
||||
if (!viewerRecord) return;
|
||||
const connection = ConnectionHandler.getConnection(
|
||||
viewerRecord,
|
||||
"PersonalAPIKeyListFragment_personalAPIKeys",
|
||||
);
|
||||
if (connection) {
|
||||
ConnectionHandler.deleteNode(connection, key.id);
|
||||
}
|
||||
},
|
||||
onCompleted: (_response, errors) => {
|
||||
if (errors?.length) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to revoke API key."),
|
||||
errors as GraphQLError[],
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
reject(errors);
|
||||
return;
|
||||
}
|
||||
toast({
|
||||
title: __("Success"),
|
||||
description: __("API key revoked successfully."),
|
||||
variant: "success",
|
||||
});
|
||||
resolve();
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to revoke API key."),
|
||||
error,
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
reject(error);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
{
|
||||
title: __("Revoke API Key"),
|
||||
message: __(
|
||||
`Are you sure you want to revoke the API key "${key.name}"? This action cannot be undone.`,
|
||||
),
|
||||
label: __("Revoke"),
|
||||
variant: "danger",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleShowToken = (key: { id: string; name: string }) => {
|
||||
revealTokenCommit({
|
||||
variables: {
|
||||
input: {
|
||||
tokenId: key.id,
|
||||
},
|
||||
},
|
||||
onCompleted: (response, errors) => {
|
||||
if (errors?.length) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to reveal API key token."),
|
||||
errors as any,
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const tokenValue = response.revealPersonalAPIKeyToken?.token;
|
||||
if (!tokenValue) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: __("No token returned."),
|
||||
variant: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setToken(tokenValue);
|
||||
tokenDialogRef.current?.open();
|
||||
},
|
||||
onError: (error: Error) => {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to reveal API key token."),
|
||||
error,
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
@@ -314,7 +170,7 @@ export function PersonalAPIKeyList(props: {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{keys.length === 0 ? (
|
||||
{viewer.personalAPIKeys.edges.length === 0 ? (
|
||||
<Card padded>
|
||||
<div className="text-center py-12">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
||||
@@ -328,10 +184,8 @@ export function PersonalAPIKeyList(props: {
|
||||
) : (
|
||||
<Card padded>
|
||||
<PersonalAPIKeysTable
|
||||
keys={keys}
|
||||
onRevoke={handleRevoke}
|
||||
onShowToken={handleShowToken}
|
||||
isShowingToken={isRevealingToken}
|
||||
edges={viewer.personalAPIKeys.edges}
|
||||
connectionId={connectionID}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { formatDate, formatError, type GraphQLError } from "@probo/helpers";
|
||||
import { Button, Spinner, Td, Tr, useConfirm, useToast } from "@probo/ui";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useMutation, useFragment } from "react-relay";
|
||||
import type { PersonalAPIKeyRowFragment$key } from "/__generated__/iam/PersonalAPIKeyRowFragment.graphql";
|
||||
import type { PersonalAPIKeyRow_revokeMutation } from "/__generated__/iam/PersonalAPIKeyRow_revokeMutation.graphql";
|
||||
import clsx from "clsx";
|
||||
import { PersonalAPIKeyTokenAction } from "./PersonalAPIKeyTokenAction";
|
||||
import { Suspense } from "react";
|
||||
|
||||
const revokeMutation = graphql`
|
||||
mutation PersonalAPIKeyRow_revokeMutation(
|
||||
$input: RevokePersonalAPIKeyInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
revokePersonalAPIKey(input: $input) {
|
||||
personalAPIKeyId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const personalAPIKeyRowFragment = graphql`
|
||||
fragment PersonalAPIKeyRowFragment on PersonalAPIKey
|
||||
@refetchable(queryName: "PersonalAPIKeyRowRefetchQuery")
|
||||
@argumentDefinitions(includeToken: { type: "Boolean", defaultValue: false }) {
|
||||
id
|
||||
name
|
||||
createdAt
|
||||
expiresAt
|
||||
token @include(if: $includeToken)
|
||||
}
|
||||
`;
|
||||
|
||||
export function PersonalAPIKeyRow(props: {
|
||||
fKey: PersonalAPIKeyRowFragment$key;
|
||||
connectionId: string;
|
||||
}) {
|
||||
const { fKey, connectionId } = props;
|
||||
const { __ } = useTranslate();
|
||||
const confirm = useConfirm();
|
||||
const { toast } = useToast();
|
||||
const now = new Date();
|
||||
|
||||
const key = useFragment(personalAPIKeyRowFragment, fKey);
|
||||
const expired = new Date(key.expiresAt) < now;
|
||||
|
||||
const [revokeCommit, isRevoking] =
|
||||
useMutation<PersonalAPIKeyRow_revokeMutation>(revokeMutation);
|
||||
|
||||
const handleRevoke = () => {
|
||||
confirm(
|
||||
async () => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
revokeCommit({
|
||||
variables: {
|
||||
input: { personalAPIKeyId: key.id },
|
||||
connections: [connectionId],
|
||||
},
|
||||
onCompleted: (_response, errors) => {
|
||||
if (errors?.length) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to revoke API key."),
|
||||
errors as GraphQLError[]
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
reject(errors);
|
||||
return;
|
||||
}
|
||||
toast({
|
||||
title: __("Success"),
|
||||
description: __("API key revoked successfully."),
|
||||
variant: "success",
|
||||
});
|
||||
resolve();
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to revoke API key."),
|
||||
error
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
reject(error);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
{
|
||||
title: __("Revoke API Key"),
|
||||
message: __(
|
||||
`Are you sure you want to revoke the API key "${key.name}"? This action cannot be undone.`
|
||||
),
|
||||
label: __("Revoke"),
|
||||
variant: "danger",
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Tr className={clsx(isRevoking && "opacity-60 pointer-events-none")}>
|
||||
<Td>
|
||||
<div className="font-medium text-txt-primary">{key.name}</div>
|
||||
<div className="text-xs text-txt-tertiary">
|
||||
{expired ? __("Expired") : __("Active")}
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{formatDate(key.createdAt)}
|
||||
</span>
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{formatDate(key.expiresAt)}
|
||||
</span>
|
||||
</Td>
|
||||
<Td width={140} className="text-end">
|
||||
<div className="flex gap-2 justify-end">
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<PersonalAPIKeyTokenAction fKey={fKey} disabled={isRevoking} />
|
||||
</Suspense>
|
||||
<Button variant="danger" onClick={handleRevoke} disabled={isRevoking}>
|
||||
{__("Revoke")}
|
||||
</Button>
|
||||
</div>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Button, useDialogRef, useToast } from "@probo/ui";
|
||||
import { formatError } from "@probo/helpers";
|
||||
import { useRefetchableFragment } from "react-relay";
|
||||
import { PersonalAPIKeyTokenDialog } from "./PersonalAPIKeyTokenDialog";
|
||||
import { personalAPIKeyRowFragment } from "./PersonalAPIKeyRow";
|
||||
import type { PersonalAPIKeyRowFragment$key } from "/__generated__/iam/PersonalAPIKeyRowFragment.graphql";
|
||||
import type { PersonalAPIKeyRowRefetchQuery } from "/__generated__/iam/PersonalAPIKeyRowRefetchQuery.graphql";
|
||||
|
||||
export function PersonalAPIKeyTokenAction(props: {
|
||||
fKey: PersonalAPIKeyRowFragment$key;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
const { fKey, disabled } = props;
|
||||
const { __ } = useTranslate();
|
||||
const { toast } = useToast();
|
||||
const dialogRef = useDialogRef();
|
||||
|
||||
const [data, refetch] = useRefetchableFragment<
|
||||
PersonalAPIKeyRowRefetchQuery,
|
||||
PersonalAPIKeyRowFragment$key
|
||||
>(personalAPIKeyRowFragment, fKey);
|
||||
|
||||
const handleShow = () => {
|
||||
dialogRef.current?.open();
|
||||
|
||||
refetch(
|
||||
{ includeToken: true },
|
||||
{
|
||||
fetchPolicy: "network-only",
|
||||
onComplete: (error) => {
|
||||
if (error) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(
|
||||
__("Failed to load API key token."),
|
||||
error
|
||||
),
|
||||
variant: "error",
|
||||
});
|
||||
dialogRef.current?.close();
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button variant="secondary" onClick={handleShow} disabled={!!disabled}>
|
||||
{__("Show")}
|
||||
</Button>
|
||||
|
||||
<PersonalAPIKeyTokenDialog
|
||||
dialogRef={dialogRef}
|
||||
token={data.token ?? ""}
|
||||
onDone={() => {
|
||||
dialogRef.current?.close();
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useCopy } from "@probo/hooks";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export function PersonalAPIKeyTokenDialog(props: {
|
||||
dialogRef: React.RefObject<{ open: () => void; close: () => void } | null>;
|
||||
@@ -18,8 +17,6 @@ export function PersonalAPIKeyTokenDialog(props: {
|
||||
const { __ } = useTranslate();
|
||||
const [isCopied, copy] = useCopy();
|
||||
|
||||
useEffect(() => {}, [token]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
ref={dialogRef}
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { formatDate } from "@probo/helpers";
|
||||
import { Button, Table, Tbody, Td, Th, Thead, Tr } from "@probo/ui";
|
||||
|
||||
export type PersonalAPIKeyRow = {
|
||||
id: string;
|
||||
name: string;
|
||||
createdAt: string;
|
||||
expiresAt: string;
|
||||
lastUsedAt: string | null;
|
||||
};
|
||||
import { Table, Tbody, Th, Thead, Tr } from "@probo/ui";
|
||||
import { PersonalAPIKeyRow } from "./PersonalAPIKeyRow";
|
||||
import type { PersonalAPIKeyListFragment$data } from "/__generated__/iam/PersonalAPIKeyListFragment.graphql";
|
||||
|
||||
export function PersonalAPIKeysTable(props: {
|
||||
keys: PersonalAPIKeyRow[];
|
||||
onRevoke: (key: { id: string; name: string }) => void;
|
||||
onShowToken: (key: { id: string; name: string }) => void;
|
||||
isShowingToken?: boolean;
|
||||
edges: PersonalAPIKeyListFragment$data["personalAPIKeys"]["edges"];
|
||||
connectionId: string;
|
||||
}) {
|
||||
const { keys, onRevoke, onShowToken, isShowingToken } = props;
|
||||
const { edges, connectionId } = props;
|
||||
const { __ } = useTranslate();
|
||||
const now = new Date();
|
||||
|
||||
return (
|
||||
<Table>
|
||||
@@ -32,51 +22,13 @@ export function PersonalAPIKeysTable(props: {
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{keys.map((k) => {
|
||||
const expired = new Date(k.expiresAt) < now;
|
||||
return (
|
||||
<Tr key={k.id}>
|
||||
<Td>
|
||||
<div className="font-medium text-txt-primary">{k.name}</div>
|
||||
<div className="text-xs text-txt-tertiary">
|
||||
{expired ? __("Expired") : __("Active")}
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{k.lastUsedAt ? formatDate(k.lastUsedAt) : "—"}
|
||||
</span>
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{formatDate(k.createdAt)}
|
||||
</span>
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="text-sm text-txt-secondary">
|
||||
{formatDate(k.expiresAt)}
|
||||
</span>
|
||||
</Td>
|
||||
<Td width={140} className="text-end">
|
||||
<div className="flex gap-2 justify-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => onShowToken({ id: k.id, name: k.name })}
|
||||
disabled={!!isShowingToken}
|
||||
>
|
||||
{__("Show")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="danger"
|
||||
onClick={() => onRevoke({ id: k.id, name: k.name })}
|
||||
>
|
||||
{__("Revoke")}
|
||||
</Button>
|
||||
</div>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
{edges.map(({ node }) => (
|
||||
<PersonalAPIKeyRow
|
||||
key={node.id}
|
||||
fKey={node}
|
||||
connectionId={connectionId}
|
||||
/>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user