utils#parseSearch JavaScript Examples

The following examples show how to use utils#parseSearch. 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 6 votes vote down vote up
ConfirmEmail = ({fetchUser, loading, error, history, verifyUser, location}: Props) => {
    const {t} = useTranslation();

    useEffect(() => {
        const {user, code, next} = parseSearch(location.search);

        verifyUser({user, code}, () => {
            fetchUser(() => {
                if (next)
                    history.push(next);
                else
                    history.push('/');
            });
        });
    }, []);

    return (
        <div className={css.confirm}>
            {error && !loading && <div className={css.message}>
                <div className={css.text}>{error}</div>
                <Link to={routes.authLogin()}>{t('signIn')}</Link>
            </div>}

            {loading && <Loader />}
        </div>
    );
}
Example #2
Source File: index.js    From dstack-server with Apache License 2.0 4 votes vote down vote up
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>
    );
}