mirror of
https://gitee.com/eolink_admin/postcat.git
synced 2024-11-30 02:37:57 +08:00
Merge branch 'main' into web
This commit is contained in:
commit
23a08811ab
@ -28,16 +28,16 @@ export class AppComponent {
|
||||
console.log('isSuccess', isSuccess);
|
||||
if (!isSuccess) {
|
||||
const timer = setTimeout(() => {
|
||||
this.remoteService.switchDataSource();
|
||||
this.remoteService.switchDataSource('local');
|
||||
}, 5000);
|
||||
this.modal.info({
|
||||
nzContent: $localize `:{can not connect}:Unable to connect to remote data sources, please check and reconnect. In order not to affect use, the app will help you jump to local`,
|
||||
nzContent: $localize`:{can not connect}:Unable to connect to remote data sources, please check and reconnect. In order not to affect use, the app will help you jump to local`,
|
||||
nzFooter: null,
|
||||
nzCentered: true,
|
||||
nzClosable: false,
|
||||
nzOnOk: () => {
|
||||
clearTimeout(timer);
|
||||
timer && this.remoteService.switchDataSource();
|
||||
timer && this.remoteService.switchDataSource('local');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -15,9 +15,14 @@ export class ApiTabService {
|
||||
return Object.values(this.BASIC_TBAS).find((val) => this.router.url.includes(val.pathname))?.type || 'preview';
|
||||
}
|
||||
private changeContent$: Subject<any> = new Subject();
|
||||
BASIC_TBAS = {
|
||||
test: { pathname: '/home/api/test', type: 'edit', title: $localize`New Request`, extends: { method: 'POST' } },
|
||||
edit: { pathname: '/home/api/edit', type: 'edit', title: $localize`New API` },
|
||||
BASIC_TBAS: { [key: string]: Partial<TabItem> } = {
|
||||
test: {
|
||||
pathname: '/home/api/test',
|
||||
type: 'edit',
|
||||
title: $localize`New Request`,
|
||||
extends: { method: 'POST' },
|
||||
},
|
||||
edit: { pathname: '/home/api/edit', isFixed: true, type: 'edit', title: $localize`New API` },
|
||||
detail: { pathname: '/home/api/detail', type: 'preview', title: $localize`Preview` },
|
||||
overview: { pathname: '/home/api/overview', type: 'preview', title: $localize`:@@API Index:Index`, icon: 'home' },
|
||||
mock: { pathname: '/home/api/mock', type: 'preview', title: 'Mock' },
|
||||
@ -115,7 +120,7 @@ export class ApiTabService {
|
||||
}
|
||||
//?Why should use getCurrentTab()?
|
||||
//Because maybe current tab has't finish init
|
||||
const currentTab = this.apiTabComponent.getTabByUrl(url);
|
||||
const currentTab = this.apiTabComponent.getExistTabByUrl(url);
|
||||
const contentID = this.getContentID(url);
|
||||
//Get tab cache
|
||||
this.componentRef.model = currentTab?.content?.[contentID] || null;
|
||||
@ -124,9 +129,11 @@ export class ApiTabService {
|
||||
}
|
||||
updateTab(currentTab, inData) {
|
||||
const model = inData.model;
|
||||
const contentID = this.getContentID(currentTab.pathname);
|
||||
|
||||
//Set tabItem
|
||||
const replaceTab: Partial<TabItem> = {
|
||||
hasChanged: currentTab.hasChanged,
|
||||
isLoading: false,
|
||||
extends: {},
|
||||
};
|
||||
@ -148,7 +155,6 @@ export class ApiTabService {
|
||||
}
|
||||
//Only hasChanged edit page storage data
|
||||
if (currentTab.type === 'edit') {
|
||||
const contentID = this.getContentID(currentTab.pathname);
|
||||
//Set hasChange
|
||||
if (!this.componentRef?.isFormChange) {
|
||||
throw new Error(
|
||||
@ -157,7 +163,10 @@ export class ApiTabService {
|
||||
}
|
||||
switch (inData.when) {
|
||||
case 'editing': {
|
||||
replaceTab.hasChanged = this.componentRef.isFormChange();
|
||||
// Saved APIs do not need to verify changes
|
||||
if (!currentTab.params.uuid || currentTab.params.uuid.includes('history')) {
|
||||
replaceTab.hasChanged = this.componentRef.isFormChange();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'saved': {
|
||||
@ -170,15 +179,6 @@ export class ApiTabService {
|
||||
replaceTab.hasChanged =
|
||||
currentTab.extends?.hasChanged?.[contentID === 'edit' ? 'test' : 'edit'] || replaceTab.hasChanged;
|
||||
|
||||
//Set isFixed
|
||||
if (replaceTab.hasChanged) {
|
||||
replaceTab.isFixed = true;
|
||||
}
|
||||
//Has tested set fixed
|
||||
if (currentTab.pathname === '/home/api/test' && model.testStartTime !== undefined) {
|
||||
replaceTab.isFixed = true;
|
||||
}
|
||||
|
||||
// Set storage
|
||||
//Set baseContent
|
||||
if (['init', 'saved'].includes(inData.when)) {
|
||||
@ -190,6 +190,15 @@ export class ApiTabService {
|
||||
replaceTab.content = inData.when === 'saved' ? {} : currentTab.content || {};
|
||||
replaceTab.content[contentID] = model && !isEmptyObj(model) ? model : null;
|
||||
}
|
||||
|
||||
//Set isFixed
|
||||
if (replaceTab.hasChanged) {
|
||||
replaceTab.isFixed = true;
|
||||
}
|
||||
//Has tested/exsix api set fixed
|
||||
if (currentTab.pathname === '/home/api/test' && (model.testStartTime !== undefined || currentTab.params.uuid)) {
|
||||
replaceTab.isFixed = true;
|
||||
}
|
||||
}
|
||||
// console.log('updatePartialTab',inData.url,currentTab, replaceTab);
|
||||
this.apiTabComponent.updatePartialTab(inData.url, replaceTab);
|
||||
@ -205,7 +214,7 @@ export class ApiTabService {
|
||||
console.warn(`EO_WARNING:apiTabComponent hasn't init yet!`);
|
||||
return;
|
||||
}
|
||||
const currentTab = this.apiTabComponent.getTabByUrl(inData.url);
|
||||
const currentTab = this.apiTabComponent.getExistTabByUrl(inData.url);
|
||||
if (!currentTab) {
|
||||
console.warn(`has't find the tab fit child component ,url:${inData.url}`);
|
||||
return;
|
||||
|
@ -139,22 +139,26 @@ export class ApiTabOperateService {
|
||||
/**
|
||||
* Get exist tab index
|
||||
*
|
||||
* @param type sameTab means has same {params.uuid}
|
||||
* @param type sameTab means has same pageID and same {params.uuid}
|
||||
* @param tab
|
||||
* @returns
|
||||
*/
|
||||
getSameContentTabIndex(tab: TabItem): number {
|
||||
let result = -1;
|
||||
const sameTabIDTab = this.tabStorage.tabsByID.get(tab.uuid);
|
||||
if (sameTabIDTab && !sameTabIDTab.params.uuid && sameTabIDTab.pathname === tab.pathname) {
|
||||
return this.tabStorage.tabOrder.findIndex((uuid) => uuid === sameTabIDTab.uuid);
|
||||
getSameContentTab(tab: Partial<TabItem>): TabItem | null {
|
||||
let result = null;
|
||||
if (!tab.params.uuid) {
|
||||
const sameTabIDTab = this.tabStorage.tabsByID.get(tab.uuid);
|
||||
if (sameTabIDTab && sameTabIDTab.pathname === tab.pathname) {
|
||||
return sameTabIDTab;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//Get exist params.uuid content tab,same pathname and uuid match
|
||||
const mapObj = Object.fromEntries(this.tabStorage.tabsByID);
|
||||
for (const key in mapObj) {
|
||||
if (Object.prototype.hasOwnProperty.call(mapObj, key)) {
|
||||
const tabInfo = mapObj[key];
|
||||
if (tabInfo.params.uuid && tabInfo.params.uuid === tab.params.uuid && tabInfo.pathname === tab.pathname) {
|
||||
result = this.tabStorage.tabOrder.findIndex((uuid) => uuid === tabInfo.uuid);
|
||||
if (tabInfo.params.uuid === tab.params.uuid && tabInfo.pathname === tab.pathname) {
|
||||
result = tabInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -167,10 +171,9 @@ export class ApiTabOperateService {
|
||||
* @param url
|
||||
* @returns tabInfo
|
||||
*/
|
||||
getBaiscTabFromUrl(url): TabItem {
|
||||
getTabInfoFromUrl(url): { uuid: number; pathname: string; params: any } {
|
||||
const urlArr = url.split('?');
|
||||
const params: any = {};
|
||||
const timestamp = Date.now();
|
||||
const basicTab = Object.values(this.BASIC_TABS).find((val) => urlArr[0].includes(val.pathname));
|
||||
if (!basicTab) {
|
||||
throw new Error(`EO_ERROR: Please check this router has added in BASIC_TABS,current route:${url}`);
|
||||
@ -183,19 +186,30 @@ export class ApiTabOperateService {
|
||||
}
|
||||
params[key] = value;
|
||||
});
|
||||
params.pageID = params.pageID || timestamp;
|
||||
const result = {
|
||||
//If data need load from ajax/indexeddb,add loading
|
||||
uuid: params.pageID,
|
||||
isLoading: params.uuid ? true : false,
|
||||
pathname: basicTab.pathname,
|
||||
params,
|
||||
};
|
||||
['title', 'icon', 'type', 'extends'].forEach((keyName) => {
|
||||
result[keyName] = basicTab[keyName];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Get basic tab info from url
|
||||
*
|
||||
* @param url
|
||||
* @returns tabInfo
|
||||
*/
|
||||
getBaiscTabFromUrl(url): TabItem {
|
||||
const result = this.getTabInfoFromUrl(url);
|
||||
const basicTab = Object.values(this.BASIC_TABS).find((val) => result.pathname === val.pathname);
|
||||
if (!basicTab) {
|
||||
throw new Error(`EO_ERROR: Please check this router has added in BASIC_TABS,current route:${url}`);
|
||||
}
|
||||
result.params.pageID = result.params.pageID || Date.now();
|
||||
Object.assign(result, basicTab);
|
||||
return result as TabItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operate tab after router change,router triggle tab change
|
||||
* Such as new tab,pick tab,close tab...
|
||||
@ -203,89 +217,68 @@ export class ApiTabOperateService {
|
||||
* @param res.url location.pathname+location.search
|
||||
*/
|
||||
operateTabAfterRouteChange(res: { url: string }) {
|
||||
const tmpTabItem = this.getBaiscTabFromUrl(res.url);
|
||||
const sameContentIndex = this.getSameContentTabIndex(tmpTabItem);
|
||||
const existTab = this.getTabByIndex(sameContentIndex);
|
||||
console.log('operateTabAfterRouteChange', existTab, tmpTabItem);
|
||||
//If page lack pageID
|
||||
//Jump to exist tab item to keep same pageID and so on
|
||||
if (!res.url.includes('pageID')) {
|
||||
const pureTab = this.getTabInfoFromUrl(res.url);
|
||||
const nextTab = this.getBaiscTabFromUrl(res.url);
|
||||
const existTab = this.getSameContentTab(pureTab);
|
||||
//!Every tab must has pageID
|
||||
//If lack pageID,Jump to exist tab item to keep same pageID and so on
|
||||
if (!pureTab.uuid) {
|
||||
if (existTab) {
|
||||
tmpTabItem.uuid = tmpTabItem.params.pageID = existTab.uuid;
|
||||
pureTab.uuid = pureTab.params.pageID = existTab.uuid;
|
||||
}
|
||||
this.navigateTabRoute(tmpTabItem);
|
||||
this.navigateTabRoute(nextTab);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.tabStorage.tabOrder.length === 0) {
|
||||
this.tabStorage.addTab(tmpTabItem);
|
||||
this.tabStorage.addTab(nextTab);
|
||||
this.updateChildView();
|
||||
return;
|
||||
}
|
||||
|
||||
//same tab content,selected it
|
||||
if (existTab) {
|
||||
this.selectedIndex = sameContentIndex;
|
||||
this.selectedIndex = this.tabStorage.tabOrder.findIndex((uuid) => uuid === existTab.uuid);
|
||||
this.updateChildView();
|
||||
return;
|
||||
}
|
||||
//If has same content tab (same {params.uuid}),replace it and merge data
|
||||
const mapObj = Object.fromEntries(this.tabStorage.tabsByID);
|
||||
for (const key in mapObj) {
|
||||
if (Object.prototype.hasOwnProperty.call(mapObj, key)) {
|
||||
const tab = mapObj[key];
|
||||
if (tab.params.uuid && tab.params.uuid === tmpTabItem.params.uuid) {
|
||||
const mergeTab = this.preventBlankTab(tab, tmpTabItem);
|
||||
mergeTab.content = tab.content;
|
||||
mergeTab.baseContent = tab.baseContent;
|
||||
mergeTab.extends = Object.assign(mergeTab.extends || {}, tab.extends);
|
||||
this.selectedIndex = this.tabStorage.tabOrder.findIndex((uuid) => uuid === tab.uuid);
|
||||
this.tabStorage.updateTab(this.selectedIndex, mergeTab);
|
||||
this.updateChildView();
|
||||
return;
|
||||
}
|
||||
//!Same params.uuid can only open one Tab
|
||||
//If has same subTab (same {params.uuid}), merge data and replace it
|
||||
if (nextTab.params?.uuid) {
|
||||
const hasFind = this.jumpToSameSubTab(nextTab);
|
||||
if (hasFind) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
//If has same tab (same uuid),replace it
|
||||
const samePageID = this.tabStorage.tabsByID.has(tmpTabItem.uuid);
|
||||
if (samePageID) {
|
||||
this.selectedIndex = this.tabStorage.tabOrder.findIndex((uuid) => uuid === tmpTabItem.uuid);
|
||||
this.tabStorage.updateTab(this.selectedIndex, tmpTabItem);
|
||||
//Determine whether to replace the current Tab
|
||||
let canbeReplaceTab = null;
|
||||
if (this.tabStorage.tabsByID.has(pureTab.uuid)) {
|
||||
//If the same tab exists, directly replace
|
||||
canbeReplaceTab = nextTab;
|
||||
} else {
|
||||
canbeReplaceTab = this.findTabCanbeReplace();
|
||||
}
|
||||
|
||||
//Find other tab to be replace
|
||||
const currentTab = this.getCurrentTab();
|
||||
//* Replace current tab first
|
||||
const canbeReplaceTab =
|
||||
currentTab && this.canbeReplace(currentTab)
|
||||
? currentTab
|
||||
: Object.values(mapObj).find((val) => this.canbeReplace(val));
|
||||
if (canbeReplaceTab) {
|
||||
this.selectedIndex = this.tabStorage.tabOrder.findIndex((uuid) => uuid === canbeReplaceTab.uuid);
|
||||
this.tabStorage.updateTab(this.selectedIndex, tmpTabItem);
|
||||
this.tabStorage.updateTab(this.selectedIndex, nextTab);
|
||||
this.updateChildView();
|
||||
return;
|
||||
}
|
||||
|
||||
//No one can be replace,add tab
|
||||
this.tabStorage.addTab(tmpTabItem);
|
||||
this.tabStorage.addTab(nextTab);
|
||||
this.selectedIndex = this.tabStorage.tabOrder.length - 1;
|
||||
this.updateChildView();
|
||||
}
|
||||
//*Prevent toggling splash screen with empty tab title
|
||||
preventBlankTab(origin, target) {
|
||||
private preventBlankTab(origin, target) {
|
||||
const result = target;
|
||||
/**
|
||||
* Keyname effect show tab
|
||||
*/
|
||||
['title', 'hasChanged', 'isFixed', 'isLoading'].forEach((keyName) => {
|
||||
//Dont't replace is loading tab content
|
||||
if (result[keyName] && !result.isLoading) {
|
||||
return;
|
||||
}
|
||||
['title', 'hasChanged', 'isLoading'].forEach((keyName) => {
|
||||
result[keyName] = origin[keyName];
|
||||
});
|
||||
result.isLoading = false;
|
||||
return result;
|
||||
}
|
||||
canbeReplace(tabItem: TabItem) {
|
||||
@ -304,15 +297,46 @@ export class ApiTabOperateService {
|
||||
getCurrentTab() {
|
||||
return this.getTabByIndex(this.selectedIndex);
|
||||
}
|
||||
private getUrlByTab(tab: TabItem) {
|
||||
return (
|
||||
tab.pathname +
|
||||
'?' +
|
||||
Object.keys(tab.params)
|
||||
.sort()
|
||||
.map((keyName) => `${keyName}=${tab.params[keyName]}`)
|
||||
.join('&')
|
||||
);
|
||||
/**
|
||||
* Same sub means tab has same {params.uuid}
|
||||
*
|
||||
* @param inTab
|
||||
* @returns hasFind
|
||||
*/
|
||||
private jumpToSameSubTab(inTab): boolean {
|
||||
const mapObj = Object.fromEntries(this.tabStorage.tabsByID);
|
||||
for (const key in mapObj) {
|
||||
if (Object.prototype.hasOwnProperty.call(mapObj, key)) {
|
||||
const tab = mapObj[key];
|
||||
if (tab.params.uuid && tab.params.uuid === inTab.params.uuid) {
|
||||
const mergeTab = this.preventBlankTab(tab, inTab);
|
||||
mergeTab.content = tab.content;
|
||||
mergeTab.baseContent = tab.baseContent;
|
||||
mergeTab.extends = Object.assign(mergeTab.extends || {}, tab.extends);
|
||||
this.selectedIndex = this.tabStorage.tabOrder.findIndex((uuid) => uuid === tab.uuid);
|
||||
this.tabStorage.updateTab(this.selectedIndex, mergeTab);
|
||||
this.updateChildView();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find can be replace tab
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
private findTabCanbeReplace(): TabItem {
|
||||
const mapObj = Object.fromEntries(this.tabStorage.tabsByID);
|
||||
const currentTab = this.getCurrentTab();
|
||||
//* Replace current tab first
|
||||
const result =
|
||||
currentTab && this.canbeReplace(currentTab)
|
||||
? currentTab
|
||||
: Object.values(mapObj).find((val) => this.canbeReplace(val));
|
||||
return result;
|
||||
}
|
||||
private updateChildView() {
|
||||
this.messageService.send({ type: 'tabContentInit', data: {} });
|
||||
|
@ -1,4 +1,3 @@
|
||||
<!-- {{getConsoleTabs()|json}} -->
|
||||
<nz-tabset
|
||||
[(nzSelectedIndex)]="tabOperate.selectedIndex"
|
||||
nzType="editable-card"
|
||||
@ -24,7 +23,7 @@
|
||||
>
|
||||
<span class="text_omit tab_text"> {{ tabStorage.tabsByID.get(uuid).title }}</span>
|
||||
<!-- Close/HasEdit -->
|
||||
<div class="tab-item-button-group">
|
||||
<div class="tab-item-button-group flex items-center">
|
||||
<span class="tab-has-edit-icon eo-tab-theme-icon" *ngIf="tabStorage.tabsByID.get(uuid).hasChanged"></span>
|
||||
<button
|
||||
aria-label="Close tab"
|
||||
|
@ -80,12 +80,19 @@
|
||||
}
|
||||
.tab-item-button-group {
|
||||
position: absolute;
|
||||
background: var(--MAIN_BG);
|
||||
padding-right: 10px;
|
||||
right: 0px;
|
||||
margin-right: 10px;
|
||||
right: 0;
|
||||
}
|
||||
.ant-tabs-tab-remove {
|
||||
padding: 3px;
|
||||
margin-left: 3px;
|
||||
border-radius: 50%;
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
.fixed-tab-item-container{
|
||||
.fixed-tab-item-container {
|
||||
font-style: initial;
|
||||
}
|
||||
}
|
||||
|
@ -116,13 +116,12 @@ export class ApiTabComponent implements OnInit, OnDestroy {
|
||||
* @param url
|
||||
* @returns
|
||||
*/
|
||||
getTabByUrl(url: string): TabItem | null {
|
||||
const tabItem = this.tabOperate.getBaiscTabFromUrl(url);
|
||||
const existTabIndex = this.tabOperate.getSameContentTabIndex(tabItem);
|
||||
if (existTabIndex === -1) {
|
||||
getExistTabByUrl(url: string): TabItem | null {
|
||||
const existTab = this.tabOperate.getSameContentTab(this.tabOperate.getTabInfoFromUrl(url));
|
||||
if (!existTab) {
|
||||
return null;
|
||||
}
|
||||
return this.tabStorage.tabsByID.get(this.tabStorage.tabOrder[existTabIndex]);
|
||||
return existTab;
|
||||
}
|
||||
getCurrentTab() {
|
||||
return this.tabOperate.getCurrentTab();
|
||||
@ -138,20 +137,20 @@ export class ApiTabComponent implements OnInit, OnDestroy {
|
||||
* @returns
|
||||
*/
|
||||
updatePartialTab(url: string, tabItem: Partial<TabItem>) {
|
||||
const originTab = this.getTabByUrl(url);
|
||||
if (!originTab) {
|
||||
const existTab = this.getExistTabByUrl(url);
|
||||
if (!existTab) {
|
||||
console.error(`EO_ERROR:updatePartialTab fail,can't find exist tab to fixed url:${url}`);
|
||||
return;
|
||||
}
|
||||
const index = this.tabStorage.tabOrder.findIndex((uuid) => uuid === originTab.uuid);
|
||||
const index = this.tabStorage.tabOrder.findIndex((uuid) => uuid === existTab.uuid);
|
||||
this.tabStorage.updateTab(
|
||||
index,
|
||||
Object.assign({}, originTab, tabItem, {
|
||||
extends: Object.assign({}, originTab.extends, tabItem.extends),
|
||||
Object.assign({}, existTab, tabItem, {
|
||||
extends: Object.assign({}, existTab.extends, tabItem.extends),
|
||||
})
|
||||
);
|
||||
//! Prevent rendering delay
|
||||
this.cdRef.detectChanges();
|
||||
// this.cdRef.detectChanges();
|
||||
}
|
||||
/**
|
||||
* Cache tab header/tabs content for restore when page close or component destroy
|
||||
|
@ -242,9 +242,9 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
isFormChange(): boolean {
|
||||
//Has exist api can't save
|
||||
//TODO If has test case,test data will be saved to test case
|
||||
if (this.model.request.uuid) {
|
||||
return false;
|
||||
}
|
||||
// if (this.model.request.uuid) {
|
||||
// return false;
|
||||
// }
|
||||
if (!this.initialModel.request || !this.model.request) {
|
||||
return false;
|
||||
}
|
||||
|
@ -9,10 +9,8 @@
|
||||
</div>
|
||||
<section class="h-full p-4 max-w-[80vw] mx-auto">
|
||||
<div class="flex">
|
||||
<i
|
||||
class="block w-24 h-24 mr-8 bg-center bg-no-repeat bg-cover border rounded-lg bd_all"
|
||||
[ngStyle]="{ 'background-image': 'url(' + (extensionDetail?.logo || '') + ')' }"
|
||||
></i>
|
||||
<i class="block w-24 h-24 mr-8 bg-center bg-no-repeat bg-cover border rounded-lg bd_all"
|
||||
[ngStyle]="{ 'background-image': 'url(' + (extensionDetail?.logo || '') + ')' }"></i>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex flex-col">
|
||||
<span class="mb-2 text-xl font-bold">{{ extensionDetail?.moduleName }}</span>
|
||||
@ -36,18 +34,13 @@
|
||||
<div class="shrink-0 w-[200px] 2xl:w-[250px] overflow-auto h-full">
|
||||
<h2 class="text-lg font-bold" i18n>Install</h2>
|
||||
<div class="flex items-center mt-[22px]" *ngIf="!extensionDetail?.installed">
|
||||
<button
|
||||
*ngIf="isElectron"
|
||||
nz-button
|
||||
nzType="primary"
|
||||
nzBlock
|
||||
nzSize="large"
|
||||
[nzLoading]="isOperating"
|
||||
(click)="manageExtension('install', extensionDetail?.name)"
|
||||
i18n
|
||||
>
|
||||
<nz-skeleton-element *ngIf="isNotLoaded" nzType="button" nzSize="large" [nzActive]="true" style="width:100%">
|
||||
</nz-skeleton-element>
|
||||
<button *ngIf="isElectron && !isNotLoaded" nz-button nzType="primary" nzBlock nzSize="large"
|
||||
[nzLoading]="isOperating" (click)="manageExtension('install', extensionDetail?.name)" i18n>
|
||||
Install
|
||||
</button>
|
||||
|
||||
<div *ngIf="!isElectron">
|
||||
<button nz-button nzType="primary" nz-dropdown [nzDropdownMenu]="download" class="!w-full" i18n>
|
||||
Download Client
|
||||
@ -65,20 +58,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
*ngIf="extensionDetail?.installed"
|
||||
nz-button
|
||||
nzBlock
|
||||
nzType="primary"
|
||||
nzDanger
|
||||
nzSize="large"
|
||||
[nzLoading]="isOperating"
|
||||
class="mt-[12px]"
|
||||
(click)="manageExtension('uninstall', extensionDetail?.name)"
|
||||
i18n
|
||||
>
|
||||
Uninstall
|
||||
</button>
|
||||
<div *ngIf="extensionDetail?.installed">
|
||||
<nz-skeleton-element *ngIf="isNotLoaded" nzType="button" [nzActive]="true" nzSize="large" style="width:100%">
|
||||
</nz-skeleton-element>
|
||||
<button *ngIf="!isNotLoaded" nz-button nzBlock nzType="primary" nzDanger nzSize="large"
|
||||
[nzLoading]="isOperating" class="mt-[12px]" (click)="manageExtension('uninstall', extensionDetail?.name)"
|
||||
i18n>
|
||||
Uninstall
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h2 class="text-lg font-bold mt-[30px]" i18n>Support</h2>
|
||||
<nz-descriptions [nzColumn]="1" nzTitle="">
|
||||
|
@ -3,6 +3,9 @@
|
||||
.ant-tabs-content-holder {
|
||||
padding-top: 20px;
|
||||
}
|
||||
.ant-skeleton-element .ant-skeleton-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.md-preview {
|
||||
img {
|
||||
@ -13,7 +16,7 @@
|
||||
.markdown-desc {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
||||
.ant-descriptions-row > td {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
@ -22,4 +25,4 @@
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import { LanguageService } from 'eo/workbench/browser/src/app/core/services/lang
|
||||
export class ExtensionDetailComponent implements OnInit {
|
||||
isOperating = false;
|
||||
introLoading = false;
|
||||
isNotLoaded = true;
|
||||
extensionDetail: EoExtensionInfo;
|
||||
resourceInfo = ResourceInfo;
|
||||
get isElectron() {
|
||||
@ -37,6 +38,7 @@ export class ExtensionDetailComponent implements OnInit {
|
||||
if (!this.extensionDetail?.installed) {
|
||||
await this.fetchReadme(this.language.systemLanguage);
|
||||
}
|
||||
this.isNotLoaded = false;
|
||||
this.extensionDetail.introduction ||= $localize`This plugin has no documentation yet.`;
|
||||
}
|
||||
|
||||
|
@ -10,14 +10,7 @@
|
||||
(click)="handleShowModal()">
|
||||
<eo-iconpark-icon name="setting-two"></eo-iconpark-icon>
|
||||
</span>
|
||||
<!-- <span
|
||||
i18n-title
|
||||
class="flex items-center justify-center mx-1 icon"
|
||||
title="{{ dataSourceText }}数据源"
|
||||
(click)="switchDataSource()"
|
||||
>
|
||||
<eo-iconpark-icon [name]="isRemote ? 'link-cloud-sucess' : 'link-cloud-faild'"></eo-iconpark-icon>
|
||||
</span> -->
|
||||
|
||||
<span class="flex items-center justify-center mx-1 icon" nz-dropdown [nzDropdownMenu]="menu">
|
||||
<eo-iconpark-icon name="help"> </eo-iconpark-icon>
|
||||
</span>
|
||||
|
@ -71,7 +71,9 @@ export class NavbarComponent implements OnInit {
|
||||
fetch('https://api.github.com/repos/eolinker/eoapi/releases')
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if(!(data instanceof Array)) {return;}
|
||||
if (!(data instanceof Array)) {
|
||||
return;
|
||||
}
|
||||
[...this.resourceInfo]
|
||||
.sort((a1, a2) => a2.suffix.length - a1.suffix.length)
|
||||
.forEach((item) => {
|
||||
@ -110,13 +112,6 @@ export class NavbarComponent implements OnInit {
|
||||
this.isSettingVisible = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* switch data
|
||||
*/
|
||||
switchDataSource = async () => {
|
||||
this.remoteService.switchDataSource();
|
||||
};
|
||||
|
||||
getModules(): Array<ModuleInfo> {
|
||||
return Array.from(this.modules.values());
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
<eo-navbar></eo-navbar>
|
||||
<div class="page-body"
|
||||
[style.--remote-notification-height]="isShowNotification && electron.isElectron ? '50px' : '0px'">
|
||||
<div *ngIf="isShowNotification && electron.isElectron" class="remote-notification">
|
||||
<div *ngIf="!isRemote && isShowNotification && electron.isElectron" class="remote-notification">
|
||||
<i nz-icon [nzType]="isRemote ? 'cloud' : 'exclamation-circle'" nzTheme="outline" class="text-[13px] mr-[2px]"></i>
|
||||
<span i18n>Current data storage exists {{ dataSourceText }},please switch if you want to collaborate</span>
|
||||
<a class="eo-blod ml-0.5" (click)="switchDataSource()" i18n>{{ isRemote ? 'Remote Server' : 'Localhost' }} Data Storage</a>
|
||||
<a class="eo-blod ml-0.5" (click)="switchDataSource()" i18n>Remote Server Data Storage</a>
|
||||
<i nz-icon nzType="close" nzTheme="outline" class="absolute right-[20px] cursor-pointer"
|
||||
(click)="closeNotification()"></i>
|
||||
</div>
|
||||
|
@ -66,7 +66,7 @@ export class PagesComponent implements OnInit {
|
||||
}
|
||||
|
||||
switchDataSource = () => {
|
||||
this.remoteService.switchDataSource();
|
||||
this.remoteService.switchDataSource('http');
|
||||
};
|
||||
|
||||
updateState = async () => {
|
||||
@ -86,7 +86,7 @@ export class PagesComponent implements OnInit {
|
||||
.subscribe((inArg: Message) => {
|
||||
switch (inArg.type) {
|
||||
case 'onDataSourceChange': {
|
||||
this.rawChange$.next(inArg.type);
|
||||
// this.rawChange$.next(inArg.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ export class DataStorageComponent implements OnInit, OnChanges {
|
||||
...this.validateForm.value,
|
||||
};
|
||||
this.modelChange.emit(this.model);
|
||||
await this.remoteService.switchDataSource();
|
||||
await this.remoteService.switchDataSource(this.model['eoapi-common.dataStorage']);
|
||||
}
|
||||
|
||||
setFormValue(model = {}) {
|
||||
|
@ -149,9 +149,9 @@ export class SettingComponent implements OnInit {
|
||||
break;
|
||||
}
|
||||
case 'onDataSourceChange': {
|
||||
if (inArg.data.showWithSetting) {
|
||||
this.remoteService.refreshComponent();
|
||||
}
|
||||
// if (inArg.data.showWithSetting) {
|
||||
// this.remoteService.refreshComponent();
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -160,17 +160,6 @@ export class SettingComponent implements OnInit {
|
||||
|
||||
hasChild = (_: number, node: FlatNode): boolean => node.expandable;
|
||||
|
||||
/**
|
||||
* switch data source
|
||||
*/
|
||||
switchDataSource() {
|
||||
this.switchDataSourceLoading = true;
|
||||
this.remoteService.switchDataSource().finally(() => {
|
||||
this.switchDataSourceLoading = false;
|
||||
});
|
||||
// this.messageService.send({ type: 'switchDataSource', data: { showWithSetting: true } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the module
|
||||
*
|
||||
@ -183,7 +172,9 @@ export class SettingComponent implements OnInit {
|
||||
}
|
||||
|
||||
handleScroll = debounce((e: Event) => {
|
||||
if (this.isClick) {return;}
|
||||
if (this.isClick) {
|
||||
return;
|
||||
}
|
||||
const target = e.target as HTMLDivElement;
|
||||
const treeNodes = this.dataSource._flattenedData.value;
|
||||
treeNodes.some((node) => {
|
||||
|
@ -22,7 +22,9 @@ export const IS_SHOW_DATA_SOURCE_TIP = 'IS_SHOW_DATA_SOURCE_TIP';
|
||||
export class RemoteService {
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
/** data source type @type { DataSourceType } */
|
||||
dataSourceType: DataSourceType = 'local';
|
||||
get dataSourceType(): DataSourceType {
|
||||
return this.settingService.settings['eoapi-common.dataStorage'] ?? 'local';
|
||||
}
|
||||
get isElectron() {
|
||||
return this.electronService.isElectron;
|
||||
}
|
||||
@ -49,14 +51,12 @@ export class RemoteService {
|
||||
private settingService: SettingService,
|
||||
private router: Router
|
||||
) {
|
||||
this.dataSourceType = this.settingService.settings['eoapi-common.dataStorage'] ?? this.dataSourceType;
|
||||
this.messageService
|
||||
.get()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((inArg: Message) => {
|
||||
switch (inArg.type) {
|
||||
case 'onDataSourceChange': {
|
||||
this.dataSourceType = inArg.data.dataSourceType;
|
||||
if (localStorage.getItem(IS_SHOW_DATA_SOURCE_TIP) === 'true') {
|
||||
this.showMessage();
|
||||
}
|
||||
@ -86,7 +86,7 @@ export class RemoteService {
|
||||
* Test if remote server address is available
|
||||
*/
|
||||
async pingRmoteServerUrl(): Promise<[boolean, any]> {
|
||||
const { url: remoteUrl, token } = window.eo?.getModuleSettings('eoapi-common.remoteServer') || {};
|
||||
const { url: remoteUrl, token } = this.settingService.getConfiguration('eoapi-common.remoteServer') || {};
|
||||
|
||||
if (!remoteUrl) {
|
||||
return [false, remoteUrl];
|
||||
@ -160,12 +160,9 @@ export class RemoteService {
|
||||
/**
|
||||
* switch data
|
||||
*/
|
||||
switchDataSource = async () => {
|
||||
if (this.isRemote) {
|
||||
localStorage.setItem(IS_SHOW_DATA_SOURCE_TIP, 'true');
|
||||
this.switchToLocal();
|
||||
this.refreshComponent();
|
||||
} else {
|
||||
switchDataSource = async (dataSource: DataSourceType) => {
|
||||
const isRemote = dataSource === 'http';
|
||||
if (isRemote) {
|
||||
const [isSuccess] = await this.pingRmoteServerUrl();
|
||||
if (isSuccess) {
|
||||
localStorage.setItem(IS_SHOW_DATA_SOURCE_TIP, 'true');
|
||||
@ -175,6 +172,10 @@ export class RemoteService {
|
||||
this.message.create('error', $localize`Remote data source not available`);
|
||||
localStorage.setItem(IS_SHOW_DATA_SOURCE_TIP, 'false');
|
||||
}
|
||||
} else {
|
||||
localStorage.setItem(IS_SHOW_DATA_SOURCE_TIP, 'true');
|
||||
this.switchToLocal();
|
||||
this.refreshComponent();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,9 @@ export const IS_SHOW_REMOTE_SERVER_NOTIFICATION = 'IS_SHOW_REMOTE_SERVER_NOTIFIC
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class StorageService {
|
||||
private instance;
|
||||
dataSourceType: DataSourceType = getSettings()['eoapi-common.dataStorage'] || 'local';
|
||||
get dataSourceType(): DataSourceType {
|
||||
return getSettings()['eoapi-common.dataStorage'] || 'local';
|
||||
}
|
||||
constructor(
|
||||
private injector: Injector,
|
||||
private messageService: MessageService,
|
||||
@ -47,7 +49,7 @@ export class StorageService {
|
||||
callback(handleResult);
|
||||
},
|
||||
(error: any) => {
|
||||
console.log('EOERROR:',action, error);
|
||||
console.log('EOERROR:', action, error);
|
||||
handleResult.status = StorageResStatus.error;
|
||||
callback(handleResult);
|
||||
}
|
||||
@ -73,8 +75,7 @@ export class StorageService {
|
||||
};
|
||||
toggleDataSource = (options: any = {}) => {
|
||||
const { dataSourceType } = options;
|
||||
this.dataSourceType = dataSourceType ?? (this.dataSourceType === 'http' ? 'local' : 'http');
|
||||
this.setStorage(this.dataSourceType, options);
|
||||
this.setStorage(dataSourceType ?? (this.dataSourceType === 'http' ? 'local' : 'http'), options);
|
||||
};
|
||||
setDataStorage(value) {
|
||||
this.settingService.putSettings({
|
||||
|
Loading…
Reference in New Issue
Block a user