From b9d798e9c92a6f7957c8faf3a47848ddab64ed2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Fern=C3=A1ndez?= Date: Fri, 14 Mar 2025 14:56:52 +0100 Subject: [PATCH 1/5] API Client Generation: Add documentation (#102056) --- public/app/api/README.md | 157 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 public/app/api/README.md diff --git a/public/app/api/README.md b/public/app/api/README.md new file mode 100644 index 00000000000..356289f08a6 --- /dev/null +++ b/public/app/api/README.md @@ -0,0 +1,157 @@ +## Generating RTK Query API Clients + +To show the steps to follow, we are going to work on adding an API client to create a new dashboard. Just adapt the following guide to your use case. + +### 1. Generate an OpenAPI snapshot + +First, check if the `group` and the `version` are already present in [openapi_test.go](/pkg/tests/apis/openapi_test.go). If so, move on to the next step. +
If you need to add a new block, you can check for the right `group` and `version` in the backend API call that you want to replicate in the frontend. + +```jsx +{ + Group: "dashboard.grafana.app", + Version: "v0alpha1", +} +``` + +Afterwards, you need to run the `TestIntegrationOpenAPIs` test. Note that it will fail the first time you run it. On the second run, it will generate the corresponding OpenAPI spec, which you can find in [openapi_snapshots](/pkg/tests/apis/openapi_snapshots). +
+
+ +> Note: You don’t need to follow these two steps if the `group` you’re working with is already in the `openapi_test.go` file. + +
+ +### 2. Create the API definition + +In the `../public/app/features/{your_group_name}/api/` folder you have to create the `baseAPI.ts` file for your group. This file should have the following content: + +```jsx +import { createApi } from '@reduxjs/toolkit/query/react'; + +import { createBaseQuery } from 'app/api/createBaseQuery'; +import { getAPIBaseURL } from 'app/api/utils'; + +export const BASE_URL = getAPIBaseURL('dashboard.grafana.app', 'v0alpha1'); + +export const baseAPI = createApi({ + reducerPath: 'dashboardAPI', + baseQuery: createBaseQuery({ + baseURL: BASE_URL, + }), + endpoints: () => ({}), +}); +``` + +This is the API definition for the specific group you're working with, where `getAPIBaseURL` should have the proper `group` and `version` as parameters. The `reducePath` should also be modified to match `group + API`: `dashboard` will be `dashboardAPI`, `iam` will be `iamAPI` and so on. + +### 3. Add the output information + +Open [generate-rtk-apis.ts](scripts/generate-rtk-apis.ts) and add the following information: + +| Data | Descritpion | +| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| outputFile name | File that will be created after running the API Client Generation script. It is the key of the object. | +| apiFile | File with the group's API definition. | +| schemaFile | File with the schema that was automatically created in the second step. Although it is in openapi_snapshots, you should link the one saved in `data/openapi`. | +| apiImport | Function name exported in the API definition (baseAPI.ts file). | +| filterEndpoints | The `operationId` of the particular route you want to work with. You can check the available operationIds in the specific group's spec file. As seen in the `migrate-to-cloud` one, it is an array | +|  tag | Must be set to `true`, to automatically attach tags to endpoints. This is needed for proper cache invalidation. See more info in the [official documentation](https://redux-toolkit.js.org/rtk-query/usage/automated-refetching#:~:text=RTK%20Query%20uses,an%20active%20subscription.).  | + +
+ +> More info in [Redux Toolkit](https://redux-toolkit.js.org/rtk-query/usage/code-generation#simple-usage) + +In our example, the information added will be: + +```jsx +'../public/app/features/dashboard/api/endpoints.gen.ts': { + apiFile: '../public/app/features/dashboard/api/baseAPI.ts', + schemaFile: '../data/openapi/dashboard.grafana.app-v0alpha1.json', + apiImport: 'baseAPI', + filterEndpoints: ['createDashboard', 'updateDashboard'], + tag: true, +}, +``` + +### 4. Run the API Client script + +Then, we are ready to run the script to create the API client: + +```jsx +yarn generate-apis +``` + +This will create an `endpoints.gen.ts` file in the path specified in the previous step. + +### 5. Create the index file for your hooks + +In the same `api` folder where the `endpoints.gen.ts` file has been saved, you have to create an index file from which you can import the types and hooks needed. By doing this, we selectively export hooks/types from `endpoints.gen.ts`. + +In our case, the dashboard index will be like: + +```jsx +import { generatedAPI } from './endpoints.gen'; + +export const dashboardAPI = generatedAPI; +export const { useCreateDashboardMutation, useUpdateDashboardMutation} = dashboardAPI; +// eslint-disable-next-line no-barrel-files/no-barrel-files +export { type Dashboard } from './endpoints.gen'; + +``` + +There are some use cases where the hook will not work, and that is a clue to see if it needs to be modified. The hooks can be tweaked by using `enhanceEndpoints`. + +```jsx +export const dashboardsAPI = generatedApi.enhanceEndpoints({ + endpoints: { + // Need to mutate the generated query to set the Content-Type header correctly + updateDashboard: (endpointDefinition) => { + const originalQuery = endpointDefinition.query; + if (originalQuery) { + endpointDefinition.query = (requestOptions) => ({ + ...originalQuery(requestOptions), + headers: { + 'Content-Type': 'application/merge-patch+json', + }, + }); + } + }, + }, +}); +``` + +### 6. Add reducers and middleware to the Redux store + +Last but not least, you need to add the middleware and reducers to the store. + +In Grafana, the reducers are added to [`root.ts`](public/app/core/reducers/root.ts): + +```jsx + import { dashboardAPI } from ''; + const rootReducers = { + ..., + [dashboardAPI.reducerPath]: dashboardAPI.reducer, + }; +``` + +And the middleware is added to [`configureStore.ts`](public/app/store/configureStore.ts): + +```jsx +import { dashboardAPI } from ''; +export function configureStore(initialState?: Partial) { + const store = reduxConfigureStore({ + reducer: createRootReducer(), + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ thunk: true, serializableCheck: false, immutableCheck: false }).concat( + ..., + dashboardAPI.middleware + ), + ..., + }); +``` + +You have available the official documentation in [RTK Query](https://redux-toolkit.js.org/tutorials/rtk-query#add-the-service-to-your-store) + +After this step is done, it is time to use your hooks across Grafana. +Enjoy coding! From 24da64cd3469ba5d53aa0657acb47ef951cc48c6 Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Fri, 14 Mar 2025 16:03:51 +0200 Subject: [PATCH 2/5] Provisioning: Load dashboard in state manager (#102194) MergeProvisioning: Load dashboard in state manager --- .../pages/DashboardScenePageStateManager.ts | 3 +++ .../dashboard-scene/scene/DashboardScene.tsx | 15 +-------------- .../app/features/provisioning/dashboardLoader.ts | 2 +- public/app/types/dashboard.ts | 6 ++++++ 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts index d66ac86c9fd..2bd41da5e4f 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts +++ b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts @@ -314,6 +314,9 @@ export class DashboardScenePageStateManager extends DashboardScenePageStateManag } break; + case DashboardRoutes.Provisioning: { + return await dashboardLoaderSrv.loadDashboard('provisioning', slug, uid); + } case DashboardRoutes.Public: { return await dashboardLoaderSrv.loadDashboard('public', '', uid); } diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.tsx index 0ca9bf5ae1e..51f9091cad5 100644 --- a/public/app/features/dashboard-scene/scene/DashboardScene.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardScene.tsx @@ -33,7 +33,7 @@ import { VariablesChanged } from 'app/features/variables/types'; import { DashboardDTO, DashboardMeta, KioskMode, SaveDashboardResponseDTO } from 'app/types'; import { ShowConfirmModalEvent } from 'app/types/events'; -import { AnnoKeyManagerIdentity, AnnoKeyManagerKind, AnnoKeySourcePath, ManagerKind } from '../../apiserver/types'; +import { AnnoKeyManagerKind, AnnoKeySourcePath, ManagerKind } from '../../apiserver/types'; import { DashboardEditPane } from '../edit-pane/DashboardEditPane'; import { PanelEditor } from '../panel-edit/PanelEditor'; import { DashboardSceneChangeTracker } from '../saving/DashboardSceneChangeTracker'; @@ -766,19 +766,6 @@ export class DashboardScene extends SceneObjectBase impleme getPath() { return this.state.meta.k8s?.annotations?.[AnnoKeySourcePath]; } - - setManager(kind: ManagerKind, id: string) { - this.setState({ - meta: { - k8s: { - annotations: { - [AnnoKeyManagerKind]: kind, - [AnnoKeyManagerIdentity]: id, - }, - }, - }, - }); - } } export class DashboardVariableDependency implements SceneVariableDependencyConfigLike { diff --git a/public/app/features/provisioning/dashboardLoader.ts b/public/app/features/provisioning/dashboardLoader.ts index 6614a966eba..914d42da88a 100644 --- a/public/app/features/provisioning/dashboardLoader.ts +++ b/public/app/features/provisioning/dashboardLoader.ts @@ -11,7 +11,7 @@ import { BASE_URL } from './api/baseAPI'; */ export async function loadDashboardFromProvisioning(repo: string, path: string): Promise { const params = new URLSearchParams(window.location.search); - const ref = params.get('ref'); // commit hash or branch + const ref = params.get('ref') ?? undefined; // commit hash or branch const url = `${BASE_URL}/repositories/${repo}/files/${path}`; return getBackendSrv() diff --git a/public/app/types/dashboard.ts b/public/app/types/dashboard.ts index 51478ac3829..35a075794e5 100644 --- a/public/app/types/dashboard.ts +++ b/public/app/types/dashboard.ts @@ -3,6 +3,8 @@ import { Dashboard, DataSourceRef } from '@grafana/schema'; import { ObjectMeta } from 'app/features/apiserver/types'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +import { ProvisioningPreview } from '../features/provisioning/types'; + export interface HomeDashboardRedirectDTO { redirectUri: string; } @@ -78,6 +80,9 @@ export interface DashboardMeta { // until we use the resource as the main container k8s?: Partial; + // If the dashboard was loaded from a remote repository + provisioning?: ProvisioningPreview; + // This is a property added specifically for edge cases where dashboards should be reloaded on scopes, time range or variables changes // This property is not persisted in the DB but its existence is controlled by the API reloadOnParamsChange?: boolean; @@ -105,6 +110,7 @@ export enum DashboardRoutes { Home = 'home-dashboard', New = 'new-dashboard', Normal = 'normal-dashboard', + Provisioning = 'provisioning-dashboard', Scripted = 'scripted-dashboard', Public = 'public-dashboard', Embedded = 'embedded-dashboard', From dd07d3dbbe447bdcebc576ca7d0afe520c7e10f4 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 14 Mar 2025 14:34:36 +0000 Subject: [PATCH 3/5] API client generation: centralise api clients (#102186) * centralise iam api * centralise folder api client * rename to baseAPI * centralise provisioning api * remove iam feature folder from CODEOWNERS * fix type name * Update public/app/features/provisioning/utils/selectors.ts Co-authored-by: Alex Khomenko --------- Co-authored-by: Alex Khomenko --- .github/CODEOWNERS | 1 - .../api => api/clients/folder}/baseAPI.ts | 2 +- .../clients/folder}/endpoints.gen.ts | 9 +- .../api => api/clients/folder}/index.ts | 0 .../api/api.ts => api/clients/iam/baseAPI.ts} | 6 +- .../api => api/clients/iam}/endpoints.gen.ts | 4 +- public/app/api/clients/iam/index.ts | 5 + .../clients/provisioning}/baseAPI.ts | 2 +- .../clients/provisioning}/endpoints.gen.ts | 179 +++++++++--------- .../api => api/clients/provisioning}/index.ts | 0 .../utils/createOnCacheEntryAdded.ts | 4 +- .../provisioning}/utils/getListParams.ts | 8 +- public/app/core/reducers/root.ts | 8 +- public/app/features/iam/index.ts | 3 - .../hooks/useCreateOrUpdateRepository.ts | 6 +- .../hooks/useCreateOrUpdateRepositoryFile.ts | 6 +- .../hooks/useGetResourceRepository.ts | 2 +- .../hooks/useIsProvisionedInstance.ts | 2 +- .../provisioning/hooks/useIsProvisionedNG.ts | 2 +- .../provisioning/hooks/useRepositoryJobs.ts | 2 +- .../provisioning/hooks/useRepositoryList.ts | 4 +- public/app/features/provisioning/types.ts | 2 +- .../provisioning/utils/checkSyncSettings.ts | 2 +- .../app/features/provisioning/utils/data.ts | 2 +- .../provisioning/{api => utils}/selectors.ts | 4 +- .../provisioning/{api => utils}/types.ts | 0 public/app/store/configureStore.ts | 8 +- scripts/generate-rtk-apis.ts | 22 +-- 28 files changed, 148 insertions(+), 147 deletions(-) rename public/app/{features/folders/api => api/clients/folder}/baseAPI.ts (91%) rename public/app/{features/folders/api => api/clients/folder}/endpoints.gen.ts (97%) rename public/app/{features/folders/api => api/clients/folder}/index.ts (100%) rename public/app/{features/iam/api/api.ts => api/clients/iam/baseAPI.ts} (61%) rename public/app/{features/iam/api => api/clients/iam}/endpoints.gen.ts (98%) create mode 100644 public/app/api/clients/iam/index.ts rename public/app/{features/provisioning/api => api/clients/provisioning}/baseAPI.ts (91%) rename public/app/{features/provisioning/api => api/clients/provisioning}/endpoints.gen.ts (92%) rename public/app/{features/provisioning/api => api/clients/provisioning}/index.ts (100%) rename public/app/{features/provisioning/api => api/clients/provisioning}/utils/createOnCacheEntryAdded.ts (94%) rename public/app/{features/provisioning/api => api/clients/provisioning}/utils/getListParams.ts (65%) delete mode 100644 public/app/features/iam/index.ts rename public/app/features/provisioning/{api => utils}/selectors.ts (90%) rename public/app/features/provisioning/{api => utils}/types.ts (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c8fd9fe2158..a485a1f6061 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -505,7 +505,6 @@ playwright.config.ts @grafana/plugins-platform-frontend /public/app/features/explore/ @grafana/observability-traces-and-profiling /public/app/features/expressions/ @grafana/grafana-datasources-core-services /public/app/features/folders/ @grafana/grafana-frontend-platform -/public/app/features/iam/ @grafana/grafana-frontend-platform /public/app/features/inspector/ @grafana/dashboards-squad /public/app/features/invites/ @grafana/grafana-frontend-platform /public/app/features/library-panels/ @grafana/dashboards-squad diff --git a/public/app/features/folders/api/baseAPI.ts b/public/app/api/clients/folder/baseAPI.ts similarity index 91% rename from public/app/features/folders/api/baseAPI.ts rename to public/app/api/clients/folder/baseAPI.ts index c5957bea332..afa1e588376 100644 --- a/public/app/features/folders/api/baseAPI.ts +++ b/public/app/api/clients/folder/baseAPI.ts @@ -5,7 +5,7 @@ import { getAPIBaseURL } from 'app/api/utils'; export const BASE_URL = getAPIBaseURL('folder.grafana.app', 'v0alpha1'); -export const baseAPI = createApi({ +export const api = createApi({ reducerPath: 'folderAPI', baseQuery: createBaseQuery({ baseURL: BASE_URL, diff --git a/public/app/features/folders/api/endpoints.gen.ts b/public/app/api/clients/folder/endpoints.gen.ts similarity index 97% rename from public/app/features/folders/api/endpoints.gen.ts rename to public/app/api/clients/folder/endpoints.gen.ts index 5ede70048ec..98b36472013 100644 --- a/public/app/features/folders/api/endpoints.gen.ts +++ b/public/app/api/clients/folder/endpoints.gen.ts @@ -1,4 +1,4 @@ -import { baseAPI as api } from './baseAPI'; +import { api } from './baseAPI'; export const addTagTypes = ['Folder'] as const; const injectedRtkApi = api .enhanceEndpoints({ @@ -6,7 +6,7 @@ const injectedRtkApi = api }) .injectEndpoints({ endpoints: (build) => ({ - getFolder: build.query({ + getFolder: build.query({ query: (queryArg) => ({ url: `/folders/${queryArg.name}`, params: { @@ -19,8 +19,8 @@ const injectedRtkApi = api overrideExisting: false, }); export { injectedRtkApi as generatedAPI }; -export type GetFolderResponse = /** status 200 OK */ Folder; -export type GetFolderArg = { +export type GetFolderApiResponse = /** status 200 OK */ Folder; +export type GetFolderApiArg = { /** name of the Folder */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -122,4 +122,3 @@ export type Folder = { metadata?: ObjectMeta; spec?: Spec; }; -export const { useGetFolderQuery } = injectedRtkApi; diff --git a/public/app/features/folders/api/index.ts b/public/app/api/clients/folder/index.ts similarity index 100% rename from public/app/features/folders/api/index.ts rename to public/app/api/clients/folder/index.ts diff --git a/public/app/features/iam/api/api.ts b/public/app/api/clients/iam/baseAPI.ts similarity index 61% rename from public/app/features/iam/api/api.ts rename to public/app/api/clients/iam/baseAPI.ts index 07a735c561a..bb2d1e31850 100644 --- a/public/app/features/iam/api/api.ts +++ b/public/app/api/clients/iam/baseAPI.ts @@ -1,11 +1,11 @@ import { createApi } from '@reduxjs/toolkit/query/react'; -import { createBaseQuery } from '../../../api/createBaseQuery'; -import { getAPIBaseURL } from '../../../api/utils'; +import { createBaseQuery } from '../../createBaseQuery'; +import { getAPIBaseURL } from '../../utils'; export const BASE_URL = getAPIBaseURL('iam.grafana.app', 'v0alpha1'); -export const iamApi = createApi({ +export const api = createApi({ baseQuery: createBaseQuery({ baseURL: BASE_URL }), reducerPath: 'iamAPI', endpoints: () => ({}), diff --git a/public/app/features/iam/api/endpoints.gen.ts b/public/app/api/clients/iam/endpoints.gen.ts similarity index 98% rename from public/app/features/iam/api/endpoints.gen.ts rename to public/app/api/clients/iam/endpoints.gen.ts index 9f424e5ec09..d59b1d4cd52 100644 --- a/public/app/features/iam/api/endpoints.gen.ts +++ b/public/app/api/clients/iam/endpoints.gen.ts @@ -1,4 +1,4 @@ -import { iamApi as api } from './api'; +import { api } from './baseAPI'; export const addTagTypes = ['Display'] as const; const injectedRtkApi = api .enhanceEndpoints({ @@ -18,7 +18,7 @@ const injectedRtkApi = api }), overrideExisting: false, }); -export { injectedRtkApi as generatedIamApi }; +export { injectedRtkApi as generatedAPI }; export type GetDisplayMappingApiResponse = /** status 200 undefined */ DisplayList; export type GetDisplayMappingApiArg = { /** Display keys */ diff --git a/public/app/api/clients/iam/index.ts b/public/app/api/clients/iam/index.ts new file mode 100644 index 00000000000..af251160d2a --- /dev/null +++ b/public/app/api/clients/iam/index.ts @@ -0,0 +1,5 @@ +import { generatedAPI } from './endpoints.gen'; + +export const iamAPI = generatedAPI.enhanceEndpoints({}); + +export const { useGetDisplayMappingQuery } = generatedAPI; diff --git a/public/app/features/provisioning/api/baseAPI.ts b/public/app/api/clients/provisioning/baseAPI.ts similarity index 91% rename from public/app/features/provisioning/api/baseAPI.ts rename to public/app/api/clients/provisioning/baseAPI.ts index 9a30da30d82..9d3693bf8e3 100644 --- a/public/app/features/provisioning/api/baseAPI.ts +++ b/public/app/api/clients/provisioning/baseAPI.ts @@ -5,7 +5,7 @@ import { createBaseQuery } from 'app/api/createBaseQuery'; export const BASE_URL = `apis/provisioning.grafana.app/v0alpha1/namespaces/${config.namespace}`; -export const baseAPI = createApi({ +export const api = createApi({ reducerPath: 'provisioningAPI', baseQuery: createBaseQuery({ baseURL: BASE_URL, diff --git a/public/app/features/provisioning/api/endpoints.gen.ts b/public/app/api/clients/provisioning/endpoints.gen.ts similarity index 92% rename from public/app/features/provisioning/api/endpoints.gen.ts rename to public/app/api/clients/provisioning/endpoints.gen.ts index fd8429fee34..c614724dbe2 100644 --- a/public/app/features/provisioning/api/endpoints.gen.ts +++ b/public/app/api/clients/provisioning/endpoints.gen.ts @@ -1,4 +1,4 @@ -import { baseAPI as api } from './baseAPI'; +import { api } from './baseAPI'; export const addTagTypes = ['Job', 'Repository', 'Provisioning'] as const; const injectedRtkApi = api .enhanceEndpoints({ @@ -6,7 +6,7 @@ const injectedRtkApi = api }) .injectEndpoints({ endpoints: (build) => ({ - listJob: build.query({ + listJob: build.query({ query: (queryArg) => ({ url: `/jobs`, params: { @@ -25,7 +25,7 @@ const injectedRtkApi = api }), providesTags: ['Job'], }), - getJob: build.query({ + getJob: build.query({ query: (queryArg) => ({ url: `/jobs/${queryArg.name}`, params: { @@ -34,7 +34,7 @@ const injectedRtkApi = api }), providesTags: ['Job'], }), - listRepository: build.query({ + listRepository: build.query({ query: (queryArg) => ({ url: `/repositories`, params: { @@ -53,7 +53,7 @@ const injectedRtkApi = api }), providesTags: ['Repository'], }), - createRepository: build.mutation({ + createRepository: build.mutation({ query: (queryArg) => ({ url: `/repositories`, method: 'POST', @@ -67,7 +67,10 @@ const injectedRtkApi = api }), invalidatesTags: ['Repository'], }), - deletecollectionRepository: build.mutation({ + deletecollectionRepository: build.mutation< + DeletecollectionRepositoryApiResponse, + DeletecollectionRepositoryApiArg + >({ query: (queryArg) => ({ url: `/repositories`, method: 'DELETE', @@ -90,7 +93,7 @@ const injectedRtkApi = api }), invalidatesTags: ['Repository'], }), - getRepository: build.query({ + getRepository: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}`, params: { @@ -99,7 +102,7 @@ const injectedRtkApi = api }), providesTags: ['Repository'], }), - replaceRepository: build.mutation({ + replaceRepository: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}`, method: 'PUT', @@ -113,7 +116,7 @@ const injectedRtkApi = api }), invalidatesTags: ['Repository'], }), - deleteRepository: build.mutation({ + deleteRepository: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}`, method: 'DELETE', @@ -128,11 +131,11 @@ const injectedRtkApi = api }), invalidatesTags: ['Repository'], }), - createRepositoryExport: build.mutation({ + createRepositoryExport: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/export`, method: 'POST', body: queryArg.body }), invalidatesTags: ['Repository'], }), - getRepositoryFiles: build.query({ + getRepositoryFiles: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/files/`, params: { @@ -141,7 +144,7 @@ const injectedRtkApi = api }), providesTags: ['Repository'], }), - getRepositoryFilesWithPath: build.query({ + getRepositoryFilesWithPath: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/files/${queryArg.path}`, params: { @@ -151,8 +154,8 @@ const injectedRtkApi = api providesTags: ['Repository'], }), replaceRepositoryFilesWithPath: build.mutation< - ReplaceRepositoryFilesWithPathResponse, - ReplaceRepositoryFilesWithPathArg + ReplaceRepositoryFilesWithPathApiResponse, + ReplaceRepositoryFilesWithPathApiArg >({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/files/${queryArg.path}`, @@ -166,8 +169,8 @@ const injectedRtkApi = api invalidatesTags: ['Repository'], }), createRepositoryFilesWithPath: build.mutation< - CreateRepositoryFilesWithPathResponse, - CreateRepositoryFilesWithPathArg + CreateRepositoryFilesWithPathApiResponse, + CreateRepositoryFilesWithPathApiArg >({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/files/${queryArg.path}`, @@ -181,8 +184,8 @@ const injectedRtkApi = api invalidatesTags: ['Repository'], }), deleteRepositoryFilesWithPath: build.mutation< - DeleteRepositoryFilesWithPathResponse, - DeleteRepositoryFilesWithPathArg + DeleteRepositoryFilesWithPathApiResponse, + DeleteRepositoryFilesWithPathApiArg >({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/files/${queryArg.path}`, @@ -194,7 +197,7 @@ const injectedRtkApi = api }), invalidatesTags: ['Repository'], }), - getRepositoryHistory: build.query({ + getRepositoryHistory: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/history`, params: { @@ -203,7 +206,10 @@ const injectedRtkApi = api }), providesTags: ['Repository'], }), - getRepositoryHistoryWithPath: build.query({ + getRepositoryHistoryWithPath: build.query< + GetRepositoryHistoryWithPathApiResponse, + GetRepositoryHistoryWithPathApiArg + >({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/history/${queryArg.path}`, params: { @@ -212,19 +218,22 @@ const injectedRtkApi = api }), providesTags: ['Repository'], }), - createRepositoryMigrate: build.mutation({ + createRepositoryMigrate: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/migrate`, method: 'POST', body: queryArg.body }), invalidatesTags: ['Repository'], }), - getRepositoryRenderWithPath: build.query({ + getRepositoryRenderWithPath: build.query< + GetRepositoryRenderWithPathApiResponse, + GetRepositoryRenderWithPathApiArg + >({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/render/${queryArg.path}` }), providesTags: ['Repository'], }), - getRepositoryResources: build.query({ + getRepositoryResources: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/resources` }), providesTags: ['Repository'], }), - getRepositoryStatus: build.query({ + getRepositoryStatus: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/status`, params: { @@ -233,7 +242,7 @@ const injectedRtkApi = api }), providesTags: ['Repository'], }), - replaceRepositoryStatus: build.mutation({ + replaceRepositoryStatus: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/status`, method: 'PUT', @@ -247,27 +256,27 @@ const injectedRtkApi = api }), invalidatesTags: ['Repository'], }), - createRepositorySync: build.mutation({ + createRepositorySync: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/sync`, method: 'POST', body: queryArg.body }), invalidatesTags: ['Repository'], }), - createRepositoryTest: build.mutation({ + createRepositoryTest: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/test`, method: 'POST', body: queryArg.body }), invalidatesTags: ['Repository'], }), - getRepositoryWebhook: build.query({ + getRepositoryWebhook: build.query({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/webhook` }), providesTags: ['Repository'], }), - createRepositoryWebhook: build.mutation({ + createRepositoryWebhook: build.mutation({ query: (queryArg) => ({ url: `/repositories/${queryArg.name}/webhook`, method: 'POST' }), invalidatesTags: ['Repository'], }), - getFrontendSettings: build.query({ + getFrontendSettings: build.query({ query: () => ({ url: `/settings` }), providesTags: ['Provisioning', 'Repository'], }), - getResourceStats: build.query({ + getResourceStats: build.query({ query: () => ({ url: `/stats` }), providesTags: ['Provisioning', 'Repository'], }), @@ -275,8 +284,8 @@ const injectedRtkApi = api overrideExisting: false, }); export { injectedRtkApi as generatedAPI }; -export type ListJobResponse = /** status 200 OK */ JobList; -export type ListJobArg = { +export type ListJobApiResponse = /** status 200 OK */ JobList; +export type ListJobApiArg = { /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ allowWatchBookmarks?: boolean; /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". @@ -320,15 +329,15 @@ export type ListJobArg = { /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ watch?: boolean; }; -export type GetJobResponse = /** status 200 OK */ Job; -export type GetJobArg = { +export type GetJobApiResponse = /** status 200 OK */ Job; +export type GetJobApiArg = { /** name of the Job */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ pretty?: string; }; -export type ListRepositoryResponse = /** status 200 OK */ RepositoryList; -export type ListRepositoryArg = { +export type ListRepositoryApiResponse = /** status 200 OK */ RepositoryList; +export type ListRepositoryApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ pretty?: string; /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ @@ -372,11 +381,11 @@ export type ListRepositoryArg = { /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ watch?: boolean; }; -export type CreateRepositoryResponse = /** status 200 OK */ +export type CreateRepositoryApiResponse = /** status 200 OK */ | Repository | /** status 201 Created */ Repository | /** status 202 Accepted */ Repository; -export type CreateRepositoryArg = { +export type CreateRepositoryApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ pretty?: string; /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ @@ -387,8 +396,8 @@ export type CreateRepositoryArg = { fieldValidation?: string; repository: Repository; }; -export type DeletecollectionRepositoryResponse = /** status 200 OK */ Status; -export type DeletecollectionRepositoryArg = { +export type DeletecollectionRepositoryApiResponse = /** status 200 OK */ Status; +export type DeletecollectionRepositoryApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ pretty?: string; /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". @@ -438,15 +447,15 @@ export type DeletecollectionRepositoryArg = { /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ timeoutSeconds?: number; }; -export type GetRepositoryResponse = /** status 200 OK */ Repository; -export type GetRepositoryArg = { +export type GetRepositoryApiResponse = /** status 200 OK */ Repository; +export type GetRepositoryApiArg = { /** name of the Repository */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ pretty?: string; }; -export type ReplaceRepositoryResponse = /** status 200 OK */ Repository | /** status 201 Created */ Repository; -export type ReplaceRepositoryArg = { +export type ReplaceRepositoryApiResponse = /** status 200 OK */ Repository | /** status 201 Created */ Repository; +export type ReplaceRepositoryApiArg = { /** name of the Repository */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -459,8 +468,8 @@ export type ReplaceRepositoryArg = { fieldValidation?: string; repository: Repository; }; -export type DeleteRepositoryResponse = /** status 200 OK */ Status | /** status 202 Accepted */ Status; -export type DeleteRepositoryArg = { +export type DeleteRepositoryApiResponse = /** status 200 OK */ Status | /** status 202 Accepted */ Status; +export type DeleteRepositoryApiArg = { /** name of the Repository */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -476,8 +485,8 @@ export type DeleteRepositoryArg = { /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ propagationPolicy?: string; }; -export type CreateRepositoryExportResponse = /** status 200 OK */ Job; -export type CreateRepositoryExportArg = { +export type CreateRepositoryExportApiResponse = /** status 200 OK */ Job; +export type CreateRepositoryExportApiArg = { /** name of the Job */ name: string; body: { @@ -491,7 +500,7 @@ export type CreateRepositoryExportArg = { prefix?: string; }; }; -export type GetRepositoryFilesResponse = /** status 200 OK */ { +export type GetRepositoryFilesApiResponse = /** status 200 OK */ { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion?: string; items?: any[]; @@ -499,14 +508,14 @@ export type GetRepositoryFilesResponse = /** status 200 OK */ { kind?: string; metadata?: any; }; -export type GetRepositoryFilesArg = { +export type GetRepositoryFilesApiArg = { /** name of the ResourceWrapper */ name: string; /** branch or commit hash */ ref?: string; }; -export type GetRepositoryFilesWithPathResponse = /** status 200 OK */ ResourceWrapper; -export type GetRepositoryFilesWithPathArg = { +export type GetRepositoryFilesWithPathApiResponse = /** status 200 OK */ ResourceWrapper; +export type GetRepositoryFilesWithPathApiArg = { /** name of the ResourceWrapper */ name: string; /** path to the resource */ @@ -514,8 +523,8 @@ export type GetRepositoryFilesWithPathArg = { /** branch or commit hash */ ref?: string; }; -export type ReplaceRepositoryFilesWithPathResponse = /** status 200 OK */ ResourceWrapper; -export type ReplaceRepositoryFilesWithPathArg = { +export type ReplaceRepositoryFilesWithPathApiResponse = /** status 200 OK */ ResourceWrapper; +export type ReplaceRepositoryFilesWithPathApiArg = { /** name of the ResourceWrapper */ name: string; /** path to the resource */ @@ -528,8 +537,8 @@ export type ReplaceRepositoryFilesWithPathArg = { [key: string]: any; }; }; -export type CreateRepositoryFilesWithPathResponse = /** status 200 OK */ ResourceWrapper; -export type CreateRepositoryFilesWithPathArg = { +export type CreateRepositoryFilesWithPathApiResponse = /** status 200 OK */ ResourceWrapper; +export type CreateRepositoryFilesWithPathApiArg = { /** name of the ResourceWrapper */ name: string; /** path to the resource */ @@ -542,8 +551,8 @@ export type CreateRepositoryFilesWithPathArg = { [key: string]: any; }; }; -export type DeleteRepositoryFilesWithPathResponse = /** status 200 OK */ ResourceWrapper; -export type DeleteRepositoryFilesWithPathArg = { +export type DeleteRepositoryFilesWithPathApiResponse = /** status 200 OK */ ResourceWrapper; +export type DeleteRepositoryFilesWithPathApiArg = { /** name of the ResourceWrapper */ name: string; /** path to the resource */ @@ -553,15 +562,15 @@ export type DeleteRepositoryFilesWithPathArg = { /** optional message sent with any changes */ message?: string; }; -export type GetRepositoryHistoryResponse = /** status 200 OK */ string; -export type GetRepositoryHistoryArg = { +export type GetRepositoryHistoryApiResponse = /** status 200 OK */ string; +export type GetRepositoryHistoryApiArg = { /** name of the HistoryList */ name: string; /** branch or commit hash */ ref?: string; }; -export type GetRepositoryHistoryWithPathResponse = /** status 200 OK */ string; -export type GetRepositoryHistoryWithPathArg = { +export type GetRepositoryHistoryWithPathApiResponse = /** status 200 OK */ string; +export type GetRepositoryHistoryWithPathApiArg = { /** name of the HistoryList */ name: string; /** path to the resource */ @@ -569,8 +578,8 @@ export type GetRepositoryHistoryWithPathArg = { /** branch or commit hash */ ref?: string; }; -export type CreateRepositoryMigrateResponse = /** status 200 OK */ Job; -export type CreateRepositoryMigrateArg = { +export type CreateRepositoryMigrateApiResponse = /** status 200 OK */ Job; +export type CreateRepositoryMigrateApiArg = { /** name of the Job */ name: string; body: { @@ -582,27 +591,27 @@ export type CreateRepositoryMigrateArg = { prefix?: string; }; }; -export type GetRepositoryRenderWithPathResponse = unknown; -export type GetRepositoryRenderWithPathArg = { +export type GetRepositoryRenderWithPathApiResponse = unknown; +export type GetRepositoryRenderWithPathApiArg = { /** name of the Repository */ name: string; /** path to the resource */ path: string; }; -export type GetRepositoryResourcesResponse = /** status 200 OK */ ResourceList; -export type GetRepositoryResourcesArg = { +export type GetRepositoryResourcesApiResponse = /** status 200 OK */ ResourceList; +export type GetRepositoryResourcesApiArg = { /** name of the ResourceList */ name: string; }; -export type GetRepositoryStatusResponse = /** status 200 OK */ Repository; -export type GetRepositoryStatusArg = { +export type GetRepositoryStatusApiResponse = /** status 200 OK */ Repository; +export type GetRepositoryStatusApiArg = { /** name of the Repository */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ pretty?: string; }; -export type ReplaceRepositoryStatusResponse = /** status 200 OK */ Repository | /** status 201 Created */ Repository; -export type ReplaceRepositoryStatusArg = { +export type ReplaceRepositoryStatusApiResponse = /** status 200 OK */ Repository | /** status 201 Created */ Repository; +export type ReplaceRepositoryStatusApiArg = { /** name of the Repository */ name: string; /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -615,8 +624,8 @@ export type ReplaceRepositoryStatusArg = { fieldValidation?: string; repository: Repository; }; -export type CreateRepositorySyncResponse = /** status 200 OK */ Job; -export type CreateRepositorySyncArg = { +export type CreateRepositorySyncApiResponse = /** status 200 OK */ Job; +export type CreateRepositorySyncApiArg = { /** name of the Job */ name: string; body: { @@ -624,8 +633,8 @@ export type CreateRepositorySyncArg = { incremental: boolean; }; }; -export type CreateRepositoryTestResponse = /** status 200 OK */ TestResults; -export type CreateRepositoryTestArg = { +export type CreateRepositoryTestApiResponse = /** status 200 OK */ TestResults; +export type CreateRepositoryTestApiArg = { /** name of the TestResults */ name: string; body: { @@ -638,20 +647,20 @@ export type CreateRepositoryTestArg = { status?: any; }; }; -export type GetRepositoryWebhookResponse = /** status 200 OK */ WebhookResponse; -export type GetRepositoryWebhookArg = { +export type GetRepositoryWebhookApiResponse = /** status 200 OK */ WebhookResponse; +export type GetRepositoryWebhookApiArg = { /** name of the WebhookResponse */ name: string; }; -export type CreateRepositoryWebhookResponse = /** status 200 OK */ WebhookResponse; -export type CreateRepositoryWebhookArg = { +export type CreateRepositoryWebhookApiResponse = /** status 200 OK */ WebhookResponse; +export type CreateRepositoryWebhookApiArg = { /** name of the WebhookResponse */ name: string; }; -export type GetFrontendSettingsResponse = /** status 200 undefined */ RepositoryViewList; -export type GetFrontendSettingsArg = void; -export type GetResourceStatsResponse = /** status 200 undefined */ ResourceStats; -export type GetResourceStatsArg = void; +export type GetFrontendSettingsApiResponse = /** status 200 undefined */ RepositoryViewList; +export type GetFrontendSettingsApiArg = void; +export type GetResourceStatsApiResponse = /** status 200 undefined */ ResourceStats; +export type GetResourceStatsApiArg = void; export type Time = string; export type FieldsV1 = object; export type ManagedFieldsEntry = { diff --git a/public/app/features/provisioning/api/index.ts b/public/app/api/clients/provisioning/index.ts similarity index 100% rename from public/app/features/provisioning/api/index.ts rename to public/app/api/clients/provisioning/index.ts diff --git a/public/app/features/provisioning/api/utils/createOnCacheEntryAdded.ts b/public/app/api/clients/provisioning/utils/createOnCacheEntryAdded.ts similarity index 94% rename from public/app/features/provisioning/api/utils/createOnCacheEntryAdded.ts rename to public/app/api/clients/provisioning/utils/createOnCacheEntryAdded.ts index 14226987468..724eb79193d 100644 --- a/public/app/features/provisioning/api/utils/createOnCacheEntryAdded.ts +++ b/public/app/api/clients/provisioning/utils/createOnCacheEntryAdded.ts @@ -1,7 +1,7 @@ import { Subscription } from 'rxjs'; -import { ScopedResourceClient } from '../../../apiserver/client'; -import { ListOptions } from '../../../apiserver/types'; +import { ScopedResourceClient } from '../../../../features/apiserver/client'; +import { ListOptions } from '../../../../features/apiserver/types'; import { ListMeta, ObjectMeta } from '../endpoints.gen'; /** diff --git a/public/app/features/provisioning/api/utils/getListParams.ts b/public/app/api/clients/provisioning/utils/getListParams.ts similarity index 65% rename from public/app/features/provisioning/api/utils/getListParams.ts rename to public/app/api/clients/provisioning/utils/getListParams.ts index 0e4df8c9e17..eb4af0ab6e7 100644 --- a/public/app/features/provisioning/api/utils/getListParams.ts +++ b/public/app/api/clients/provisioning/utils/getListParams.ts @@ -1,8 +1,8 @@ -import { parseListOptionsSelector } from '../../../apiserver/client'; -import { ListOptions } from '../../../apiserver/types'; -import { ListRepositoryArg } from '../endpoints.gen'; +import { parseListOptionsSelector } from '../../../../features/apiserver/client'; +import { ListOptions } from '../../../../features/apiserver/types'; +import { ListRepositoryApiArg } from '../endpoints.gen'; -type ListParams = Omit & +type ListParams = Omit & Pick; /** diff --git a/public/app/core/reducers/root.ts b/public/app/core/reducers/root.ts index 1609cf7c1a2..319344500c6 100644 --- a/public/app/core/reducers/root.ts +++ b/public/app/core/reducers/root.ts @@ -27,11 +27,11 @@ import teamsReducers from 'app/features/teams/state/reducers'; import usersReducers from 'app/features/users/state/reducers'; import templatingReducers from 'app/features/variables/state/keyedVariablesReducer'; +import { folderAPI } from '../../api/clients/folder'; +import { iamAPI } from '../../api/clients/iam'; +import { provisioningAPI } from '../../api/clients/provisioning'; import { alertingApi } from '../../features/alerting/unified/api/alertingApi'; -import { folderAPI } from '../../features/folders/api'; -import { iamApi } from '../../features/iam/api/api'; import { userPreferencesAPI } from '../../features/preferences/api'; -import { provisioningAPI } from '../../features/provisioning/api'; import { cleanUpAction } from '../actions/cleanUp'; const rootReducers = { @@ -61,7 +61,7 @@ const rootReducers = { [publicDashboardApi.reducerPath]: publicDashboardApi.reducer, [browseDashboardsAPI.reducerPath]: browseDashboardsAPI.reducer, [cloudMigrationAPI.reducerPath]: cloudMigrationAPI.reducer, - [iamApi.reducerPath]: iamApi.reducer, + [iamAPI.reducerPath]: iamAPI.reducer, [userPreferencesAPI.reducerPath]: userPreferencesAPI.reducer, [provisioningAPI.reducerPath]: provisioningAPI.reducer, [folderAPI.reducerPath]: folderAPI.reducer, diff --git a/public/app/features/iam/index.ts b/public/app/features/iam/index.ts deleted file mode 100644 index 5236538f8dd..00000000000 --- a/public/app/features/iam/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { generatedIamApi } from './api/endpoints.gen'; - -export const { useGetDisplayMappingQuery } = generatedIamApi; diff --git a/public/app/features/provisioning/hooks/useCreateOrUpdateRepository.ts b/public/app/features/provisioning/hooks/useCreateOrUpdateRepository.ts index 37f803a9838..b25f53003c3 100644 --- a/public/app/features/provisioning/hooks/useCreateOrUpdateRepository.ts +++ b/public/app/features/provisioning/hooks/useCreateOrUpdateRepository.ts @@ -1,6 +1,10 @@ import { useCallback } from 'react'; -import { RepositorySpec, useCreateRepositoryMutation, useReplaceRepositoryMutation } from '../api'; +import { + RepositorySpec, + useCreateRepositoryMutation, + useReplaceRepositoryMutation, +} from '../../../api/clients/provisioning'; export function useCreateOrUpdateRepository(name?: string) { const [create, createRequest] = useCreateRepositoryMutation(); diff --git a/public/app/features/provisioning/hooks/useCreateOrUpdateRepositoryFile.ts b/public/app/features/provisioning/hooks/useCreateOrUpdateRepositoryFile.ts index dbcc9ffb978..b7cc98380d3 100644 --- a/public/app/features/provisioning/hooks/useCreateOrUpdateRepositoryFile.ts +++ b/public/app/features/provisioning/hooks/useCreateOrUpdateRepositoryFile.ts @@ -1,17 +1,17 @@ import { useCallback } from 'react'; import { - ReplaceRepositoryFilesWithPathArg, + ReplaceRepositoryFilesWithPathApiArg, useCreateRepositoryFilesWithPathMutation, useReplaceRepositoryFilesWithPathMutation, -} from '../api'; +} from '../../../api/clients/provisioning'; export function useCreateOrUpdateRepositoryFile(name?: string) { const [create, createRequest] = useCreateRepositoryFilesWithPathMutation(); const [update, updateRequest] = useReplaceRepositoryFilesWithPathMutation(); const updateOrCreate = useCallback( - (data: ReplaceRepositoryFilesWithPathArg) => { + (data: ReplaceRepositoryFilesWithPathApiArg) => { const actions = name ? update : create; return actions(data); }, diff --git a/public/app/features/provisioning/hooks/useGetResourceRepository.ts b/public/app/features/provisioning/hooks/useGetResourceRepository.ts index 1d09d69141c..c47fb4d554a 100644 --- a/public/app/features/provisioning/hooks/useGetResourceRepository.ts +++ b/public/app/features/provisioning/hooks/useGetResourceRepository.ts @@ -1,7 +1,7 @@ import { skipToken } from '@reduxjs/toolkit/query/react'; +import { useGetFolderQuery } from '../../../api/clients/folder'; import { AnnoKeyManagerKind } from '../../apiserver/types'; -import { useGetFolderQuery } from '../../folders/api'; import { useRepositoryList } from './useRepositoryList'; diff --git a/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts b/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts index 441552a392b..3de98a2c935 100644 --- a/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts +++ b/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts @@ -1,6 +1,6 @@ import { skipToken } from '@reduxjs/toolkit/query'; -import { RepositoryViewList, useGetFrontendSettingsQuery } from '../api'; +import { RepositoryViewList, useGetFrontendSettingsQuery } from '../../../api/clients/provisioning'; import { checkSyncSettings } from '../utils/checkSyncSettings'; export function useIsProvisionedInstance(settings?: RepositoryViewList) { diff --git a/public/app/features/provisioning/hooks/useIsProvisionedNG.ts b/public/app/features/provisioning/hooks/useIsProvisionedNG.ts index 74ac239ad83..cacd1be26d3 100644 --- a/public/app/features/provisioning/hooks/useIsProvisionedNG.ts +++ b/public/app/features/provisioning/hooks/useIsProvisionedNG.ts @@ -1,7 +1,7 @@ import { useUrlParams } from 'app/core/navigation/hooks'; +import { useGetFrontendSettingsQuery } from '../../../api/clients/provisioning'; import { DashboardScene } from '../../dashboard-scene/scene/DashboardScene'; -import { useGetFrontendSettingsQuery } from '../api'; import { useGetResourceRepository } from './useGetResourceRepository'; diff --git a/public/app/features/provisioning/hooks/useRepositoryJobs.ts b/public/app/features/provisioning/hooks/useRepositoryJobs.ts index 1935cf167ef..affdfc6a87d 100644 --- a/public/app/features/provisioning/hooks/useRepositoryJobs.ts +++ b/public/app/features/provisioning/hooks/useRepositoryJobs.ts @@ -1,6 +1,6 @@ import { skipToken } from '@reduxjs/toolkit/query/react'; -import { Job, useListJobQuery } from '../api'; +import { Job, useListJobQuery } from '../../../api/clients/provisioning'; interface RepositoryJobsArgs { name?: string; diff --git a/public/app/features/provisioning/hooks/useRepositoryList.ts b/public/app/features/provisioning/hooks/useRepositoryList.ts index fe68c11ae43..e4622c2f2bb 100644 --- a/public/app/features/provisioning/hooks/useRepositoryList.ts +++ b/public/app/features/provisioning/hooks/useRepositoryList.ts @@ -1,10 +1,10 @@ import { skipToken } from '@reduxjs/toolkit/query'; -import { ListRepositoryArg, Repository, useListRepositoryQuery } from '../api'; +import { ListRepositoryApiArg, Repository, useListRepositoryQuery } from '../../../api/clients/provisioning'; // Sort repositories alphabetically by title export function useRepositoryList( - options: ListRepositoryArg | typeof skipToken = {} + options: ListRepositoryApiArg | typeof skipToken = {} ): [Repository[] | undefined, boolean] { const query = useListRepositoryQuery(options); const collator = new Intl.Collator(undefined, { numeric: true }); diff --git a/public/app/features/provisioning/types.ts b/public/app/features/provisioning/types.ts index 2fffca4e522..fbe4cbfda1d 100644 --- a/public/app/features/provisioning/types.ts +++ b/public/app/features/provisioning/types.ts @@ -1,4 +1,4 @@ -import { GitHubRepositoryConfig, LocalRepositoryConfig, RepositorySpec } from './api'; +import { GitHubRepositoryConfig, LocalRepositoryConfig, RepositorySpec } from '../../api/clients/provisioning'; export type RepositoryFormData = Omit & GitHubRepositoryConfig & diff --git a/public/app/features/provisioning/utils/checkSyncSettings.ts b/public/app/features/provisioning/utils/checkSyncSettings.ts index a69eee3f9d5..40f07afd6ea 100644 --- a/public/app/features/provisioning/utils/checkSyncSettings.ts +++ b/public/app/features/provisioning/utils/checkSyncSettings.ts @@ -1,4 +1,4 @@ -import { RepositoryViewList } from '../api'; +import { RepositoryViewList } from '../../../api/clients/provisioning'; export function checkSyncSettings(settings?: RepositoryViewList): [boolean, boolean] { if (!settings?.items?.length) { diff --git a/public/app/features/provisioning/utils/data.ts b/public/app/features/provisioning/utils/data.ts index bf83b161eca..13e4910df9e 100644 --- a/public/app/features/provisioning/utils/data.ts +++ b/public/app/features/provisioning/utils/data.ts @@ -1,4 +1,4 @@ -import { RepositorySpec } from '../api'; +import { RepositorySpec } from '../../../api/clients/provisioning'; import { RepositoryFormData } from '../types'; export const dataToSpec = (data: RepositoryFormData): RepositorySpec => { diff --git a/public/app/features/provisioning/api/selectors.ts b/public/app/features/provisioning/utils/selectors.ts similarity index 90% rename from public/app/features/provisioning/api/selectors.ts rename to public/app/features/provisioning/utils/selectors.ts index 1ea0f43416b..b4f4ef4c95d 100644 --- a/public/app/features/provisioning/api/selectors.ts +++ b/public/app/features/provisioning/utils/selectors.ts @@ -2,9 +2,7 @@ import { createSelector } from '@reduxjs/toolkit'; import { RootState } from 'app/store/configureStore'; -import { Repository } from './endpoints.gen'; - -import { provisioningAPI } from './index'; +import { Repository, provisioningAPI } from '../../../api/clients/provisioning/index'; const emptyRepos: Repository[] = []; diff --git a/public/app/features/provisioning/api/types.ts b/public/app/features/provisioning/utils/types.ts similarity index 100% rename from public/app/features/provisioning/api/types.ts rename to public/app/features/provisioning/utils/types.ts diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 639ac168787..89629e77a86 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -8,12 +8,12 @@ import { cloudMigrationAPI } from 'app/features/migrate-to-cloud/api'; import { userPreferencesAPI } from 'app/features/preferences/api'; import { StoreState } from 'app/types/store'; +import { folderAPI } from '../api/clients/folder'; +import { iamAPI } from '../api/clients/iam'; +import { provisioningAPI } from '../api/clients/provisioning'; import { buildInitialState } from '../core/reducers/navModel'; import { addReducer, createRootReducer } from '../core/reducers/root'; import { alertingApi } from '../features/alerting/unified/api/alertingApi'; -import { folderAPI } from '../features/folders/api'; -import { iamApi } from '../features/iam/api/api'; -import { provisioningAPI } from '../features/provisioning/api'; import { setStore } from './store'; @@ -42,7 +42,7 @@ export function configureStore(initialState?: Partial) { browseDashboardsAPI.middleware, cloudMigrationAPI.middleware, userPreferencesAPI.middleware, - iamApi.middleware, + iamAPI.middleware, provisioningAPI.middleware, folderAPI.middleware, ...extraMiddleware diff --git a/scripts/generate-rtk-apis.ts b/scripts/generate-rtk-apis.ts index 3bc9ee949fc..efa374be767 100644 --- a/scripts/generate-rtk-apis.ts +++ b/scripts/generate-rtk-apis.ts @@ -39,34 +39,24 @@ const config: ConfigFile = { apiImport: 'baseAPI', filterEndpoints: ['getUserPreferences', 'updateUserPreferences', 'patchUserPreferences'], }, - '../public/app/features/iam/api/endpoints.gen.ts': { + '../public/app/api/clients/iam/endpoints.gen.ts': { schemaFile: '../data/openapi/iam.grafana.app-v0alpha1.json', - apiFile: '../public/app/features/iam/api/api.ts', - apiImport: 'iamApi', + apiFile: '../public/app/api/clients/iam/baseAPI.ts', filterEndpoints: ['getDisplayMapping'], - exportName: 'generatedIamApi', - flattenArg: false, tag: true, }, - '../public/app/features/provisioning/api/endpoints.gen.ts': { - apiFile: '../public/app/features/provisioning/api/baseAPI.ts', + '../public/app/api/clients/provisioning/endpoints.gen.ts': { + apiFile: '../public/app/api/clients/provisioning/baseAPI.ts', schemaFile: '../data/openapi/provisioning.grafana.app-v0alpha1.json', - apiImport: 'baseAPI', filterEndpoints, - argSuffix: 'Arg', - responseSuffix: 'Response', tag: true, hooks: true, }, - '../public/app/features/folders/api/endpoints.gen.ts': { - apiFile: '../public/app/features/folders/api/baseAPI.ts', + '../public/app/api/clients/folder/endpoints.gen.ts': { + apiFile: '../public/app/api/clients/folder/baseAPI.ts', schemaFile: '../data/openapi/folder.grafana.app-v0alpha1.json', - apiImport: 'baseAPI', filterEndpoints: ['getFolder'], - argSuffix: 'Arg', - responseSuffix: 'Response', tag: true, - hooks: true, }, }, }; From 38d94b86ecd83f4e463bf771b869809de22a0cb5 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 14 Mar 2025 15:03:45 +0000 Subject: [PATCH 4/5] Api clients: fix import to point to new centralised client (#102208) fix import to point to new centralised client --- public/app/features/provisioning/dashboardLoader.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/app/features/provisioning/dashboardLoader.ts b/public/app/features/provisioning/dashboardLoader.ts index 914d42da88a..b75c691067b 100644 --- a/public/app/features/provisioning/dashboardLoader.ts +++ b/public/app/features/provisioning/dashboardLoader.ts @@ -1,10 +1,9 @@ import { getBackendSrv } from '@grafana/runtime'; import { DashboardDTO } from 'app/types'; +import { BASE_URL } from '../../api/clients/provisioning/baseAPI'; import { AnnoKeyManagerIdentity, AnnoKeyManagerKind, AnnoKeySourcePath } from '../apiserver/types'; -import { BASE_URL } from './api/baseAPI'; - /** * * Load a dashboard from repository From b3452ae72029b57d3b8c2937986149e701853cd9 Mon Sep 17 00:00:00 2001 From: Syerikjan Kh Date: Fri, 14 Mar 2025 11:05:27 -0400 Subject: [PATCH 5/5] feat: datasourceconnectionsTab to private preview (#102200) --- .../configure-grafana/feature-toggles/index.md | 1 - pkg/services/featuremgmt/registry.go | 2 +- pkg/services/featuremgmt/toggles_gen.csv | 2 +- pkg/services/featuremgmt/toggles_gen.json | 6 +++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 23849201ec7..8691417c8b7 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -222,7 +222,6 @@ Experimental features might be changed or removed without prior notice. | `templateVariablesUsesCombobox` | Use new combobox component for template variables | | `grafanaAdvisor` | Enables Advisor app | | `elasticsearchImprovedParsing` | Enables less memory intensive Elasticsearch result parsing | -| `datasourceConnectionsTab` | Shows defined connections for a data source in the plugins detail page | | `newLogsPanel` | Enables the new logs panel in Explore | | `pluginsCDNSyncLoader` | Load plugins from CDN synchronously | | `assetSriChecks` | Enables SRI checks for Grafana JavaScript assets | diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 69edda72941..d9053899ef8 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -1669,7 +1669,7 @@ var ( { Name: "datasourceConnectionsTab", Description: "Shows defined connections for a data source in the plugins detail page", - Stage: FeatureStageExperimental, + Stage: FeatureStagePrivatePreview, Owner: grafanaPluginsPlatformSquad, RequiresDevMode: false, FrontendOnly: true, diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 8e5f863480e..4d6d6ca54bc 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -221,7 +221,7 @@ ABTestFeatureToggleB,experimental,@grafana/sharing-squad,false,false,false grafanaAdvisor,experimental,@grafana/plugins-platform-backend,false,false,false elasticsearchImprovedParsing,experimental,@grafana/aws-datasources,false,false,false exploreMetricsUseExternalAppPlugin,preview,@grafana/observability-metrics,false,true,true -datasourceConnectionsTab,experimental,@grafana/plugins-platform-backend,false,false,true +datasourceConnectionsTab,privatePreview,@grafana/plugins-platform-backend,false,false,true fetchRulesUsingPost,experimental,@grafana/alerting-squad,false,false,false alertingConversionAPI,experimental,@grafana/alerting-squad,false,false,false alertingAlertmanagerExtraDedupStage,experimental,@grafana/alerting-squad,false,true,false diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index a92ebcadc16..89f92814f9f 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -1293,15 +1293,15 @@ { "metadata": { "name": "datasourceConnectionsTab", - "resourceVersion": "1737049826022", + "resourceVersion": "1741961069415", "creationTimestamp": "2025-01-21T17:39:48Z", "annotations": { - "grafana.app/updatedTimestamp": "2025-01-16 17:50:26.022636488 +0000 UTC" + "grafana.app/updatedTimestamp": "2025-03-14 14:04:29.415154706 +0000 UTC" } }, "spec": { "description": "Shows defined connections for a data source in the plugins detail page", - "stage": "experimental", + "stage": "privatePreview", "codeowner": "@grafana/plugins-platform-backend", "frontend": true }