后台模式 根据环境设置不同时间间隔去刷新token
This commit is contained in:
parent
5b27c67a0b
commit
63ddd648ac
|
|
@ -1358,24 +1358,32 @@ export async function refreshToken(params, context) {
|
|||
fn();
|
||||
return '';
|
||||
}
|
||||
else if (now - token.refreshedAt > 600 * 1000) {
|
||||
const newValue = await generateNewIdAsync();
|
||||
await context.operate('token', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
value: newValue,
|
||||
refreshedAt: now,
|
||||
},
|
||||
filter: {
|
||||
id: token.id,
|
||||
}
|
||||
}, {});
|
||||
fn();
|
||||
return newValue;
|
||||
}
|
||||
else {
|
||||
fn();
|
||||
if (process.env.OAK_PLATFORM === 'server') {
|
||||
// 只有server模式去刷新token
|
||||
// 'development' | 'production' | 'staging'
|
||||
const intervals = {
|
||||
development: 7200 * 1000,
|
||||
staging: 600 * 1000,
|
||||
production: 600 * 1000, // 十分钟
|
||||
};
|
||||
const interval = intervals[process.env.NODE_ENV] || 600 * 1000;
|
||||
if (now - token.refreshedAt > interval) {
|
||||
const newValue = await generateNewIdAsync();
|
||||
await context.operate('token', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
value: newValue,
|
||||
refreshedAt: now,
|
||||
},
|
||||
filter: {
|
||||
id: token.id,
|
||||
},
|
||||
}, {});
|
||||
fn();
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
fn();
|
||||
return tokenValue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
|||
showBack: false;
|
||||
onCreate: () => void;
|
||||
onUpdate: (id: string) => void;
|
||||
disableDisplay: false;
|
||||
}>) => React.ReactElement;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export default OakComponent({
|
|||
userId,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
|
@ -59,12 +59,12 @@ export default OakComponent({
|
|||
data: {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
filter: userRelationFilter,
|
||||
},
|
||||
|
|
@ -99,10 +99,10 @@ export default OakComponent({
|
|||
$attr: {
|
||||
$$createAt$$: 1,
|
||||
},
|
||||
$direction: 'desc'
|
||||
$direction: 'desc',
|
||||
};
|
||||
},
|
||||
}
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
|
|
@ -120,9 +120,9 @@ export default OakComponent({
|
|||
sourceRelation: {
|
||||
userRelation$relation: {
|
||||
userId,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
/* filter.relationId = {
|
||||
$in: {
|
||||
|
|
@ -162,14 +162,24 @@ export default OakComponent({
|
|||
},
|
||||
],
|
||||
isList: true,
|
||||
formData({ data: users, props, features }) {
|
||||
formData({ data: rows, props, features }) {
|
||||
const { entity, entityId } = props;
|
||||
const filter = this.getFilterByName('fulltext');
|
||||
const users = props.disableDisplay
|
||||
? rows?.filter((ele) => {
|
||||
const userRelations = ele.userRelation$user?.filter(
|
||||
(ele) => !ele.$$deleteAt$$
|
||||
);
|
||||
return !!(userRelations && userRelations.length > 0);
|
||||
})
|
||||
: rows;
|
||||
return {
|
||||
users: users?.map((ele) => {
|
||||
const { mobile$user, extraFile$entity } = ele;
|
||||
const mobile = mobile$user && mobile$user[0]?.mobile;
|
||||
const avatar = features.extraFile.getUrl(extraFile$entity && extraFile$entity[0]);
|
||||
const avatar = features.extraFile.getUrl(
|
||||
extraFile$entity && extraFile$entity[0]
|
||||
);
|
||||
const user2 = Object.assign({}, ele, {
|
||||
mobile,
|
||||
avatar,
|
||||
|
|
@ -185,8 +195,9 @@ export default OakComponent({
|
|||
redirectToAfterConfirm: {},
|
||||
claimUrl: '',
|
||||
qrCodeType: '',
|
||||
onUpdate: (id) => { },
|
||||
onCreate: () => { },
|
||||
onUpdate: (id) => {},
|
||||
onCreate: () => {},
|
||||
disableDisplay: false,
|
||||
},
|
||||
data: {
|
||||
searchValue: '',
|
||||
|
|
@ -206,7 +217,10 @@ export default OakComponent({
|
|||
listeners: {
|
||||
'entity,entityId'(prev, next) {
|
||||
if (this.state.oakFullpath) {
|
||||
if (prev.entity !== next.entity || prev.entityId !== next.entityId) {
|
||||
if (
|
||||
prev.entity !== next.entity ||
|
||||
prev.entityId !== next.entityId
|
||||
) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -222,33 +236,45 @@ export default OakComponent({
|
|||
},
|
||||
methods: {
|
||||
goUpsert() {
|
||||
const { entity, entityId, redirectToAfterConfirm, qrCodeType, claimUrl, onCreate, } = this.props;
|
||||
const {
|
||||
entity,
|
||||
entityId,
|
||||
redirectToAfterConfirm,
|
||||
qrCodeType,
|
||||
claimUrl,
|
||||
onCreate,
|
||||
} = this.props;
|
||||
if (onCreate) {
|
||||
onCreate();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.warn('userRelation将不再作为page直接使用,请使用回调函数处理');
|
||||
console.warn(
|
||||
'userRelation将不再作为page直接使用,请使用回调函数处理'
|
||||
);
|
||||
}
|
||||
this.navigateTo({
|
||||
url: '/userRelation/upsert',
|
||||
entity,
|
||||
entityId,
|
||||
}, {
|
||||
redirectToAfterConfirm,
|
||||
qrCodeType,
|
||||
claimUrl,
|
||||
});
|
||||
this.navigateTo(
|
||||
{
|
||||
url: '/userRelation/upsert',
|
||||
entity,
|
||||
entityId,
|
||||
},
|
||||
{
|
||||
redirectToAfterConfirm,
|
||||
qrCodeType,
|
||||
claimUrl,
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
goUpdate(id) {
|
||||
const { entity, entityId, onUpdate } = this.props;
|
||||
if (onUpdate) {
|
||||
onUpdate(id);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.warn('userRelation将不再作为page直接使用,请使用回调函数处理');
|
||||
console.warn(
|
||||
'userRelation将不再作为page直接使用,请使用回调函数处理'
|
||||
);
|
||||
}
|
||||
this.navigateTo({
|
||||
url: '/userRelation/upsert/byUser',
|
||||
|
|
@ -265,23 +291,26 @@ export default OakComponent({
|
|||
const user = users.find((ele) => ele.id === idRemove);
|
||||
const relations = user.userRelation$user;
|
||||
try {
|
||||
this.updateItem({
|
||||
userRelation$user: [
|
||||
{
|
||||
id: generateNewId(),
|
||||
action: 'remove',
|
||||
data: {},
|
||||
filter: {
|
||||
id: {
|
||||
$in: relations.map((ele) => ele.id),
|
||||
this.updateItem(
|
||||
{
|
||||
userRelation$user: [
|
||||
{
|
||||
id: generateNewId(),
|
||||
action: 'remove',
|
||||
data: {},
|
||||
filter: {
|
||||
id: {
|
||||
$in: relations.map((ele) => ele.id),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}, idRemove, 'revoke');
|
||||
],
|
||||
},
|
||||
idRemove,
|
||||
'revoke'
|
||||
);
|
||||
await this.execute();
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
if (err instanceof OakUserUnpermittedException) {
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
|
|
@ -309,16 +338,18 @@ export default OakComponent({
|
|||
this.refresh();
|
||||
},
|
||||
chooseActionMp(e) {
|
||||
const { entity, entityId, redirectToAfterConfirm, qrCodeType, } = this.props;
|
||||
const { item: { mode }, } = e.detail;
|
||||
const { entity, entityId, redirectToAfterConfirm, qrCodeType } =
|
||||
this.props;
|
||||
const {
|
||||
item: { mode },
|
||||
} = e.detail;
|
||||
if (mode === 'byMobile') {
|
||||
this.navigateTo({
|
||||
url: '/userRelation/upsert/byMobile',
|
||||
entity,
|
||||
entityId,
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.navigateTo({
|
||||
url: '/userRelation/upsert/byUserEntityGrant',
|
||||
entity,
|
||||
|
|
@ -363,8 +394,7 @@ export default OakComponent({
|
|||
const { idRemoveMp } = this.state;
|
||||
try {
|
||||
await this.confirmDelete(idRemoveMp);
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
idRemoveMp: '',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -129,11 +129,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-popover-inner {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.subMenuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
padding: 0 !important;
|
||||
.selectArticle {
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.select {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default function Render(props) {
|
|||
const urlList = record.content.news_item.map((ele) => {
|
||||
return ele.url;
|
||||
});
|
||||
return (<div>
|
||||
return (<div className={Style.selectArticle}>
|
||||
<Select ref={selectRef} style={{ width: 160 }} bordered={false} value={urlList.includes(url) ? url : '请选择一篇文章'} dropdownRender={() => <div className={Style.select}>
|
||||
{record.content.news_item.map((ele, index) => (<Popover content={<div style={{ padding: 12 }}><ShowNews oakAutoUnmount={true} news={record.content.news_item.filter((ele, index2) => index === index2)}/></div>} placement='right'>
|
||||
<div className={Style.selectItem} onClick={() => {
|
||||
|
|
|
|||
|
|
@ -1373,25 +1373,33 @@ async function refreshToken(params, context) {
|
|||
fn();
|
||||
return '';
|
||||
}
|
||||
else if (now - token.refreshedAt > 600 * 1000) {
|
||||
const newValue = await (0, uuid_1.generateNewIdAsync)();
|
||||
await context.operate('token', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
value: newValue,
|
||||
refreshedAt: now,
|
||||
},
|
||||
filter: {
|
||||
id: token.id,
|
||||
}
|
||||
}, {});
|
||||
fn();
|
||||
return newValue;
|
||||
}
|
||||
else {
|
||||
fn();
|
||||
if (process.env.OAK_PLATFORM === 'server') {
|
||||
// 只有server模式去刷新token
|
||||
// 'development' | 'production' | 'staging'
|
||||
const intervals = {
|
||||
development: 7200 * 1000,
|
||||
staging: 600 * 1000,
|
||||
production: 600 * 1000, // 十分钟
|
||||
};
|
||||
const interval = intervals[process.env.NODE_ENV] || 600 * 1000;
|
||||
if (now - token.refreshedAt > interval) {
|
||||
const newValue = await (0, uuid_1.generateNewIdAsync)();
|
||||
await context.operate('token', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
value: newValue,
|
||||
refreshedAt: now,
|
||||
},
|
||||
filter: {
|
||||
id: token.id,
|
||||
},
|
||||
}, {});
|
||||
fn();
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
fn();
|
||||
return tokenValue;
|
||||
}
|
||||
exports.refreshToken = refreshToken;
|
||||
|
|
|
|||
|
|
@ -1925,24 +1925,36 @@ export async function refreshToken<
|
|||
fn();
|
||||
return '';
|
||||
}
|
||||
else if (now - (token.refreshedAt as number) > 600 * 1000) {
|
||||
const newValue = await generateNewIdAsync();
|
||||
await context.operate('token', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
value: newValue,
|
||||
refreshedAt: now,
|
||||
},
|
||||
filter: {
|
||||
id: token.id,
|
||||
}
|
||||
}, {});
|
||||
fn();
|
||||
return newValue;
|
||||
}
|
||||
else {
|
||||
fn();
|
||||
if (process.env.OAK_PLATFORM === 'server') {
|
||||
// 只有server模式去刷新token
|
||||
// 'development' | 'production' | 'staging'
|
||||
const intervals = {
|
||||
development: 7200 * 1000, // 2小时
|
||||
staging: 600 * 1000, // 十分钟
|
||||
production: 600 * 1000, // 十分钟
|
||||
};
|
||||
const interval = intervals[process.env.NODE_ENV] || 600 * 1000;
|
||||
if (now - (token.refreshedAt as number) > interval) {
|
||||
const newValue = await generateNewIdAsync();
|
||||
await context.operate(
|
||||
'token',
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
value: newValue,
|
||||
refreshedAt: now,
|
||||
},
|
||||
filter: {
|
||||
id: token.id,
|
||||
},
|
||||
},
|
||||
{}
|
||||
);
|
||||
fn();
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
fn();
|
||||
return tokenValue;
|
||||
}
|
||||
|
|
@ -14,10 +14,11 @@ export default OakComponent({
|
|||
const isRoot = this.features.token.isRoot();
|
||||
assert(userId);
|
||||
const { entity, entityId } = this.props;
|
||||
const userRelationFilter: EntityDict['userRelation']['Selection']['filter'] = {
|
||||
entity: entity as string,
|
||||
entityId,
|
||||
};
|
||||
const userRelationFilter: EntityDict['userRelation']['Selection']['filter'] =
|
||||
{
|
||||
entity: entity as string,
|
||||
entityId,
|
||||
};
|
||||
if (!isRoot) {
|
||||
userRelationFilter.relation = {
|
||||
relationAuth$destRelation: {
|
||||
|
|
@ -26,8 +27,8 @@ export default OakComponent({
|
|||
userId,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
id: 1,
|
||||
|
|
@ -64,13 +65,12 @@ export default OakComponent({
|
|||
data: {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
filter: userRelationFilter,
|
||||
},
|
||||
|
|
@ -105,10 +105,10 @@ export default OakComponent({
|
|||
$attr: {
|
||||
$$createAt$$: 1,
|
||||
},
|
||||
$direction: 'desc'
|
||||
}
|
||||
$direction: 'desc',
|
||||
};
|
||||
},
|
||||
}
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
|
|
@ -116,61 +116,40 @@ export default OakComponent({
|
|||
const userId = this.features.token.getUserId();
|
||||
const isRoot = this.features.token.isRoot();
|
||||
const { entityId, entity } = this.props;
|
||||
const filter: EntityDict['userRelation']['Selection']['filter'] = {
|
||||
entity,
|
||||
entityId,
|
||||
};
|
||||
const filter: EntityDict['userRelation']['Selection']['filter'] =
|
||||
{
|
||||
entity,
|
||||
entityId,
|
||||
};
|
||||
if (!isRoot) {
|
||||
filter.relation = {
|
||||
relationAuth$destRelation: {
|
||||
sourceRelation: {
|
||||
userRelation$relation: {
|
||||
userId,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* filter.relationId = {
|
||||
$in: {
|
||||
entity: 'relationAuth',
|
||||
data: {
|
||||
destRelationId: 1,
|
||||
},
|
||||
filter: {
|
||||
sourceRelationId: {
|
||||
$in: {
|
||||
entity: 'userRelation',
|
||||
data: {
|
||||
relationId: 1,
|
||||
},
|
||||
filter: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}; */
|
||||
};
|
||||
}
|
||||
return {
|
||||
userRelation$user: filter,
|
||||
/* id: {
|
||||
$in: {
|
||||
entity: 'userRelation',
|
||||
data: {
|
||||
userId: 1,
|
||||
},
|
||||
filter,
|
||||
},
|
||||
}, */
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
isList: true,
|
||||
formData({ data: users, props, features }) {
|
||||
formData({ data: rows, props, features }) {
|
||||
const { entity, entityId } = props;
|
||||
const filter = this.getFilterByName('fulltext');
|
||||
const users = props.disableDisplay
|
||||
? rows?.filter((ele) => {
|
||||
const userRelations = ele.userRelation$user?.filter(
|
||||
(ele) => !ele.$$deleteAt$$
|
||||
);
|
||||
return !!(userRelations && userRelations.length > 0);
|
||||
})
|
||||
: rows;
|
||||
return {
|
||||
users: users?.map((ele: any) => {
|
||||
const { mobile$user, extraFile$entity } = ele;
|
||||
|
|
@ -190,11 +169,13 @@ export default OakComponent({
|
|||
properties: {
|
||||
entity: '' as keyof EntityDict,
|
||||
entityId: '',
|
||||
redirectToAfterConfirm: {} as EntityDict['userEntityGrant']['Schema']['redirectTo'],
|
||||
redirectToAfterConfirm:
|
||||
{} as EntityDict['userEntityGrant']['Schema']['redirectTo'],
|
||||
claimUrl: '',
|
||||
qrCodeType: '' as string,
|
||||
qrCodeType: '',
|
||||
onUpdate: (id: string) => {},
|
||||
onCreate: () => {},
|
||||
disableDisplay: false,
|
||||
},
|
||||
data: {
|
||||
searchValue: '',
|
||||
|
|
@ -214,7 +195,10 @@ export default OakComponent({
|
|||
listeners: {
|
||||
'entity,entityId'(prev, next) {
|
||||
if (this.state.oakFullpath) {
|
||||
if (prev.entity !== next.entity || prev.entityId !== next.entityId) {
|
||||
if (
|
||||
prev.entity !== next.entity ||
|
||||
prev.entityId !== next.entityId
|
||||
) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -240,10 +224,11 @@ export default OakComponent({
|
|||
} = this.props;
|
||||
if (onCreate) {
|
||||
onCreate();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.warn('userRelation将不再作为page直接使用,请使用回调函数处理');
|
||||
console.warn(
|
||||
'userRelation将不再作为page直接使用,请使用回调函数处理'
|
||||
);
|
||||
}
|
||||
this.navigateTo(
|
||||
{
|
||||
|
|
@ -263,19 +248,18 @@ export default OakComponent({
|
|||
const { entity, entityId, onUpdate } = this.props;
|
||||
if (onUpdate) {
|
||||
onUpdate(id);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.warn('userRelation将不再作为page直接使用,请使用回调函数处理');
|
||||
console.warn(
|
||||
'userRelation将不再作为page直接使用,请使用回调函数处理'
|
||||
);
|
||||
}
|
||||
this.navigateTo(
|
||||
{
|
||||
url: '/userRelation/upsert/byUser',
|
||||
entity,
|
||||
entityId,
|
||||
oakId: id,
|
||||
},
|
||||
);
|
||||
this.navigateTo({
|
||||
url: '/userRelation/upsert/byUser',
|
||||
entity,
|
||||
entityId,
|
||||
oakId: id,
|
||||
});
|
||||
}
|
||||
},
|
||||
async confirmDelete(idRemove: string) {
|
||||
|
|
@ -338,12 +322,8 @@ export default OakComponent({
|
|||
},
|
||||
|
||||
chooseActionMp(e: WechatMiniprogram.TouchEvent) {
|
||||
const {
|
||||
entity,
|
||||
entityId,
|
||||
redirectToAfterConfirm,
|
||||
qrCodeType,
|
||||
} = this.props;
|
||||
const { entity, entityId, redirectToAfterConfirm, qrCodeType } =
|
||||
this.props;
|
||||
const {
|
||||
item: { mode },
|
||||
} = e.detail;
|
||||
|
|
@ -422,19 +402,20 @@ export default OakComponent({
|
|||
},
|
||||
},
|
||||
}) as <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(
|
||||
props: ReactComponentProps<
|
||||
ED2,
|
||||
T2,
|
||||
true,
|
||||
{
|
||||
entity: keyof ED2,
|
||||
entityId: string,
|
||||
redirectToAfterConfirm: ED2['userEntityGrant']['Schema']['redirectTo'],
|
||||
qrCodeType: string,
|
||||
showTitle: true,
|
||||
showBack: false,
|
||||
onCreate: () => void,
|
||||
onUpdate: (id: string) => void,
|
||||
}
|
||||
>
|
||||
) => React.ReactElement;
|
||||
props: ReactComponentProps<
|
||||
ED2,
|
||||
T2,
|
||||
true,
|
||||
{
|
||||
entity: keyof ED2;
|
||||
entityId: string;
|
||||
redirectToAfterConfirm: ED2['userEntityGrant']['Schema']['redirectTo'];
|
||||
qrCodeType: string;
|
||||
showTitle: true;
|
||||
showBack: false;
|
||||
onCreate: () => void;
|
||||
onUpdate: (id: string) => void;
|
||||
disableDisplay: false;
|
||||
}
|
||||
>
|
||||
) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -129,11 +129,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-popover-inner {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.subMenuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
|||
Loading…
Reference in New Issue