Skip to content

Commit

Permalink
feat(platform): add amap route
Browse files Browse the repository at this point in the history
  • Loading branch information
xiejay97 committed Oct 13, 2022
1 parent 7d8ca9f commit 18f1e12
Show file tree
Hide file tree
Showing 30 changed files with 433 additions and 188 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
},
"dependencies": {},
"devDependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@amap/amap-jsapi-types": "^0.0.8",
"@ant-design/icons-svg": "^4.2.1",
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/hooks/src/useForkRef.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isFunction, isObject } from 'lodash';
import { useCallback } from 'react';

function setRef(ref: any, value: any): void {
export function setRef(ref: any, value: any): void {
if (isFunction(ref)) {
ref(value);
} else if (isObject(ref) && 'current' in ref) {
Expand Down
2 changes: 1 addition & 1 deletion packages/platform/src/app/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import AppExceptionRoute from './routes/exception/Exception';
import AppLayout from './routes/layout/Layout';
import AppLoginRoute from './routes/login/Login';

const AppAMapRoute = React.lazy(() => import('./routes/dashboard/AMap'));
const AppAMapRoute = React.lazy(() => import('./routes/dashboard/amap/AMap'));
const AppEChartsRoute = React.lazy(() => import('./routes/dashboard/echarts/ECharts'));

const AppACLRoute = React.lazy(() => import('./routes/test/acl/ACL'));
Expand Down
83 changes: 83 additions & 0 deletions packages/platform/src/app/components/amap/AMap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import AMapLoader from '@amap/amap-jsapi-loader';
import { isNull, isUndefined } from 'lodash';
import React, { useCallback, useRef } from 'react';

import { setRef } from '@react-devui/hooks/useForkRef';
import { getClassName } from '@react-devui/utils';

const CONFIG: {
key?: string;
securityJsCode?: string | null;
version?: string;
} = {
version: '2.0',
};

export interface AppAMapProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
aKey?: string;
aSecurityJsCode?: string | null;
aVersion?: string;
aPlugins?: string[];
aOptions?: AMap.MapOptions;
}

function AMap(props: AppAMapProps, ref: React.ForwardedRef<AMap.Map>): JSX.Element | null {
const {
aKey = CONFIG.key,
aSecurityJsCode = CONFIG.securityJsCode,
aVersion = CONFIG.version,
aPlugins,
aOptions,

...restProps
} = props;

//#region Ref
const elRef = useRef<HTMLDivElement>(null);
//#endregion

const instanceRef = useRef<AMap.Map | null>(null);
const containerRef = useCallback(
(el: HTMLElement | null) => {
instanceRef.current?.destroy();
instanceRef.current = null;
setRef(ref, instanceRef.current);

if (el) {
if (isUndefined(aKey) || isUndefined(aSecurityJsCode) || isUndefined(aVersion)) {
throw new Error('Configs of amap is required!');
}

if (!isNull(aSecurityJsCode)) {
window['_AMapSecurityConfig'] = {
// serviceHost: 'http://1.1.1.1:80/_AMapService',

securityJsCode: aSecurityJsCode,
};
}

AMapLoader.load({
key: aKey,
version: aVersion,
plugins: aPlugins,
})
.then((AMap) => {
instanceRef.current = new AMap.Map(el, aOptions);
setRef(ref, instanceRef.current);
})
.catch((e) => {
console.error(e);
});
}
},
[aKey, aOptions, aPlugins, aSecurityJsCode, aVersion, ref]
);

return (
<div {...restProps} ref={elRef} className={getClassName(restProps.className, 'app-amap')}>
<div ref={containerRef} className="app-amap__container"></div>
</div>
);
}

export const AppAMap = React.forwardRef(AMap);
1 change: 1 addition & 0 deletions packages/platform/src/app/components/amap/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AMap';
65 changes: 0 additions & 65 deletions packages/platform/src/app/components/chart/Chart.tsx

This file was deleted.

1 change: 0 additions & 1 deletion packages/platform/src/app/components/chart/index.ts

This file was deleted.

76 changes: 76 additions & 0 deletions packages/platform/src/app/components/echarts/ECharts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import type { AppTheme } from '../../App';

import * as echarts from 'echarts';
import { cloneDeep, merge } from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react';

import { useAsync, useResize, useStorage } from '@react-devui/hooks';
import { setRef } from '@react-devui/hooks/useForkRef';
import { getClassName } from '@react-devui/utils';

import { STORAGE_KEY } from '../../../config/storage';
import chartTheme from './theme.json';

echarts.registerTheme('light', chartTheme.light);
echarts.registerTheme('dark', merge(cloneDeep(chartTheme.light), chartTheme.dark));

export interface AppEChartsProps<O extends echarts.EChartsOption> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
aOption: O | null;
}

function ECharts<O extends echarts.EChartsOption>(props: AppEChartsProps<O>, ref: React.ForwardedRef<echarts.ECharts>): JSX.Element | null {
const {
aOption,

...restProps
} = props;

//#region Ref
const elRef = useRef<HTMLDivElement>(null);
//#endregion

const dataRef = useRef<{
clearTid?: () => void;
}>({});

const async = useAsync();

const themeStorage = useStorage<AppTheme>(...STORAGE_KEY.theme);

const [instance, setInstance] = useState<echarts.ECharts | null>(null);
const containerRef = useCallback(
(el: HTMLElement | null) => {
setInstance((draft) => {
draft?.dispose();
const instance = el ? echarts.init(el, themeStorage.value, { renderer: 'svg' }) : null;
setRef(ref, instance);
return instance;
});
},
[ref, themeStorage.value]
);

useEffect(() => {
if (instance && aOption) {
instance.setOption(aOption);
}
}, [aOption, instance]);

useResize(elRef, () => {
if (instance) {
dataRef.current.clearTid?.();
dataRef.current.clearTid = async.setTimeout(() => {
dataRef.current.clearTid = undefined;
instance.resize({ animation: { duration: 200 } });
}, 100);
}
});

return (
<div {...restProps} ref={elRef} className={getClassName(restProps.className, 'app-echarts')}>
<div ref={containerRef} className="app-echarts__container"></div>
</div>
);
}

export const AppECharts = React.forwardRef(ECharts);
1 change: 1 addition & 0 deletions packages/platform/src/app/components/echarts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ECharts';
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@
"breadcrumb": {
"itemStyle": {
"color": "var(--d-color-icon-decorator)"
},
"emphasis": {
"itemStyle": {
"color": "var(--d-color-primary-lighter)"
}
}
}
},
Expand Down Expand Up @@ -283,7 +288,7 @@
},
"emphasis": {
"iconStyle": {
"borderColor": "var(--d-text-color)"
"borderColor": "var(--d-color-primary-lighter)"
}
}
},
Expand Down
7 changes: 5 additions & 2 deletions packages/platform/src/app/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export type { AppChartProps } from './chart';
export { AppChart } from './chart';
export type { AppAMapProps } from './amap';
export { AppAMap } from './amap';

export type { AppEChartsProps } from './echarts';
export { AppECharts } from './echarts';

export { AppFCPLoader } from './fcp-loader';

Expand Down
3 changes: 0 additions & 3 deletions packages/platform/src/app/routes/dashboard/AMap.tsx

This file was deleted.

20 changes: 20 additions & 0 deletions packages/platform/src/app/routes/dashboard/amap/AMap.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@import '~styles/module';

@include b(amap) {
@include app-route;

@include e(empty) {
position: relative;
padding-top: 61.8%;
font-weight: 500;
background-color: var(--d-mask-background-color);

& > div {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
}
}
58 changes: 58 additions & 0 deletions packages/platform/src/app/routes/dashboard/amap/AMap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useTranslation } from 'react-i18next';

import { useStorage } from '@react-devui/hooks';
import { DButton, DForm, DInput, FormControl, FormGroup, useForm, Validators } from '@react-devui/ui';

import { STORAGE_KEY } from '../../../../config/storage';
import { AppAMap } from '../../../components';
import styles from './AMap.module.scss';

export default function AMap(): JSX.Element | null {
const { t } = useTranslation();
const amapStorage = useStorage<{ key: string; securityJsCode: string | null }>(...STORAGE_KEY.amap);

const [form, updateForm] = useForm(
() =>
new FormGroup({
key: new FormControl(amapStorage.value?.key ?? '', Validators.required),
securityJsCode: new FormControl(amapStorage.value?.securityJsCode ?? ''),
})
);

return (
<div className={styles['app-amap']}>
<DForm
className="mb-3"
onSubmit={() => {
amapStorage.set({
key: form.value.key,
securityJsCode: form.value.securityJsCode ? form.value.securityJsCode : null,
});
}}
dLayout="vertical"
dUpdate={updateForm}
>
<DForm.Group dFormGroup={form}>
<DForm.Item dFormControls={{ key: t('routes.dashboard.amap.Please enter your JSAPI key') }} dLabel="Key">
{({ key }) => <DInput dFormControl={key} dPlaceholder="Key" />}
</DForm.Item>
<DForm.Item dFormControls={{ securityJsCode: {} }} dLabel={t('routes.dashboard.amap.Security key')}>
{({ securityJsCode }) => <DInput dFormControl={securityJsCode} dPlaceholder={t('routes.dashboard.amap.Security key')} />}
</DForm.Item>
<DForm.Item>
<DButton type="submit" disabled={!form.valid}>
{t('routes.dashboard.amap.OK')}
</DButton>
</DForm.Item>
</DForm.Group>
</DForm>
{amapStorage.value ? (
<AppAMap style={{ paddingTop: '61.8%' }} aKey={amapStorage.value.key} aSecurityJsCode={amapStorage.value.securityJsCode}></AppAMap>
) : (
<div className={styles['app-amap__empty']}>
<div>{t('routes.dashboard.amap.No JSAPI key')}</div>
</div>
)}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useState } from 'react';
import { useMount } from '@react-devui/hooks';
import { DCard } from '@react-devui/ui';

import { AppChart, AppRouteHeader } from '../../../components';
import { AppECharts, AppRouteHeader } from '../../../components';
import styles from './ECharts.module.scss';
import { getOptions } from './options';

Expand All @@ -26,7 +26,7 @@ export default function ECharts(): JSX.Element | null {
<div key={index} className="col-12 col-xxl-6">
<DCard>
<DCard.Content>
<AppChart style={{ height: 320 }} aOption={option} />
<AppECharts style={{ height: 320 }} aOption={option} />
</DCard.Content>
</DCard>
</div>
Expand Down
Loading

0 comments on commit 18f1e12

Please sign in to comment.