mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-28 19:05:53 +00:00
Adding welcome first user modal and auto-silent-renew for token (#184)
* Adding welcome first user modal and auto-silent-renew for token * Minor fix
This commit is contained in:
parent
b5ed3feac2
commit
d170cfe1c6
19
catalog-rest-service/src/main/resources/ui/src/@types/jpeg.d.ts
vendored
Normal file
19
catalog-rest-service/src/main/resources/ui/src/@types/jpeg.d.ts
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Module declaration to allow importing JPEG files
|
||||||
|
declare module '*.jpeg';
|
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
@ -19,7 +19,7 @@ import { AxiosResponse } from 'axios';
|
|||||||
import { CookieStorage } from 'cookie-storage';
|
import { CookieStorage } from 'cookie-storage';
|
||||||
import { isEmpty, isNil } from 'lodash';
|
import { isEmpty, isNil } from 'lodash';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { User } from 'Models';
|
import { NewUser, User } from 'Models';
|
||||||
import { UserManager, WebStorageStateStore } from 'oidc-client';
|
import { UserManager, WebStorageStateStore } from 'oidc-client';
|
||||||
import React, {
|
import React, {
|
||||||
ComponentType,
|
ComponentType,
|
||||||
@ -28,7 +28,13 @@ import React, {
|
|||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { Callback, makeAuthenticator, makeUserManager } from 'react-oidc';
|
import { Callback, makeAuthenticator, makeUserManager } from 'react-oidc';
|
||||||
import { Redirect, Route, Switch, useHistory } from 'react-router-dom';
|
import {
|
||||||
|
Redirect,
|
||||||
|
Route,
|
||||||
|
Switch,
|
||||||
|
useHistory,
|
||||||
|
useLocation,
|
||||||
|
} from 'react-router-dom';
|
||||||
import appState from '../AppState';
|
import appState from '../AppState';
|
||||||
import axiosClient from '../axiosAPIs';
|
import axiosClient from '../axiosAPIs';
|
||||||
import { fetchAuthorizerConfig } from '../axiosAPIs/miscAPI';
|
import { fetchAuthorizerConfig } from '../axiosAPIs/miscAPI';
|
||||||
@ -38,6 +44,7 @@ import {
|
|||||||
getUserByName,
|
getUserByName,
|
||||||
getUsers,
|
getUsers,
|
||||||
} from '../axiosAPIs/userAPI';
|
} from '../axiosAPIs/userAPI';
|
||||||
|
import { FirstTimeUserModal } from '../components/Modals/FirstTimeUserModal/FirstTimeUserModal';
|
||||||
import {
|
import {
|
||||||
API_RES_MAX_SIZE,
|
API_RES_MAX_SIZE,
|
||||||
oidcTokenKey,
|
oidcTokenKey,
|
||||||
@ -72,9 +79,16 @@ const AuthProvider: FunctionComponent<AuthProviderProps> = ({
|
|||||||
childComponentType,
|
childComponentType,
|
||||||
children,
|
children,
|
||||||
}: AuthProviderProps) => {
|
}: AuthProviderProps) => {
|
||||||
|
const location = useLocation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const showToast = useToastContext();
|
const showToast = useToastContext();
|
||||||
const { isSignedIn, isSigningIn, isSignedOut } = useAuth();
|
const {
|
||||||
|
isAuthenticatedRoute,
|
||||||
|
isFirstTimeUser,
|
||||||
|
isSignedIn,
|
||||||
|
isSigningIn,
|
||||||
|
isSignedOut,
|
||||||
|
} = useAuth(location.pathname);
|
||||||
|
|
||||||
const oidcUserToken = cookieStorage.getItem(oidcTokenKey);
|
const oidcUserToken = cookieStorage.getItem(oidcTokenKey);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@ -82,11 +96,11 @@ const AuthProvider: FunctionComponent<AuthProviderProps> = ({
|
|||||||
{} as UserManager
|
{} as UserManager
|
||||||
);
|
);
|
||||||
const [userManagerConfig, setUserManagerConfig] = useState<
|
const [userManagerConfig, setUserManagerConfig] = useState<
|
||||||
Record<string, string | WebStorageStateStore>
|
Record<string, string | boolean | WebStorageStateStore>
|
||||||
>({});
|
>({});
|
||||||
|
|
||||||
const clearOidcUserData = (
|
const clearOidcUserData = (
|
||||||
userConfig: Record<string, string | WebStorageStateStore>
|
userConfig: Record<string, string | boolean | WebStorageStateStore>
|
||||||
): void => {
|
): void => {
|
||||||
cookieStorage.removeItem(
|
cookieStorage.removeItem(
|
||||||
`oidc.user:${userConfig.authority}:${userConfig.client_id}`
|
`oidc.user:${userConfig.authority}:${userConfig.client_id}`
|
||||||
@ -198,6 +212,15 @@ const AuthProvider: FunctionComponent<AuthProviderProps> = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFirstTourModal = (skip: boolean) => {
|
||||||
|
appState.newUser = {} as NewUser;
|
||||||
|
if (skip) {
|
||||||
|
history.push(ROUTES.HOME);
|
||||||
|
} else {
|
||||||
|
// TODO: Route to tour page
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchAuthConfig();
|
fetchAuthConfig();
|
||||||
|
|
||||||
@ -241,39 +264,47 @@ const AuthProvider: FunctionComponent<AuthProviderProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!loading ? (
|
{!loading ? (
|
||||||
<Switch>
|
<>
|
||||||
<Route exact path={ROUTES.HOME}>
|
<Switch>
|
||||||
{!isSignedIn && !isSigningIn ? (
|
<Route exact path={ROUTES.HOME}>
|
||||||
<Redirect to={ROUTES.SIGNIN} />
|
{!isSignedIn && !isSigningIn ? (
|
||||||
|
<Redirect to={ROUTES.SIGNIN} />
|
||||||
|
) : (
|
||||||
|
<Redirect to={ROUTES.MY_DATA} />
|
||||||
|
)}
|
||||||
|
</Route>
|
||||||
|
<Route exact component={PageNotFound} path={ROUTES.NOT_FOUND} />
|
||||||
|
{!isSigningIn ? (
|
||||||
|
<Route exact component={SigninPage} path={ROUTES.SIGNIN} />
|
||||||
|
) : null}
|
||||||
|
<Route
|
||||||
|
path={ROUTES.CALLBACK}
|
||||||
|
render={() => (
|
||||||
|
<Callback
|
||||||
|
userManager={userManager}
|
||||||
|
onSuccess={(user) => {
|
||||||
|
cookieStorage.setItem(oidcTokenKey, user.id_token, {
|
||||||
|
expires: getOidcExpiry(),
|
||||||
|
});
|
||||||
|
fetchUserByEmail(user as OidcUser);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{isSignedOut ? <Redirect to={ROUTES.SIGNIN} /> : null}
|
||||||
|
{oidcUserToken || !userManagerConfig?.client_id ? (
|
||||||
|
children
|
||||||
) : (
|
) : (
|
||||||
<Redirect to={ROUTES.MY_DATA} />
|
<AppWithAuth />
|
||||||
)}
|
)}
|
||||||
</Route>
|
</Switch>
|
||||||
<Route exact component={PageNotFound} path={ROUTES.NOT_FOUND} />
|
{isAuthenticatedRoute && isFirstTimeUser ? (
|
||||||
{!isSigningIn ? (
|
<FirstTimeUserModal
|
||||||
<Route exact component={SigninPage} path={ROUTES.SIGNIN} />
|
onCancel={() => handleFirstTourModal(true)}
|
||||||
|
onSave={() => handleFirstTourModal(false)}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<Route
|
</>
|
||||||
path={ROUTES.CALLBACK}
|
|
||||||
render={() => (
|
|
||||||
<Callback
|
|
||||||
userManager={userManager}
|
|
||||||
onSuccess={(user) => {
|
|
||||||
cookieStorage.setItem(oidcTokenKey, user.id_token, {
|
|
||||||
expires: getOidcExpiry(),
|
|
||||||
});
|
|
||||||
fetchUserByEmail(user as OidcUser);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{isSignedOut ? <Redirect to={ROUTES.SIGNIN} /> : null}
|
|
||||||
{oidcUserToken || !userManagerConfig?.client_id ? (
|
|
||||||
children
|
|
||||||
) : (
|
|
||||||
<AppWithAuth />
|
|
||||||
)}
|
|
||||||
</Switch>
|
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { FunctionComponent, useState } from 'react';
|
import React, { FunctionComponent, useState } from 'react';
|
||||||
|
import BGConfetti from '../../../assets/img/confetti-bg.jpeg';
|
||||||
import { Button } from '../../buttons/Button/Button';
|
import { Button } from '../../buttons/Button/Button';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -15,48 +16,44 @@ const description = [
|
|||||||
|
|
||||||
export const FirstTimeUserModal: FunctionComponent<Props> = ({
|
export const FirstTimeUserModal: FunctionComponent<Props> = ({
|
||||||
onCancel,
|
onCancel,
|
||||||
|
onSave,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [active, setActive] = useState<number>(0);
|
const [active, setActive] = useState<number>(0);
|
||||||
const [lastSlide, setLastSlide] = useState<boolean>(false);
|
const [lastSlide, setLastSlide] = useState<boolean>(false);
|
||||||
|
|
||||||
const previousClick = () => {
|
const previousClick = () => {
|
||||||
if (lastSlide) {
|
setActive((pre) => pre - 1);
|
||||||
// to somthing
|
setLastSlide(false);
|
||||||
} else {
|
|
||||||
setActive((pre) => pre - 1);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const nextClick = () => {
|
const nextClick = () => {
|
||||||
if (lastSlide) {
|
setActive((pre) => {
|
||||||
onCancel();
|
const newVal = pre + 1;
|
||||||
} else {
|
setLastSlide(description.length - 1 === newVal);
|
||||||
setActive((pre) => {
|
|
||||||
const newVal = pre + 1;
|
|
||||||
description.length - 1 === newVal && setLastSlide(true);
|
|
||||||
|
|
||||||
return newVal;
|
return newVal;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<dialog className="tw-modal">
|
<dialog className="tw-modal">
|
||||||
<div className="tw-modal-backdrop tw-opacity-80" />
|
<div className="tw-modal-backdrop tw-opacity-80" />
|
||||||
<div className="tw-modal-container tw-max-w-xl tw-max-h-90vh tw-bg-gradient-to-bl tw-to-primary-lite tw-from-secondary-lite">
|
<div
|
||||||
<div className="tw-modal-header tw-border-0 tw-justify-center tw-pt-8">
|
className="tw-modal-container tw-modal-confetti tw-max-w-xl tw-max-h-90vh"
|
||||||
<p className="tw-modal-title tw-text-h4 tw-font-semibold tw-text-primary-active">
|
style={{ backgroundImage: `url(${BGConfetti})` }}>
|
||||||
|
<div className="tw-modal-header tw-border-0 tw-justify-center tw-pt-8 tw-pb-0">
|
||||||
|
<p className="tw-modal-title tw-text-h4 tw-font-semibold tw-text-primary-active tw-mt-32">
|
||||||
Welcome to OpenMetadata
|
Welcome to OpenMetadata
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-modal-body tw-relative tw-h-64 tw-justify-center tw-items-center">
|
<div className="tw-modal-body tw-relative tw-h-40 tw-justify-start tw-items-center">
|
||||||
{description.map((d, i) => (
|
{description.map((d, i) => (
|
||||||
<p
|
<p
|
||||||
className={classNames(
|
className={classNames(
|
||||||
i === active
|
i === active
|
||||||
? 'tw-opacity-100 tw-relative tw-transition-opacity tw-delay-200'
|
? 'tw-opacity-100 tw-relative tw-transition-opacity tw-delay-200'
|
||||||
: 'tw-opacity-0 tw-absolute',
|
: 'tw-opacity-0 tw-absolute',
|
||||||
'tw-text-xl tw-font-medium tw-text-center'
|
'tw-text-xl tw-font-medium tw-text-center tw-bg-white tw-mx-7'
|
||||||
)}
|
)}
|
||||||
key={i}>
|
key={i}>
|
||||||
{d}
|
{d}
|
||||||
@ -66,38 +63,48 @@ export const FirstTimeUserModal: FunctionComponent<Props> = ({
|
|||||||
<div className="tw-modal-footer tw-border-0 tw-justify-between">
|
<div className="tw-modal-footer tw-border-0 tw-justify-between">
|
||||||
<Button
|
<Button
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'tw-bg-primary-active tw-text-white',
|
'tw-text-primary-active',
|
||||||
active === 0 ? 'tw-invisible' : null
|
active === 0 ? 'tw-invisible' : null
|
||||||
)}
|
)}
|
||||||
size="regular"
|
size="regular"
|
||||||
theme="primary"
|
theme="primary"
|
||||||
variant="contained"
|
variant="text"
|
||||||
onClick={previousClick}>
|
onClick={previousClick}>
|
||||||
{lastSlide ? (
|
<i className="fas fa-arrow-left tw-text-sm tw-align-middle tw-pr-1.5" />{' '}
|
||||||
'Take a Tour'
|
<span>Previous</span>
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<i className="fas fa-arrow-left tw-text-sm tw-align-middle tw-pr-1.5" />{' '}
|
|
||||||
<span>Previous</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
className="tw-bg-primary-active tw-text-white"
|
|
||||||
size="regular"
|
|
||||||
theme="primary"
|
|
||||||
variant="contained"
|
|
||||||
onClick={nextClick}>
|
|
||||||
{lastSlide ? (
|
|
||||||
'Skip and go to landing page'
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<span>Next</span>
|
|
||||||
<i className="fas fa-arrow-right tw-text-sm tw-align-middle tw-pl-1.5" />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Button>
|
</Button>
|
||||||
|
{lastSlide ? (
|
||||||
|
<span>
|
||||||
|
<Button
|
||||||
|
className="tw-text-primary-active tw-hidden"
|
||||||
|
size="regular"
|
||||||
|
theme="default"
|
||||||
|
variant="text"
|
||||||
|
onClick={onCancel}>
|
||||||
|
<span>Skip</span>
|
||||||
|
<i className="fas fa-angle-double-right tw-text-sm tw-align-middle tw-pl-1.5" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="tw-bg-primary-active tw-text-white"
|
||||||
|
id="take-tour"
|
||||||
|
size="regular"
|
||||||
|
theme="primary"
|
||||||
|
variant="contained"
|
||||||
|
onClick={onSave}>
|
||||||
|
Explore OpenMetadata
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
className="tw-text-primary-active"
|
||||||
|
size="regular"
|
||||||
|
theme="primary"
|
||||||
|
variant="text"
|
||||||
|
onClick={nextClick}>
|
||||||
|
<span>Next</span>
|
||||||
|
<i className="fas fa-arrow-right tw-text-sm tw-align-middle tw-pl-1.5" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
@ -38,5 +38,6 @@ export const useAuth = (pathname = '') => {
|
|||||||
isAuthenticatedRoute: isAuthenticatedRoute,
|
isAuthenticatedRoute: isAuthenticatedRoute,
|
||||||
isAuthDisabled: authDisabled,
|
isAuthDisabled: authDisabled,
|
||||||
isAdminUser: userDetails?.isAdmin,
|
isAdminUser: userDetails?.isAdmin,
|
||||||
|
isFirstTimeUser: !isEmpty(userDetails) && !isEmpty(newUser),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -40,7 +40,7 @@ const SigninPage = () => {
|
|||||||
<PageContainer>
|
<PageContainer>
|
||||||
<div className="tw-w-screen tw-h-screen tw-flex tw-justify-center">
|
<div className="tw-w-screen tw-h-screen tw-flex tw-justify-center">
|
||||||
<div className="tw-flex tw-flex-col tw-items-center signin-box">
|
<div className="tw-flex tw-flex-col tw-items-center signin-box">
|
||||||
<div className="tw-flex tw-justify-center tw-items-center tw-my-7">
|
<div className="tw-flex tw-justify-center tw-items-center tw-mb-7 tw-mt-20">
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
alt="OpenMetadata Logo"
|
alt="OpenMetadata Logo"
|
||||||
icon={Icons.LOGO_SMALL}
|
icon={Icons.LOGO_SMALL}
|
||||||
@ -56,7 +56,7 @@ const SigninPage = () => {
|
|||||||
<h6 className="tw-mb-px">Centralized Metadata Store, Discover,</h6>
|
<h6 className="tw-mb-px">Centralized Metadata Store, Discover,</h6>
|
||||||
<h6 className="tw-mb-px">Collaborate and get your Data Right</h6>
|
<h6 className="tw-mb-px">Collaborate and get your Data Right</h6>
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-mt-16" onClick={handleSignIn}>
|
<div className="tw-mt-4" onClick={handleSignIn}>
|
||||||
{appState.authProvider.provider === AuthTypes.GOOGLE && (
|
{appState.authProvider.provider === AuthTypes.GOOGLE && (
|
||||||
<button className="tw-signin-button">
|
<button className="tw-signin-button">
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
|
@ -110,11 +110,17 @@
|
|||||||
.tw-modal {
|
.tw-modal {
|
||||||
@apply tw-z-9999 tw-flex tw-fixed tw-inset-0 tw-bg-transparent tw-justify-center tw-h-screen tw-w-screen tw-items-center tw-antialiased;
|
@apply tw-z-9999 tw-flex tw-fixed tw-inset-0 tw-bg-transparent tw-justify-center tw-h-screen tw-w-screen tw-items-center tw-antialiased;
|
||||||
}
|
}
|
||||||
|
.tw-modal-confetti {
|
||||||
|
background-size: cover;
|
||||||
|
background-position-y: -75px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position-x: center;
|
||||||
|
}
|
||||||
.tw-modal-backdrop {
|
.tw-modal-backdrop {
|
||||||
@apply tw-opacity-60 tw-bg-body-hover tw-absolute tw-inset-0;
|
@apply tw-opacity-60 tw-bg-body-hover tw-absolute tw-inset-0;
|
||||||
}
|
}
|
||||||
.tw-modal-container {
|
.tw-modal-container {
|
||||||
@apply tw-flex tw-flex-col tw-absolute tw-py-5 tw-bg-white tw-w-11/12 tw-max-w-screen-lg tw-max-h-screen tw-mx-auto tw-rounded-lg tw-border tw-border-main tw-shadow-xl;
|
@apply tw-flex tw-flex-col tw-absolute tw-py-5 tw-bg-white tw-w-11/12 tw-max-w-screen-lg tw-max-h-screen tw-mx-auto tw-rounded-lg tw-border tw-border-main tw-shadow-modal;
|
||||||
}
|
}
|
||||||
.tw-modal-header {
|
.tw-modal-header {
|
||||||
@apply tw-flex tw-flex-row tw-justify-between tw-px-6 tw-pb-5 tw-bg-transparent tw-border-b tw-border-separator;
|
@apply tw-flex tw-flex-row tw-justify-between tw-px-6 tw-pb-5 tw-bg-transparent tw-border-b tw-border-separator;
|
||||||
@ -280,13 +286,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.signin-box {
|
.signin-box {
|
||||||
@apply tw-m-auto tw-h-100 tw-w-120;
|
@apply tw-m-auto tw-h-100 tw-w-120 tw-bg-white tw-shadow-modal;
|
||||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.signup-box {
|
.signup-box {
|
||||||
@apply tw-m-auto tw-w-120 tw-bg-white;
|
@apply tw-m-auto tw-w-120 tw-bg-white tw-shadow-modal;
|
||||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.disable-cta * {
|
.disable-cta * {
|
||||||
|
@ -11,11 +11,12 @@ export const getOidcExpiry = () => {
|
|||||||
|
|
||||||
export const getUserManagerConfig = (
|
export const getUserManagerConfig = (
|
||||||
authClient: Record<string, string> = {}
|
authClient: Record<string, string> = {}
|
||||||
): Record<string, string | WebStorageStateStore> => {
|
): Record<string, string | boolean | WebStorageStateStore> => {
|
||||||
const { authority, clientId, callbackUrl } = authClient;
|
const { authority, clientId, callbackUrl } = authClient;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
authority,
|
authority,
|
||||||
|
automaticSilentRenew: true,
|
||||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||||
client_id: clientId,
|
client_id: clientId,
|
||||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||||
|
@ -22,6 +22,8 @@ const primary = '#7147E8';
|
|||||||
const primaryHover = '#5523E0';
|
const primaryHover = '#5523E0';
|
||||||
const primaryActive = '#450DE2';
|
const primaryActive = '#450DE2';
|
||||||
const primaryHoverLite = '#DBD1F9';
|
const primaryHoverLite = '#DBD1F9';
|
||||||
|
const secondary = '#B02AAC';
|
||||||
|
const secondaryBG = '#B02AAC40';
|
||||||
|
|
||||||
// state colors
|
// state colors
|
||||||
const success = '#51C41A';
|
const success = '#51C41A';
|
||||||
@ -66,6 +68,9 @@ module.exports = {
|
|||||||
focus: primary,
|
focus: primary,
|
||||||
search: '#D5D6D9',
|
search: '#D5D6D9',
|
||||||
},
|
},
|
||||||
|
boxShadow: {
|
||||||
|
modal: '1px 1px 5px rgba(0, 0, 0, 0.2)',
|
||||||
|
},
|
||||||
colors: {
|
colors: {
|
||||||
'grey-body': textBody,
|
'grey-body': textBody,
|
||||||
'grey-muted': textMuted,
|
'grey-muted': textMuted,
|
||||||
@ -76,6 +81,8 @@ module.exports = {
|
|||||||
'primary-hover': primaryHover,
|
'primary-hover': primaryHover,
|
||||||
'primary-active': primaryActive,
|
'primary-active': primaryActive,
|
||||||
'primary-hover-lite': primaryHoverLite,
|
'primary-hover-lite': primaryHoverLite,
|
||||||
|
secondary: secondary,
|
||||||
|
'secondary-lite': secondaryBG,
|
||||||
'body-main': bodyBG,
|
'body-main': bodyBG,
|
||||||
'body-hover': bodyHoverBG,
|
'body-hover': bodyHoverBG,
|
||||||
tag: tagBG,
|
tag: tagBG,
|
||||||
|
@ -80,7 +80,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
test: /\.(png|jpg|gif|svg|ico)$/i,
|
test: /\.(png|jpg|jpeg|gif|svg|ico)$/i,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: 'url-loader',
|
||||||
|
@ -81,7 +81,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
test: /\.(png|jpg|gif|svg|ico)$/i,
|
test: /\.(png|jpg|jpeg|gif|svg|ico)$/i,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: 'url-loader',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user