Skip to content

Commit

Permalink
[Improve]: add openapi schema modal (#3915)
Browse files Browse the repository at this point in the history
* [Improve]: add openapi schema modal

* [Improve]: modal title

* [Fix]: api method style

* [Fix]: License header

---------

Co-authored-by: benjobs <[email protected]>
  • Loading branch information
wangsizhu0504 and wolfboys authored Jul 25, 2024
1 parent 8b580f1 commit c7b6b41
Show file tree
Hide file tree
Showing 15 changed files with 383 additions and 57 deletions.
16 changes: 16 additions & 0 deletions streampark-console/streampark-console-webapp/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

package-manager-strict=false
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ enum SAVE_POINT_API {
export function fetchLatest(data: Recordable) {
return defHttp.post({ url: SAVE_POINT_API.LATEST, data });
}
export function fetchSavePonitHistory(data: Recordable) {
export function fetchSavePointHistory(data: Recordable) {
return defHttp.post({ url: SAVE_POINT_API.HISTORY, data });
}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ enum Api {
* @param data
* @returns {Promise<number>}
*/
export function fetchApiSchema(data) {
return defHttp.post<number>({ url: Api.SCHEMA, data });
export function fetchApiSchema(data: { name: string }) {
return defHttp.post({ url: Api.SCHEMA, data });
}
/**
* copyCurl
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { withInstall } from '/@/utils';

import openApi from './src';

export const OpenApi = withInstall(openApi);
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Divider, Table, Tag, type TableColumnType, Empty, Skeleton } from 'ant-design-vue';
import { defineComponent, ref, shallowRef, watchEffect } from 'vue';
import { fetchApiSchema } from '/@/api/system/openapi';
import { baseUrl } from '/@/api';
import { useAppStore } from '/@/store/modules/app';
import { ThemeEnum } from '/@/enums/appEnum';
import { useI18n } from '/@/hooks/web/useI18n';
interface RequestSchemas {
url: string;
method?: string;
params?: Recordable[];
body?: Recordable[];
header?: Recordable[];
}

const methodMap = {
GET: {
lightColor: '#22c55e',
darkColor: '#10b981',
},
POST: {
lightColor: '#f59e0b',
darkColor: '#eab308',
},
PUT: {
lightColor: '#3b82f6',
darkColor: '#0ea5e9 ',
},
DELETE: {
lightColor: '#ef4444',
darkColor: '#f43f5e',
},
PATCH: {
lightColor: '#a855f7',
darkColor: '#8b5cf6',
},
DEFAULT: {
lightColor: '#737373',
darkColor: '#71717a',
},
} as const;
export default defineComponent({
name: 'OpenApi',
props: {
name: {
type: String,
required: true,
},
},
setup(props) {
const requestRef = shallowRef<RequestSchemas>({
url: '',
});
const { t } = useI18n();
const fetchLoading = ref(false);
const appStore = useAppStore();
const handleGetRequestSchemas = async () => {
try {
fetchLoading.value = true;
const resp = await fetchApiSchema({
name: props.name,
});
requestRef.value = {
url: baseUrl() + resp.url,
method: resp.method,
params: resp.schema,
body: resp.body,
header: resp.header,
};
} catch (error) {
console.error(error);
} finally {
fetchLoading.value = false;
}
};
const tableColumns = shallowRef<TableColumnType[]>([
{ title: t('component.openApi.param'), dataIndex: 'name', width: 160 },
{ title: t('component.openApi.defaultValue'), dataIndex: 'defaultValue', width: 130 },
{ title: t('component.openApi.type'), dataIndex: 'type', width: 150 },
{
title: t('component.openApi.required'),
dataIndex: 'required',
customRender: ({ text }) => (
<Tag color={text ? 'success' : 'error'}>{text ? t('common.yes') : t('common.no')}</Tag>
),
},
{ title: t('component.openApi.description'), dataIndex: 'description' },
]);

watchEffect(() => {
if (props.name) {
handleGetRequestSchemas();
}
});

const renderParams = () => {
if (!requestRef.value.params) return null;
return (
<>
<Divider orientation="left">Params</Divider>
{renderTableData(requestRef.value.params)}
</>
);
};

const renderBody = () => {
if (!requestRef.value.body) return null;
return (
<>
<Divider orientation="left">Body</Divider>
{renderTableData(requestRef.value.body)}
</>
);
};
const renderHeader = () => {
if (!requestRef.value.header) return null;
return (
<>
<Divider orientation="left">Header</Divider>
{renderTableData(requestRef.value.header)}
</>
);
};
const renderTableData = (data: Recordable[]) => {
if (!data || (Array.isArray(data) && data.length === 0))
return (
<>
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
v-slots={{
description: () => <span class="text-gray-4">{t('component.openApi.empty')}</span>,
}}
></Empty>
</>
);
return (
<>
<Table
size="small"
bordered
pagination={false}
dataSource={data}
columns={tableColumns.value}
></Table>
</>
);
};
const renderRequestMethod = () => {
if (!requestRef.value.method) return null;
const currentMethod =
methodMap[requestRef.value.method.toLocaleUpperCase()] ?? methodMap.DEFAULT;
const darkMode = appStore.getDarkMode === ThemeEnum.DARK;
return (
<div class="relative flex">
<label for="method">
<span class="flex overflow-hidden text-ellipsis whitespace-nowrap">
<div class="flex flex-1 relative">
<div
id="method"
class="flex w-20 rounded-l bg-[#f9fafb] dark:bg-[#1c1c1e] px-4 py-2 font-semibold justify-center transition"
style={{
color: darkMode ? currentMethod.lightColor : currentMethod.darkColor,
}}
>
{requestRef.value.method.toLocaleUpperCase()}
</div>
</div>
</span>
</label>
</div>
);
};

return () => (
<>
<Skeleton loading={fetchLoading.value} active>
<div class="flex-none flex-shrink-0 ">
<div class="min-w-[12rem] flex min-h-9 flex-1 whitespace-nowrap rounded border dark:border-[#1f1f1f] border-[#f3f4f6]">
{renderRequestMethod()}
<div
class="flex flex-1 items-center text-[#111827] whitespace-nowrap rounded-r border-l border-[#f3f4f6] bg-[#f9fafb] dark:bg-[#1c1c1e] dark:border-[#1f1f1f] transition "
style="padding-left:10px"
>
{requestRef.value.url}
</div>
</div>
</div>
{renderHeader()}
{renderParams()}
{renderBody()}
</Skeleton>
</>
);
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ span.anticon:not(.app-iconify) {
}

.app-bar,
.streampark-basic-title {
div:not(.ant-modal-title)>.streampark-basic-title {
background-color: @background-color-base;
height: 100%;
font-size: 14px !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,12 @@ export default {
dragText: 'Hold down the slider and drag',
successText: 'Verified',
},
openApi: {
param: 'Parameter Name',
defaultValue: 'Default Value',
type: 'Type',
required: 'Required',
description: 'Description',
empty: 'This request has no data of this type',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ export default {
compare: 'Compare',
compareSelectTips: 'Please select the target version',
resetApi: 'Rest Api',
copyCurl: 'Copy Curl',
apiTitle: 'Api Detail',
resetApiToolTip:
'Rest API external call interface,other third-party systems easy to access StreamPark',
copyStartcURL: 'App Start',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,12 @@ export default {
dragText: '请按住滑块拖动',
successText: '验证通过',
},
openApi: {
param: '参数名',
defaultValue: '默认值',
required: '必填',
type: '类型',
description: '说明',
empty: '该请求暂无该类型数据',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export default {
compare: '比较',
compareSelectTips: '请选择目标板本',
resetApi: 'Open API',
copyCurl: '复制 CURL',
apiTitle: 'Api 详情',
resetApiToolTip: 'OPEN API,第三方系统可轻松对接 StreamPark',
copyStartcURL: '作业启动',
copyCancelcURL: '作业停止',
Expand Down
Loading

0 comments on commit c7b6b41

Please sign in to comment.