Skip to content

Commit f55f3f8

Browse files
authored
feat: API page rework (#996)
1 parent 5df3415 commit f55f3f8

File tree

10 files changed

+86
-1167
lines changed

10 files changed

+86
-1167
lines changed

packages/app-builder/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
"@types/qs": "^6.9.18",
2727
"@types/react": "18.3.11",
2828
"@types/react-dom": "18.3.1",
29-
"@types/swagger-ui-react": "^5.18.0",
3029
"autoprefixer": "^10.4.21",
3130
"jsdom": "26.0.0",
3231
"ora": "^8.2.0",
@@ -114,7 +113,6 @@
114113
"sharpstate": "^0.0.13",
115114
"short-uuid": "^5.2.0",
116115
"spin-delay": "^2.0.1",
117-
"swagger-ui-react": "^5.20.1",
118116
"temporal-polyfill": "^0.2.5",
119117
"tiny-invariant": "^1.3.3",
120118
"ts-pattern": "^5.6.2",
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"download_openapi_spec": "تنزيل مواصفات OpenAPI"
2+
"download_openapi_spec": "تنزيل مواصفات OpenAPI v0 (مهمل)",
3+
"download_openapi_spec_v1": "تنزيل مواصفات OpenAPI v1"
34
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"download_openapi_spec": "Download OpenAPI specification"
2+
"download_openapi_spec": "Download OpenAPI specification v0 (Deprecated)",
3+
"download_openapi_spec_v1": "Download OpenAPI specification v1"
34
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"download_openapi_spec": "Télécharger la spécification OpenAPI"
2+
"download_openapi_spec": "Télécharger la spécification OpenAPI v0 (Déprécié)",
3+
"download_openapi_spec_v1": "Télécharger la spécification OpenAPI v1"
34
}

packages/app-builder/src/repositories/DataModelRepository.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { type OpenApiSpec } from 'marble-api';
3030
export interface DataModelRepository {
3131
getDataModel(): Promise<DataModel>;
3232
getOpenApiSpec(): Promise<OpenApiSpec>;
33+
getOpenApiSpecOfVersion(version: string): Promise<OpenApiSpec>;
3334
postDataModelTableField(tableId: string, createFieldInput: CreateFieldInput): Promise<void>;
3435
patchDataModelField(tableId: string, updateFieldInput: UpdateFieldInput): Promise<void>;
3536
listPivots(args: { tableId?: string }): Promise<Pivot[]>;
@@ -56,6 +57,9 @@ export function makeGetDataModelRepository() {
5657
getOpenApiSpec: async () => {
5758
return marbleCoreApiClient.getDataModelOpenApi();
5859
},
60+
getOpenApiSpecOfVersion: async (version: string) => {
61+
return marbleCoreApiClient.getDataModelOpenApiOfVersion(version);
62+
},
5963
postDataModelTableField: async (tableId, createFieldInput) => {
6064
await marbleCoreApiClient.postDataModelTableField(
6165
tableId,

packages/app-builder/src/routes/_builder+/api.tsx

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,14 @@ import {
77
import { initServerServices } from '@app-builder/services/init.server';
88
import { downloadFile } from '@app-builder/utils/download-file';
99
import { getRoute } from '@app-builder/utils/routes';
10-
import { json, type LinksFunction, type LoaderFunctionArgs } from '@remix-run/node';
10+
import { type LoaderFunctionArgs } from '@remix-run/node';
1111
import { useLoaderData } from '@remix-run/react';
1212
import { type Namespace } from 'i18next';
13-
import * as React from 'react';
1413
import toast from 'react-hot-toast';
1514
import { useTranslation } from 'react-i18next';
16-
import * as R from 'remeda';
17-
import swaggercss from 'swagger-ui-react/swagger-ui.css?url';
1815
import { Button } from 'ui-design-system';
1916
import { Icon } from 'ui-icons';
2017

21-
const SwaggerUI = React.lazy(() => import('swagger-ui-react'));
22-
2318
export const handle = {
2419
i18n: ['common', 'navigation', 'api'] satisfies Namespace,
2520
BreadCrumbs: [
@@ -36,30 +31,26 @@ export const handle = {
3631
],
3732
};
3833

39-
export const links: LinksFunction = () =>
40-
swaggercss ? [{ rel: 'stylesheet', href: swaggercss }] : [];
41-
4234
export async function loader({ request }: LoaderFunctionArgs) {
4335
const { authService } = initServerServices(request);
4436
const { dataModelRepository } = await authService.isAuthenticated(request, {
4537
failureRedirect: getRoute('/sign-in'),
4638
});
4739

48-
const openapi = await dataModelRepository.getOpenApiSpec();
49-
return json({ openapi });
40+
const [openapi, openapiV1] = await Promise.all([
41+
dataModelRepository.getOpenApiSpec(),
42+
dataModelRepository.getOpenApiSpecOfVersion('v1'),
43+
]);
44+
45+
return Response.json({ openapi, openapiV1 });
5046
}
5147

5248
export default function Api() {
5349
const { t } = useTranslation(handle.i18n);
54-
const { openapi } = useLoaderData<typeof loader>();
50+
const { openapi, openapiV1 } = useLoaderData<typeof loader>();
5551

56-
// Remove those parts, because they are part of the proper openapi spec but we do not want them as input to SwaggerUI
57-
const openapiWithoutSomeParts = React.useMemo(() => {
58-
const openapiWithoutSomeParts = R.clone(openapi);
59-
delete openapiWithoutSomeParts.info;
60-
delete openapiWithoutSomeParts.components?.securitySchemes;
61-
return openapiWithoutSomeParts;
62-
}, [openapi]);
52+
console.log('openapi', openapi);
53+
console.log('openapiV1', openapiV1);
6354

6455
return (
6556
<Page.Main>
@@ -68,7 +59,24 @@ export default function Api() {
6859
</Page.Header>
6960
<Page.Container>
7061
<Page.Content>
71-
<div className="flex">
62+
<div className="flex flex-col gap-2 items-start">
63+
<Button
64+
variant="secondary"
65+
onClick={() => {
66+
try {
67+
const blob = new Blob([JSON.stringify(openapiV1)], {
68+
type: 'application/json;charset=utf-8,',
69+
});
70+
const url = URL.createObjectURL(blob);
71+
void downloadFile(url, 'openapi-v1.json');
72+
} catch (_error) {
73+
toast.error(t('common:errors.unknown'));
74+
}
75+
}}
76+
>
77+
<Icon icon="download" className="me-2 size-6" />
78+
{t('api:download_openapi_spec_v1')}
79+
</Button>
7280
<Button
7381
variant="secondary"
7482
onClick={() => {
@@ -87,17 +95,6 @@ export default function Api() {
8795
{t('api:download_openapi_spec')}
8896
</Button>
8997
</div>
90-
<div className="-mx-5">
91-
<React.Suspense fallback={t('common:loading')}>
92-
{/* Issue with UNSAFE_componentWillReceiveProps: https://github.com/swagger-api/swagger-ui/issues/5729 */}
93-
<SwaggerUI
94-
spec={openapiWithoutSomeParts}
95-
supportedSubmitMethods={[]}
96-
defaultModelExpandDepth={5}
97-
defaultModelsExpandDepth={4}
98-
/>
99-
</React.Suspense>
100-
</div>
10198
</Page.Content>
10299
</Page.Container>
103100
</Page.Main>

packages/marble-api/openapis/marblecore-api.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ paths:
232232
$ref: ./marblecore-api/data-model.yml#/~1data-model~1links
233233
/data-model/openapi:
234234
$ref: ./marblecore-api/data-model.yml#/~1data-model~1openapi
235+
/data-model/openapi/{version}:
236+
$ref: ./marblecore-api/data-model.yml#/~1data-model~1openapi~1{version}
235237
/data-model/pivots:
236238
$ref: ./marblecore-api/data-model.yml#/~1data-model~1pivots
237239
/data-model/tables/{tableId}/navigation_options:

packages/marble-api/openapis/marblecore-api/data-model.yml

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,39 @@
264264
get:
265265
tags:
266266
- Data Model
267-
summary: Get the OpenAPI specification of the client specific API for data ingestion and decision making
267+
summary: Get the current version of the OpenAPI specification of the client specific API for data ingestion and decision making
268268
operationId: getDataModelOpenApi
269269
security:
270270
- bearerAuth: []
271271
responses:
272272
'200':
273-
description: The OpenAPI specification of the client specific API for data ingestion and decision making
273+
description: The OpenAPI specification of the client specific API for data ingestion and decision making for the current version
274+
content:
275+
application/json:
276+
schema:
277+
$ref: '#/components/schemas/OpenAPISpec'
278+
'401':
279+
$ref: 'components.yml#/responses/401'
280+
'403':
281+
$ref: 'components.yml#/responses/403'
282+
/data-model/openapi/{version}:
283+
get:
284+
tags:
285+
- Data Model
286+
summary: Get the OpenAPI specification of the client specific API for data ingestion and decision making for a specific version
287+
operationId: getDataModelOpenApiOfVersion
288+
security:
289+
- bearerAuth: []
290+
parameters:
291+
- name: version
292+
description: Version of the API to get the OpenAPI specification for
293+
in: path
294+
required: true
295+
schema:
296+
type: string
297+
responses:
298+
'200':
299+
description: The OpenAPI specification of the client specific API for data ingestion and decision making for the provided version
274300
content:
275301
application/json:
276302
schema:

packages/marble-api/src/generated/marblecore-api.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3292,7 +3292,7 @@ export function postDataModelTableLink(createTableLinkBody: CreateTableLinkBody,
32923292
})));
32933293
}
32943294
/**
3295-
* Get the OpenAPI specification of the client specific API for data ingestion and decision making
3295+
* Get the current version of the OpenAPI specification of the client specific API for data ingestion and decision making
32963296
*/
32973297
export function getDataModelOpenApi(opts?: Oazapfts.RequestOpts) {
32983298
return oazapfts.ok(oazapfts.fetchJson<{
@@ -3308,6 +3308,23 @@ export function getDataModelOpenApi(opts?: Oazapfts.RequestOpts) {
33083308
...opts
33093309
}));
33103310
}
3311+
/**
3312+
* Get the OpenAPI specification of the client specific API for data ingestion and decision making for a specific version
3313+
*/
3314+
export function getDataModelOpenApiOfVersion(version: string, opts?: Oazapfts.RequestOpts) {
3315+
return oazapfts.ok(oazapfts.fetchJson<{
3316+
status: 200;
3317+
data: OpenApiSpec;
3318+
} | {
3319+
status: 401;
3320+
data: string;
3321+
} | {
3322+
status: 403;
3323+
data: string;
3324+
}>(`/data-model/openapi/${encodeURIComponent(version)}`, {
3325+
...opts
3326+
}));
3327+
}
33113328
/**
33123329
* Get the pivots associated with the current organization (can be filtered by table_id)
33133330
*/

0 commit comments

Comments
 (0)