Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 59 additions & 18 deletions core/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ const props = withDefaults(defineProps<Props>(), {
const getAppFunc = inject('getAppFunc', (arg: {name: string, func: Function}):void => {});
const dataSource = ref<{[key: string]: any}>();

// Theme management
const currentTheme = ref<'light' | 'dark'>('light');
const toggleTheme = () => {
currentTheme.value = currentTheme.value === 'light' ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', currentTheme.value);
};



const DocInfo = defineAsyncComponent(() => import('./docInfo/formView/index.vue'));
Expand All @@ -35,7 +42,7 @@ const Comp = defineAsyncComponent(() => import('./component/index.vue'));
const ApiModel = defineAsyncComponent(() => import('./component/apisModel/index.vue'));
const PathInfo = defineAsyncComponent(() => import('./pathInfo/index.vue'));

const DocInfoPreview = defineAsyncComponent(() => import('./docInfo/preview/index.vue'));
const DocInfoPreview = defineAsyncComponent(() => import('./docInfo/preView/index.vue'));
const ExternalDocPreview = defineAsyncComponent(() => import('./externalDoc/preView/index.vue'));
const ServerPreview = defineAsyncComponent(() => import('./server/preView/index.vue'));
const SecurityPreview = defineAsyncComponent(() => import('./security/preView/index.vue'));
Expand Down Expand Up @@ -211,6 +218,8 @@ onMounted(() => {
}});

getAppFunc({name: 'changeLanguage', func: handleChangeLanguage });

getAppFunc({name: 'toggleTheme', func: toggleTheme });

watch(() => showPreview.value, (newValue) => {
if (!newValue) {
Expand Down Expand Up @@ -258,44 +267,48 @@ provide('language', language);
</script>

<template>
<div class="api-root flex p-1 min-w-200 overflow-auto">
<div class="w-80 bg-gray-50 h-full overflow-y-auto p-1">
<div class="api-root flex p-2 min-w-200 overflow-auto">
<div class="api-sidebar w-80 h-full overflow-y-auto">
<SiderMenu
v-model:active-menu-key="activeMenuKey"
v-model:schemaType="schemaType"
:dataSource="dataSource"
@addComp="updateData"
@delComp="handleDelComp" />
</div>
<div class="flex flex-col flex-1 min-w-200 py-2 pl-2 h-full overflow-auto">
<div class="flex flex-col flex-1 min-w-200 h-full overflow-auto api-content">
<div> <slot name="docTitle"></slot> </div>
<div class="flex justify-between pb-3">
<div class="flex space-x-2 items-center">
<div class="flex justify-between items-center pb-4 px-4 pt-3 bg-primary border-b">
<div class="flex space-x-3 items-center">
<Upload
:customRequest="handleUploadFile"
accept=".json,.yaml"
:showUploadList="false">
<Button type="primary" size="small">{{useLocal(language)('import')}}</Button>
</Upload>
<Button size="small" @click="handleDownload">{{ useLocal(language)('export')}}</Button>
<Button size="small" @click="toggleTheme" class="theme-toggle-btn">
<span v-if="currentTheme === 'light'">🌙</span>
<span v-else>☀️</span>
</Button>
</div>
<RadioGroup v-model:value="viewMode" >
<RadioGroup v-model:value="viewMode" size="small">
<RadioButton value="form">{{useLocal(language)('form')}}</RadioButton>
<RadioButton value="code">{{useLocal(language)('code')}}</RadioButton>
<RadioButton v-if="showPreview" value="preview">{{useLocal(language)('preview')}}</RadioButton>
</RadioGroup>
</div>
<Tabs v-model:activeKey="viewMode" destroyInactiveTabPane class="flex-1 view-type-tab">
<TabPane key="form" class="overflow-auto pr-3" >
<DocInfo v-if="activeMenuKey === 'info'" :dataSource="dataSource" :viewMode="viewMode" class="mt-4" />
<ExternalDoc v-else-if="activeMenuKey === 'externalDocs'" :dataSource="dataSource" :viewMode="viewMode" class="mt-4" />
<Server v-else-if="activeMenuKey === 'servers'" :dataSource="dataSource" :viewMode="viewMode" class="mt-4" />
<Tag v-else-if="activeMenuKey === 'tags'" :dataSource="dataSource" :viewMode="viewMode" class="mt-4" />
<Extensions v-else-if="activeMenuKey === 'extensions'" :dataSource="dataSource" :viewMode="viewMode" class="mt-4" />
<Security v-else-if="activeMenuKey === 'security'" :dataSource="dataSource" :viewMode="viewMode" class="mt-4" @save="saveSecurity" />
<TabPane key="form" class="overflow-auto px-4 py-3" >
<DocInfo v-if="activeMenuKey === 'info'" :dataSource="dataSource" :viewMode="viewMode" class="api-form-container" />
<ExternalDoc v-else-if="activeMenuKey === 'externalDocs'" :dataSource="dataSource" :viewMode="viewMode" class="api-form-container" />
<Server v-else-if="activeMenuKey === 'servers'" :dataSource="dataSource" :viewMode="viewMode" class="api-form-container" />
<Tag v-else-if="activeMenuKey === 'tags'" :dataSource="dataSource" :viewMode="viewMode" class="api-form-container" />
<Extensions v-else-if="activeMenuKey === 'extensions'" :dataSource="dataSource" :viewMode="viewMode" class="api-form-container" />
<Security v-else-if="activeMenuKey === 'security'" :dataSource="dataSource" :viewMode="viewMode" class="api-form-container" @save="saveSecurity" />
<ApiModel v-else-if="selectedApi" :dataSource="selectedApi" :openapiDoc="dataSource"/>
<PathInfo :key="apiEndpoint" v-else-if="selectPath" :dataSource="selectPath" :path="apiEndpoint" />
<Comp v-else class="mt-4" :dataSource="dataSource" :schemaType="schemaType" :schemaName="activeMenuKey" @del="handleDelComp" />
<Comp v-else class="api-form-container" :dataSource="dataSource" :schemaType="schemaType" :schemaName="activeMenuKey" @del="handleDelComp" />
</TabPane>
<TabPane key="code">
<CodeView v-if="!schemaType && selectApiObj" class="h-full" :selectStr="selectApiObj" :startKey="selectApiObj ? (apiEndpoint || 'paths') : undefined" :dataSource="dataSource" />
Expand All @@ -304,7 +317,7 @@ provide('language', language);
<CodeView v-else-if="!schemaType" class="h-full" :selectStr="{[activeMenuKey]: dataSource[activeMenuKey]}" :startKey="undefined" :dataSource="dataSource" />
<CodeView v-else class="h-full" :selectStr="{[activeMenuKey]: dataSource.components?.[schemaType]?.[activeMenuKey]}" startKey="components" :dataSource="dataSource" />
</TabPane>
<TabPane v-if="showPreview" key="preview" class="overflow-auto pr-3 space-y-4">
<TabPane v-if="showPreview" key="preview" class="overflow-auto px-4 py-3 space-y-4">
<DocInfoPreview v-if="activeMenuKey === 'info'" />
<ExternalDocPreview v-else-if="activeMenuKey === 'externalDocs'" />
<ServerPreview v-else-if="activeMenuKey === 'servers'" />
Expand Down Expand Up @@ -339,11 +352,39 @@ provide('language', language);
font-size: 13px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #525A65;
color: var(--text-secondary);
background-color: var(--bg-secondary);
}

.api-sidebar {
background-color: var(--bg-sidebar);
border-right: 1px solid var(--border-primary);
padding: var(--spacing-lg);
transition: all var(--transition-base);
}

.api-content {
background-color: var(--bg-primary);
padding-left: var(--spacing-lg);
}

.bg-primary {
background-color: var(--bg-primary);
}

.border-b {
border-bottom: 1px solid var(--border-primary);
}

.theme-toggle-btn {
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
}

.ant-input.ant-input-borderless:hover {
@apply bg-gray-200;
background-color: var(--bg-hover);
}

.api-root .ant-tabs.view-type-tab>.ant-tabs-nav {
Expand Down
2 changes: 1 addition & 1 deletion core/component/apisModel/requestBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button, TabPane, Tabs, Select } from 'ant-design-vue';
import { NotificationOutlined } from '@ant-design/icons-vue';
import { CONTENT_TYPE } from '../basic/utils';
import BodyContentTypeTab from '../basic/bodyContentTypeTab.vue';
import Dropdown from '@/common/dropdown/index.vue';
import Dropdown from '@/common/Dropdown/index.vue';

const descRef = ref();
const EasyMd = defineAsyncComponent(() => import('@/common/easyMd/index.vue'));
Expand Down
2 changes: 1 addition & 1 deletion core/component/apisModel/responses.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { onMounted, ref, watch, Ref } from 'vue';
import { Button, TabPane, Tabs, Input } from 'ant-design-vue';
// import ResponseSchema from '../basic/responseSchema.vue';
import {httpStatus} from './PropTypes';
import Dropdown from '@/common/dropdown/index.vue';
import Dropdown from '@/common/Dropdown/index.vue';
import responseTabPane from './responseTabPane.vue';

interface Props {
Expand Down
4 changes: 2 additions & 2 deletions core/component/basic/attrItemList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
</template>
<script>
import { defineComponent } from 'vue';
import IconRequired from '@/common/icons/IconRequired/index.vue';
import Arrow from '@/common/arrow/index.vue';
import IconRequired from '@/common/Icons/IconRequired/index.vue';
import Arrow from '@/common/Arrow/index.vue';
import { Button, Popover } from 'ant-design-vue';
import { EditOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue';

Expand Down
4 changes: 2 additions & 2 deletions core/component/basic/attrItemListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
</template>
<script>
import { defineComponent, ref, inject, computed } from 'vue';
import IconRequired from '@/common/icons/IconRequired/index.vue';
import Arrow from '@/common/arrow/index.vue';
import IconRequired from '@/common/Icons/IconRequired/index.vue';
import Arrow from '@/common/Arrow/index.vue';
import { Button, Popover } from 'ant-design-vue';
import { EditOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue';

Expand Down
2 changes: 1 addition & 1 deletion core/component/basic/exampleBasic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ defineExpose({
@blur="autoSave" />
</template>
<div v-else class="text-center">
<img class="inline-block" src="../../Icons/noData.svg" />
<img class="inline-block" src="../../icons/noData.svg" />
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion core/component/basic/responseSchema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CONTENT_TYPE } from './utils';
// import NoDataSvg from '@/icons/noData.svg';

import BodyContentTypeTab from './bodyContentTypeTab.vue';
import Dropdown from '@/common/dropdown/index.vue';
import Dropdown from '@/common/Dropdown/index.vue';
import ParameterBasic from './parameterBasic.vue';
import NoData from '@/common/noData/index.vue';

Expand Down
2 changes: 1 addition & 1 deletion core/component/requestBody/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { ref, watch, onMounted, nextTick, Ref, inject, onBeforeUnmount, defineAsyncComponent } from 'vue';
import { Button, TabPane, Tabs } from 'ant-design-vue';
import { CONTENT_TYPE } from '../basic/utils';
import Dropdown from '@/common/dropdown/index.vue';
import Dropdown from '@/common/Dropdown/index.vue';

import BodyContentTypeTab from '../basic/bodyContentTypeTab.vue';

Expand Down
2 changes: 1 addition & 1 deletion core/component/response/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CONTENT_TYPE } from '../basic/utils';

import BodyContentTypeTab from '../basic/bodyContentTypeTab.vue';
import parameterBasic from '../basic/parameterBasic.vue';
import Dropdown from '@/common/dropdown/index.vue';
import Dropdown from '@/common/Dropdown/index.vue';
import NoData from '@/common/noData/index.vue';

const descRef = ref();
Expand Down
28 changes: 14 additions & 14 deletions core/docInfo/formView/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,27 +73,27 @@ const licenseTypeOpt = computed(() =>[
}
]);

const getData = () => {
const data = JSON.parse(JSON.stringify(formState.value));
const getFormData = () => {
const formData = JSON.parse(JSON.stringify(formState.value));
const description = descRef.value.getValue();
const {contact, license} = data;
data.description = description;
const {contact, license} = formData;
formData.description = description;
if (contact && !contact.name && !contact.url && !contact.email ) {
delete data.contact;
delete formData.contact;
}

if (!license.name) {
delete data.contact;
delete formData.license;
} else if (licenseType.value === 'identifier') {
delete data.license.url;
delete formData.license.url;
} else if (licenseType.value === 'url') {
delete data.license.identifier;
delete formData.license.identifier;
}
return data;
return formData;
};

onMounted(() => {
getAppFunc({name: 'updateData', func: saveData});
getAppFunc({name: 'updateData', func: saveFormData});
watch(() => props.dataSource?.info, () => {
easyMdKey.value += 1;
formState.value = props.dataSource?.info || {};
Expand All @@ -116,17 +116,17 @@ onMounted(() => {
});
});

const saveData = () => {
dataSource.value.info = getData();
const saveFormData = () => {
dataSource.value.info = getFormData();
}

onBeforeUnmount(() => {
getAppFunc({name: 'updateData', func: null});
saveData();
saveFormData();
});

defineExpose({
getData: getData
getData: getFormData
});

</script>
Expand Down
2 changes: 1 addition & 1 deletion core/extensions/formView/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ defineExpose({
@blur="changeSelectExtensionValue($event, selectedExtension.name)" />
</template>
<div v-else class="text-center">
<img class="inline-block" src="../../Icons/noData.svg" />
<img class="inline-block" src="../../icons/noData.svg" />
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion core/security/preView/index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { ref, computed, inject } from 'vue';
import { Tag } from 'ant-design-vue';
import Arrow from '@/common/arrow/index.vue';
import Arrow from '@/common/Arrow/index.vue';

const dataSource = inject('dataSource', ref());

Expand Down
2 changes: 1 addition & 1 deletion core/server/preView/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { ref, inject, computed } from 'vue';
import Arrow from '@/common/arrow/index.vue';
import Arrow from '@/common/Arrow/index.vue';

const dataSource = inject('dataSource', ref());

Expand Down
16 changes: 7 additions & 9 deletions core/siderMenu/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { computed, onMounted, ref, watch, inject } from 'vue';
// import { useI18n } from 'vue-i18n';
import { debounce } from 'throttle-debounce';
import { Input, Select, Dropdown, Menu, MenuItem, Modal, notification, Button } from 'ant-design-vue';
import Arrow from '@/common/arrow/index.vue';
import Arrow from '@/common/Arrow/index.vue';
import { methodOpt, getPathParameterByPath } from './config';

import docInfoSvg from '../Icons/docInfo.svg';
import outDocSvg from '../Icons/outDoc.svg';
import serverSvg from '../Icons/server.svg';
import anquanSvg from '../Icons/anquan.svg';
import tagSvg from '../Icons/tag.svg';
import MenuDropdown from '@/common/dropdown/index.vue';
import docInfoSvg from '../icons/docInfo.svg';
import outDocSvg from '../icons/outDoc.svg';
import serverSvg from '../icons/server.svg';
import anquanSvg from '../icons/anquan.svg';
import tagSvg from '../icons/tag.svg';
import MenuDropdown from '@/common/Dropdown/index.vue';


interface Props {
Expand Down Expand Up @@ -95,10 +95,8 @@ const handlekeywordsChange = debounce(600, () => {
Object.keys(apiPaths.value).forEach(path => {
if (path.includes(searchKeywords.value)) {
compExpandMap.value['apis'] = true;
console.log(path);
}
Object.keys(apiPaths.value[path]).forEach(method => {
console.log(path);
if (apiPaths.value[path][method].summary.includes(searchKeywords.value)) {
compExpandMap.value[path] = true;
compExpandMap.value['apis'] = true;
Expand Down
Loading