utils#isSignedIn JavaScript Examples
The following examples show how to use
utils#isSignedIn.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
App = ({location, fetchUser, userData, userLoading, history: {push}, setSearch}: Props) => {
const [loading, setLoading] = useState(true);
const isInitialMount = useRef(true);
useTracking();
useEffect(() => {
if (isSignedIn())
fetchUser(
() => {},
() => {
setLoading(false);
push(routes.authLogin());
}
);
else
setLoading(false);
}, []);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
setLoading(userLoading);
}
}, [userLoading]);
useEffect(() => {
setSearch('');
}, [location.pathname]);
return (
<div className={css.app}>
{!loading && (
<Switch>
{isSignedIn() && userData && (
<Redirect
exact
from="/"
to={routes.stacks(userData.user)}
/>
)}
<Redirect
exact
from="/"
to={routes.authLogin()}
/>
<Route path={routes.authLogin()} component={Login}/>
<DefaultLayoutRoute path={routes.verifyUser()} component={ConfirmEmail}/>
{isSignedIn() && (
<Switch>
<DefaultLayoutRoute path={routes.notFound()} component={NotFound} />
<DefaultLayoutRoute path={routes.settings()} component={Settings} />
<DefaultLayoutRoute path={routes.dashboards()} component={Dashboards} />
<DefaultLayoutRoute path={routes.stacks()} component={Stacks} />
</Switch>
)}
{!isSignedIn() && (
<Switch>
<UnAuthorizedLayoutRoute path={routes.notFound()} component={NotFound} />
<UnAuthorizedLayoutRoute path={routes.dashboards()} component={Dashboards} />
<UnAuthorizedLayoutRoute path={routes.stacks()} component={Stacks} />
</Switch>
)}
<Redirect
to={routes.notFound()}
/>
</Switch>
)}
{loading && <DefaultLayout>
<Loader />
</DefaultLayout>}
</div>
);
}
Example #2
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
Details = ({
data,
fetch,
update,
currentUser,
deleteDashboard,
insertCard,
deleteCard,
updateCard,
requestStatus,
loading,
}: Props) => {
const {items, moveItem, setItems} = useContext(DnDGridContext);
const {t} = useTranslation();
const [isShowStacksModal, setIsShowStacksModal] = useState(false);
const [titleValue, setTitleValue] = useState(data ? data.title : '');
const [view, setView] = useState('grid');
const {form, setForm, onChange} = useForm({});
const [fields, setFields] = useState({});
const prevData = usePrevious(data);
const params = useParams();
const {push} = useHistory();
const isDidMount = useRef(true);
const updateDebounce = useCallback(_debounce(update, 300), []);
const cards = data?.cards;
const setGridItems = cardsItems => setItems(cardsItems.map(card => ({id: card.index, card})));
useEffect(() => {
if (!data || data.id !== params.id)
fetch(params.user, params.id);
else
setGridItems(cards);
}, []);
useEffect(() => {
if (window)
window.dispatchEvent(new Event('resize'));
}, [view]);
useEffect(() => {
if (cards && !isEqual(prevData, data))
setGridItems(cards);
return () => setGridItems([]);
}, [cards]);
useEffect(() => {
if (!prevData && data || (prevData && data && prevData.id !== data.id))
setTitleValue(data.title);
if ((!isEqual(prevData, data) || isDidMount.current) && data)
parseParams();
if (isDidMount.current)
isDidMount.current = false;
}, [data]);
const onChangeTitle = event => {
setTitleValue(event.target.value);
updateDebounce({
user: params.user,
id: data.id,
title: event.target.value,
});
};
const moveCard = (indexFrom, indexTo) => {
if (indexTo < 0 || indexFrom < 0)
return;
const {stack} = items[indexFrom].card;
updateCard({
user: params.user,
dashboard: data.id,
stack,
index: indexTo,
});
moveItem(indexFrom, indexTo);
};
const onClickAdd = event => {
event.preventDefault();
setIsShowStacksModal(true);
};
const closeModal = () => setIsShowStacksModal(false);
const onClickDelete = () => {
deleteDashboard(
{
user: params.user,
id: data.id,
},
() => {
push(routes.dashboards(params.user));
}
);
};
const getDeleteCardAction = stack => () => {
deleteCard({
user: params.user,
dashboard: data.id,
stack,
});
};
const getUpdateCardAction = stack => fields => {
updateCard({
user: params.user,
dashboard: data.id,
stack,
...fields,
});
};
const addStacksToDashboard = stacks => {
stacks.forEach((stack, index) => {
insertCard({
user: params.user,
dashboard: params.id,
stack,
index: cards.length + index,
});
});
};
const parseParams = () => {
if (!cards)
return;
const fields = cards.reduce((result, card) => {
const cardFields = parseStackParams(get(card, 'head.attachments', [])) || {};
Object.keys(cardFields).forEach(fieldName => {
if (result[fieldName]) {
if (cardFields[fieldName].type === 'select') {
result[fieldName].options = unionBy(
result[fieldName].options,
cardFields[fieldName].options, 'value');
}
if (cardFields[fieldName].type === 'slider') {
result[fieldName].options = {
...result[fieldName].options,
...cardFields[fieldName].options,
};
result[fieldName].min = Math.min(result[fieldName].min, cardFields[fieldName].min);
result[fieldName].max = Math.max(result[fieldName].max, cardFields[fieldName].max);
}
} else {
result[fieldName] = cardFields[fieldName];
}
});
return result;
}, {});
const defaultFilterValues = Object.keys(fields).reduce((result, fieldName) => {
if (fields[fieldName].type === 'select')
result[fieldName] = fields[fieldName].options[0].value;
if (fields[fieldName].type === 'slider')
result[fieldName] = fields[fieldName].options[0];
if (fields[fieldName].type === 'checkbox')
result[fieldName] = false;
return result;
}, {});
setForm(defaultFilterValues);
setFields(fields);
};
const renderFilters = () => {
if (!Object.keys(fields).length)
return null;
const hasSelectField = Object.keys(fields).some(key => fields[key].type === 'select');
return (
<Filters
fields={fields}
form={form}
onChange={onChange}
className={cx(css.filters, {'with-select': hasSelectField})}
/>
);
};
if (loading)
return <Loader />;
if (requestStatus === 403)
return <AccessForbidden>
{t('youDontHaveAnAccessToThisDashboard')}.
{isSignedIn() && (
<Fragment>
<br />
<Link to={routes.dashboards(currentUser)}>
{t('goToMyDashboards')}
</Link>
</Fragment>
)}
</AccessForbidden>;
if (requestStatus === 404)
return <NotFound>
{t('theDashboardYouAreRookingForCouldNotBeFound')}
{' '}
{isSignedIn() && (
<Fragment>
<Link to={routes.dashboards(currentUser)}>
{t('goToMyDashboards')}
</Link>.
</Fragment>
)}
</NotFound>;
if (!data)
return null;
return (
<div className={css.details}>
<div className={css.header}>
<div className={css.title}>
<StretchTitleField
className={css.edit}
value={titleValue}
onChange={onChangeTitle}
readOnly={currentUser !== data.user}
placeholder={t('newDashboard')}
/>
<span className={`mdi mdi-lock${data.private ? '' : '-open'}`} />
</div>
{/*<Button*/}
{/* className={css.pdf}*/}
{/* color="secondary"*/}
{/*>*/}
{/* <span className="mdi mdi-download" />*/}
{/* PDF*/}
{/*</Button>*/}
{currentUser === data.user && <Dropdown
className={css.dropdown}
items={[
{
title: t('delete'),
onClick: onClickDelete,
},
]}
>
<Button
className={css['dropdown-button']}
color="secondary"
>
<span className="mdi mdi-dots-horizontal" />
</Button>
</Dropdown>}
</div>
{Boolean(items.length) && (
<Fragment>
<div className={css.section}>
<div className={css.fields}>
{renderFilters()}
</div>
<div className={css.controls}>
{currentUser === data.user && (
<a
className={css.addButton}
onClick={onClickAdd}
href="#"
>
<span className="mdi mdi-plus" />
{t('addStack')}
</a>
)}
<ViewSwitcher
value={view}
className={css.viewSwitcher}
onChange={view => setView(view)}
/>
</div>
</div>
<div className={cx(css.cards, view)}>
{items.map(item => (
currentUser === data.user
? <DnDItem
id={item.id}
key={item.card.stack}
onMoveItem={moveCard}
>
<Card
filters={form}
deleteCard={getDeleteCardAction(item.card.stack)}
data={item.card}
type={view}
updateCard={getUpdateCardAction(item.card.stack)}
/>
</DnDItem>
: <Card
key={item.card.stack}
filters={form}
data={item.card}
type={view}
/>
))}
</div>
</Fragment>
)}
{!items.length && (
<div className={css.empty}>
{t('thereAreNoStacksYet')} <br/>
{t('youCanSendStacksYouWantToBeHereLaterOrAddItRightNow')}
{currentUser === data.user && (
<Fragment>
{' '}
<a
className={css.addButton}
onClick={onClickAdd}
href="#"
>{t('addStack')}</a>.
</Fragment>
)}
</div>
)}
{isShowStacksModal && <SelectStacks
isShow={isShowStacksModal}
onClose={closeModal}
onAddStacks={addStacksToDashboard}
/>}
</div>
);
}
Example #3
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
List = ({
currentUser,
createDashboard,
creatingDashboard,
fetchList,
setSearch,
setSearchPlaceholder,
data,
search,
loading,
requestStatus,
}: Props) => {
const {user} = useParams();
const {push} = useHistory();
const {t} = useTranslation();
const onChangeSearch = value => setSearch(value);
useEffect(() => {
fetchList(user);
}, [user]);
useEffect(() => {
setSearchPlaceholder(t('findDashboard'));
return () => setSearchPlaceholder(null);
}, []);
const getItems = () => {
let items = [];
if (data && data.length) {
if (search.length)
items = data.filter(i => i.title.indexOf(search) >= 0);
else
items = data;
}
return items;
};
const onClickAdd = () => {
createDashboard(
user,
({dashboard}) => push(routes.dashboardsDetails(user, dashboard.id)),
);
};
const items = getItems();
if (loading)
return <Loader />;
if (requestStatus === 404)
return <NotFound>
{t('theDashboardYouAreRookingForCouldNotBeFound')}
{' '}
{isSignedIn() && (
<Fragment>
<Link to={routes.dashboards(currentUser)}>
{t('goToMyDashboards')}
</Link>.
</Fragment>
)}
</NotFound>;
return (
<div className={css.list}>
<div className={css.title}>
{currentUser === user
? t('myDashboards')
: t('dashboardsOf', {name: user})
}
{data && Boolean(data.length) && <span>{data.length}</span>}
</div>
{data && Boolean(data.length) && <SearchField
placeholder={t('search')}
className={css.search}
showEverything
size="small"
value={search}
onChange={onChangeSearch}
/>}
<div className={css.grid}>
{currentUser === user && (
<div
onClick={onClickAdd}
className={cx(css.add, {disabled: creatingDashboard})}
>
<div className={css.caption}>
<span className="mdi mdi-plus" />
{t('newDashboard')}
</div>
</div>
)}
{items.map((item, index) => (
<Item key={index} dashboard={item} />
))}
</div>
</div>
);
}
Example #4
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
Details = ({
attachment,
attachmentRequestStatus,
fetchDetails,
fetchFrame,
downloadAttachment,
clearDetails,
update,
data = {},
listData = {},
frame,
frameRequestStatus,
loading,
requestStatus,
currentUser,
}: Props) => {
let parsedAttachmentIndex;
const params = useParams();
const {push} = useHistory();
const location = useLocation();
const searchParams = parseSearch(location.search);
if (searchParams.a)
parsedAttachmentIndex = parseInt(searchParams.a);
const [attachmentIndex, setAttachmentIndex] = useState(parsedAttachmentIndex);
const [selectedFrame, setSelectedFrame] = useState(searchParams.f);
const [headId, setHeadId] = useState(null);
const {t} = useTranslation();
const didMountRef = useRef(false);
const {form, setForm, onChange} = useForm({});
const [fields, setFields] = useState({});
const prevFrame = usePrevious(frame);
const [isShowHowToModal, setIsShowHowToModal] = useState(false);
const [isShowUploadModal, setIsShowUploadModal] = useState(false);
const isFirstChangeSearch = useRef(false);
const showHowToModal = event => {
event.preventDefault();
setIsShowHowToModal(true);
};
const hideHowToModal = () => setIsShowHowToModal(false);
const onClickDownloadAttachment = event => {
event.preventDefault();
downloadAttachment(`${params.user}/${params.stack}`, selectedFrame || headId, attachmentIndex || 0);
};
useEffect(() => {
if (isFirstChangeSearch.current) {
let parsedAttachmentIndex;
if (searchParams.a)
parsedAttachmentIndex = parseInt(searchParams.a);
if (parsedAttachmentIndex !== attachmentIndex)
setAttachmentIndex(parsedAttachmentIndex);
if (searchParams.f !== selectedFrame)
setSelectedFrame(searchParams.f);
} else {
isFirstChangeSearch.current = true;
}
}, [location.search]);
useEffect(() => {
let searchParams = {};
if (attachmentIndex)
searchParams.a = attachmentIndex;
if (selectedFrame && selectedFrame !== headId)
searchParams.f = selectedFrame;
const searchString = Object
.keys(searchParams)
.map(key => `${key}=${searchParams[key]}`)
.join('&');
if (location.search.replace('?', '') !== searchString)
push({search: searchString.length ? `?${searchString}` : ''});
}, [attachmentIndex, selectedFrame, headId]);
const fetchData = () => {
fetchDetails(params.user, params.stack);
};
useEffect(() => {
if (!data.head || !listData || (data.head.id !== listData.head))
fetchData();
return () => clearDetails();
}, []);
const setHeadFrame = frameId => {
update({
stack: `${data.user}/${data.name}`,
noUpdateStore: true,
head: frameId,
}, () => setHeadId(frameId));
};
useEffect(() => {
if (selectedFrame)
fetchFrame(params.user, params.stack, selectedFrame);
}, [selectedFrame]);
useEffect(() => {
if ((!isEqual(prevFrame, frame) || !didMountRef.current) && frame)
parseParams();
}, [frame]);
useEffect(() => {
if (data && data.head)
setHeadId(data.head.id);
}, [data]);
const onChangeFrame = frameId => {
setSelectedFrame(frameId);
setAttachmentIndex(undefined);
};
const findAttach = (form, attachmentIndex) => {
const attachments = get(frame, 'attachments');
const fields = Object.keys(form);
if (!attachments)
return;
if (fields.length) {
attachments.some((attach, index) => {
let valid = true;
fields.forEach(key => {
if (!attach.params || !isEqual(attach.params[key], form[key]))
valid = false;
});
if (valid && !(attachmentIndex === undefined && index === 0))
setAttachmentIndex(index);
return valid;
});
}
};
const findAttachDebounce = useCallback(_debounce(findAttach, 300), [data, frame]);
useEffect(() => {
if (didMountRef.current)
findAttachDebounce(form, attachmentIndex);
else
didMountRef.current = true;
}, [form]);
const parseParams = () => {
const attachments = get(frame, 'attachments');
if (!attachments || !attachments.length)
return;
const fields = parseStackParams(attachments);
setFields(fields);
if (attachmentIndex !== undefined) {
if (attachments[attachmentIndex])
setForm(attachments[attachmentIndex].params);
} else
setForm(attachments[0].params);
};
const renderFields = () => {
if (!Object.keys(fields).length)
return null;
const hasSelectField = Object.keys(fields).some(key => fields[key].type === 'select');
return (
<Filters
fields={fields}
form={form}
onChange={onChange}
className={cx(css.filters, {'with-select': hasSelectField})}
/>
);
};
if (loading)
return <Loader />;
if (requestStatus === 403)
return <AccessForbidden>
{t('youDontHaveAnAccessToThisStack')}.
{isSignedIn() && (
<Fragment>
<br />
<Link to={routes.stacks(currentUser)}>
{t('goToMyStacks')}
</Link>
</Fragment>
)}
</AccessForbidden>;
if (requestStatus === 404)
return <NotFound>
{t('theStackYouAreRookingForCouldNotBeFound')}
{' '}
{isSignedIn() && (
<Fragment>
<Link to={routes.stacks(currentUser)}>
{t('goToMyStacks')}
</Link>.
</Fragment>
)}
</NotFound>;
const currentFrame = selectedFrame ? selectedFrame : get(data, 'head.id');
return (
<div className={css.details}>
<Helmet>
<title>dstack.ai | {params.user} | {params.stack}</title>
</Helmet>
<section className={css.section}>
<div className={css.header}>
<div className={css.title}>
{data.name}
<span className={`mdi mdi-lock${data.private ? '' : '-open'}`} />
</div>
{data && data.user === currentUser && (
<Dropdown
className={css.dropdown}
items={[
{
title: t('upload'),
onClick: () => setIsShowUploadModal(true),
},
]}
>
<Button
className={css['dropdown-button']}
color="secondary"
>
<span className="mdi mdi-dots-horizontal" />
</Button>
</Dropdown>
)}
</div>
<Frames
frames={get(data, 'frames', [])}
frame={currentFrame}
headId={headId}
onMarkAsHead={setHeadFrame}
onChange={onChangeFrame}
className={css.revisions}
/>
{!frameRequestStatus && renderFields()}
{attachment && (
<div className={css['attachment-head']}>
{attachment.description && (
<div className={css.description}>
<MarkdownRender source={attachment.description} />
</div>
)}
{attachment.type === 'text/csv' && (
<div className={css.actions}>
<a href="#" onClick={showHowToModal}>{t('useThisStackViaAPI')}</a>
{' '}
{t('or')}
{' '}
<a href="#" onClick={onClickDownloadAttachment}>{t('download')}</a>
{' '}
{attachment.length && (
<span className={css.size}>({formatBytes(attachment.length)})</span>
)}
</div>
)}
</div>
)}
{attachmentRequestStatus === 404 || frameRequestStatus === 404 && (
<div className={css.empty}>{t('noMatch')}</div>
)}
{(frame && !attachmentRequestStatus && !frameRequestStatus) && (
<Attachment
className={css.attachment}
withLoader
stack={`${params.user}/${params.stack}`}
frameId={currentFrame}
id={attachmentIndex || 0}
/>
)}
</section>
<Upload
stack={params.stack}
isShow={isShowUploadModal}
onClose={() => setIsShowUploadModal(false)}
refresh={fetchData}
/>
<Modal
isShow={isShowHowToModal}
withCloseButton
onClose={hideHowToModal}
size="big"
title={t('howToFetchDataUsingTheAPI')}
className={css.modal}
>
<HowToFetchData
data={{
stack: `${params.user}/${params.stack}`,
params: form,
}}
modalMode
/>
</Modal>
</div>
);
}
Example #5
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
List = ({
requestStatus,
setSearch,
fetchList,
data = [],
loading,
deleteStack,
search,
setSearchPlaceholder,
match: {params: {user}},
currentUser,
startAppProgress,
completeAppProgress,
resetAppProgress,
}: Props) => {
const {t} = useTranslation();
const [deletingStack, setDeletingStack] = useState(null);
const [isShowWelcomeModal, setIsShowWelcomeModal] = useState(false);
const [isShowHowToModal, setIsShowHowToModal] = useState(false);
const isInitialMount = useRef(true);
const showWelcomeModal = () => setIsShowWelcomeModal(true);
const onChangeSearch = value => setSearch(value);
const hideWelcomeModal = () => {
localStorage.setItem('welcome-modal-is-showing', true);
setIsShowWelcomeModal(false);
};
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
if (!localStorage.getItem('welcome-modal-is-showing') && !loading && !data.length)
showWelcomeModal();
}
}, [data]);
const fetchData = () => {
startAppProgress();
fetchList(user, completeAppProgress);
};
useEffect(() => {
fetchData();
return () => {
resetAppProgress();
};
}, [user]);
useEffect(() => {
setSearchPlaceholder(t('findStack'));
return () => setSearchPlaceholder(null);
}, []);
const showHowToModal = event => {
event.preventDefault();
setIsShowHowToModal(true);
};
const hideHowToModal = () => setIsShowHowToModal(false);
const deleteItem = () => {
deleteStack(deletingStack);
hideDeleteConfirmation();
};
const showDeleteConfirmation = name => setDeletingStack(name);
const hideDeleteConfirmation = () => setDeletingStack(null);
const getItems = () => {
let items = [];
if (data && data.length) {
if (search.length)
items = data.filter(i => i.name.indexOf(search) >= 0);
else
items = data;
}
return items;
};
const items = getItems();
if (requestStatus === 404)
return <NotFound>
{t('theStackYouAreRookingForCouldNotBeFound')}
{' '}
{isSignedIn() && (
<Fragment>
<Link to={routes.stacks(currentUser)}>
{t('goToMyStacks')}
</Link>.
</Fragment>
)}
</NotFound>;
return (
<div className={css.list}>
<Helmet>
<title>dstack.ai | {user}</title>
</Helmet>
<div className={css.title}>
{currentUser === user
? t('stacks')
: t('stacksOf', {name: user})
}
{currentUser === user && (
<Upload
withButton
className={css.upload}
refresh={fetchData}
/>
)}
</div>
{loading && !Boolean(data.length) && <Loader />}
{!loading && !data.length && (
<div className={css.message}>
{user === currentUser
? t('youHaveNoStacksYet')
: t('theUserHasNoStacksYetByName', {name: user})
}
</div>
)}
{!loading && !Boolean(data.length) && currentUser === user && (
<HowTo />
)}
{Boolean(data.length && items.length) && currentUser === user && (
<div className={css.text}>
{t('youHaveStacks', {count: data.length})}
{' '}
<a href="#" onClick={showHowToModal}>{t('seeHowToGuide')}</a>.
</div>
)}
{Boolean(data.length) && <SearchField
placeholder={t('search')}
className={css.search}
showEverything
size="small"
value={search}
onChange={onChangeSearch}
/>}
{Boolean(data.length && items.length) && <div className={css.grid}>
{items.map((item, index) => <Item
withLink
key={index}
data={item}
deleteAction={showDeleteConfirmation}
/>)}
</div>}
{Boolean(data.length && !items.length) && <div className={css.text}>
{t('noStacksAreFoundedMatchedTheSearchCriteria')}
</div>}
<Modal
isShow={Boolean(deletingStack)}
onClose={hideDeleteConfirmation}
size="confirmation"
title={t('deleteStack')}
className={css.modal}
>
<div className={css.description}>
{t('areYouSureYouWantToDelete', {name: deletingStack})}
</div>
<div className={css.buttons}>
<Button
variant="contained"
color="primary"
onClick={hideDeleteConfirmation}
className={css.button}
>{t('cancel')}</Button>
<Button
color="secondary"
variant="contained"
onClick={deleteItem}
className={css.button}
>{t('deleteStack')}</Button>
</div>
</Modal>
{currentUser === user && (
<Modal
isShow={isShowWelcomeModal}
onClose={hideWelcomeModal}
size="small"
title={`${t('welcomeToDStack')}?`}
className={css.modal}
>
<div className={css.description}>{t('yourEmailWasSuccessfullyConfirmed')}</div>
<div className={css.buttons}>
<Button
variant="contained"
color="primary"
onClick={hideWelcomeModal}
className={css.button}
>{t('getStarted')}</Button>
</div>
</Modal>
)}
<Modal
isShow={isShowHowToModal}
withCloseButton
onClose={hideHowToModal}
size="big"
title={t('howToConnectYourDataWithDStack')}
className={css.modal}
>
<HowTo modalMode />
</Modal>
</div>
);
}
Example #6
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
Header = ({
setSearch,
search,
searchPlaceholder,
logOut,
className,
userData,
match: {params},
history,
toggleMenu,
}: Props) => {
const {t} = useTranslation();
let user = '';
if (params && params.user)
user = params.user;
else if (userData && userData.user)
user = userData.user;
const onChangeSearch = value => setSearch(value);
const logOutHandle = () => {
logOut(() => history.push('/'));
};
const renderSearch = () => (
<SearchField
showEverything
isDark
placeholder={searchPlaceholder}
className={css.search}
size="small"
value={search}
onChange={onChangeSearch}
/>
);
return <div className={cx(css.header, className)}>
{isSignedIn() && <div className={cx(css.menu, 'mdi mdi-menu')} onClick={toggleMenu} />}
<Link to="/" className={css.logo}>
<img width="129" height="35" src={logo} alt="logo"/>
</Link>
<Switch>
<Route
path={routes.auth()}
render={() => (
<div className={css.title}>{t('stacks')}</div>
)}
/>
<Route
exact
path={routes.dashboards(user)}
render={renderSearch}
/>
<Route
path={routes.dashboardsDetails(user)}
render={() => (
<Link to={routes.dashboards(user)} className={css.back}>
<span className="mdi mdi-arrow-left" />
{userData && (userData.user === user)
? t('backToDashboards')
: t('backToDashboardsOf', {name: user})
}
</Link>
)}
/>
<Route
path={routes.stackDetails()}
render={() => (
<Link to={routes.stacks(user)} className={css.back}>
<span className="mdi mdi-arrow-left" />
{userData && (userData.user === user)
? t('backToMyStacks')
: t('backToStacksOF', {name: user})
}
</Link>
)}
/>
<Route
exact
path={routes.stacks(user)}
render={renderSearch}
/>
</Switch>
{userData && <div className={css.user}>
<Dropdown
items={[
{
title: t('signOut'),
onClick: logOutHandle,
},
]}
>
<Avatar className={css.avatar} name={userData.user} />
</Dropdown>
</div>}
</div>;
}
Example #7
Source File: index.js From dstack-server with Apache License 2.0 | 4 votes |
Sidebar = ({
className, currentUser, isShow, toggleMenu, userLoading,
fetchStacksList, startAppProgress, completeAppProgress,
}: Props) => {
const {t} = useTranslation();
const {path} = useRouteMatch();
const params = useParams();
const {pathname} = useLocation();
const sidebarRef = useRef(null);
useOnClickOutside(sidebarRef, () => isShow && toggleMenu());
const getMenuItemClick = item => () => {
if (isShow)
toggleMenu();
if (item.onClick)
item.onClick();
};
const refreshStacks = () => {
if (pathname === routes.stacks(params.user)) {
startAppProgress();
fetchStacksList(params.user, completeAppProgress);
}
};
const menuItems = [
{
to: routes.stacks(currentUser),
label: t('stacks'),
isActive: () => (
new RegExp(path).test(routes.stacks())
&& (!currentUser || (currentUser === params.user))
&& !new RegExp(path + '$').test(routes.dashboards())
),
onClick: refreshStacks,
},
{
to: routes.dashboards(currentUser),
label: t('dashboards'),
},
{
to: routes.settings(),
label: t('settings'),
},
];
return <div className={cx(css.sidebar, className, {show: isShow})} ref={sidebarRef}>
<div className={cx(css.close, 'mdi mdi-close')} onClick={toggleMenu} />
<div className={css.logo}>
<Link to="/">
<img width="129" height="35" src={logo} alt="logo"/>
</Link>
</div>
{isSignedIn() && !userLoading && <ul className={css.links}>
{menuItems.map((item, index) => (
<li key={index} className={css.item}>
<NavLink
onClick={getMenuItemClick(item)}
to={item.to}
activeClassName="active"
isActive={item.isActive}
>
<span className={css.label}>{item.label}</span>
{item.beta && <sub className={cx(css.sub, 'green-text')}>
{t('beta')}
</sub>}
</NavLink>
</li>
))}
<li className={css.item}>
<a
href={config.DOCS_URL}
target="_blank"
>
<span className={css.label}>{t('docs')}</span>
</a>
</li>
</ul>}
</div>;
}