mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	refactor: application-view to ApplicationView with useApplication hook
This commit is contained in:
		
							parent
							
								
									7344f47635
								
							
						
					
					
						commit
						38e549d879
					
				@ -1,6 +1,5 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { useContext } from 'react';
 | 
			
		||||
import { Link, useParams } from 'react-router-dom';
 | 
			
		||||
import {
 | 
			
		||||
    Grid,
 | 
			
		||||
    List,
 | 
			
		||||
@ -9,8 +8,13 @@ import {
 | 
			
		||||
    ListItemAvatar,
 | 
			
		||||
    Typography,
 | 
			
		||||
} from '@material-ui/core';
 | 
			
		||||
import { Report, Extension, Timeline, FlagRounded } from '@material-ui/icons';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
    Report,
 | 
			
		||||
    Extension,
 | 
			
		||||
    Timeline,
 | 
			
		||||
    FlagRounded,
 | 
			
		||||
    SvgIconComponent,
 | 
			
		||||
} from '@material-ui/icons';
 | 
			
		||||
import { shorten } from '../common';
 | 
			
		||||
import {
 | 
			
		||||
    CREATE_FEATURE,
 | 
			
		||||
@ -18,21 +22,30 @@ import {
 | 
			
		||||
} from '../providers/AccessProvider/permissions';
 | 
			
		||||
import ConditionallyRender from '../common/ConditionallyRender/ConditionallyRender';
 | 
			
		||||
import { getTogglePath } from '../../utils/route-path-helpers';
 | 
			
		||||
function ApplicationView({
 | 
			
		||||
    seenToggles,
 | 
			
		||||
    hasAccess,
 | 
			
		||||
    strategies,
 | 
			
		||||
    instances,
 | 
			
		||||
    formatFullDateTime,
 | 
			
		||||
}) {
 | 
			
		||||
    const notFoundListItem = ({ createUrl, name, permission }) => (
 | 
			
		||||
import useApplication from '../../hooks/api/getters/useApplication/useApplication';
 | 
			
		||||
import AccessContext from '../../contexts/AccessContext';
 | 
			
		||||
import { formatFullDateTimeWithLocale } from '../common/util';
 | 
			
		||||
const ApplicationView = () => {
 | 
			
		||||
    const { hasAccess } = useContext(AccessContext);
 | 
			
		||||
    const { name } = useParams<{ name: string }>();
 | 
			
		||||
    const { application } = useApplication(name);
 | 
			
		||||
    const { instances, strategies, seenToggles } = application;
 | 
			
		||||
    const notFoundListItem = ({
 | 
			
		||||
        createUrl,
 | 
			
		||||
        name,
 | 
			
		||||
        permission,
 | 
			
		||||
    }: {
 | 
			
		||||
        createUrl: string;
 | 
			
		||||
        name: string;
 | 
			
		||||
        permission: string;
 | 
			
		||||
    }) => (
 | 
			
		||||
        <ConditionallyRender
 | 
			
		||||
            key={`not_found_conditional_${name}`}
 | 
			
		||||
            condition={hasAccess(permission)}
 | 
			
		||||
            show={
 | 
			
		||||
                <ListItem key={`not_found_${name}`}>
 | 
			
		||||
                    <ListItemAvatar>
 | 
			
		||||
                        <Report style={{color: 'red'}} />
 | 
			
		||||
                        <Report style={{ color: 'red' }} />
 | 
			
		||||
                    </ListItemAvatar>
 | 
			
		||||
                    <ListItemText
 | 
			
		||||
                        primary={<Link to={`${createUrl}`}>{name}</Link>}
 | 
			
		||||
@ -54,13 +67,18 @@ function ApplicationView({
 | 
			
		||||
        />
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line react/prop-types
 | 
			
		||||
    const foundListItem = ({
 | 
			
		||||
        viewUrl,
 | 
			
		||||
        name,
 | 
			
		||||
        description,
 | 
			
		||||
        Icon,
 | 
			
		||||
        i,
 | 
			
		||||
    }: {
 | 
			
		||||
        viewUrl: string;
 | 
			
		||||
        name: string;
 | 
			
		||||
        description: string;
 | 
			
		||||
        Icon: SvgIconComponent;
 | 
			
		||||
        i: number;
 | 
			
		||||
    }) => (
 | 
			
		||||
        <ListItem key={`found_${name}-${i}`}>
 | 
			
		||||
            <ListItemAvatar>
 | 
			
		||||
@ -83,10 +101,7 @@ function ApplicationView({
 | 
			
		||||
                <hr />
 | 
			
		||||
                <List>
 | 
			
		||||
                    {seenToggles.map(
 | 
			
		||||
                        (
 | 
			
		||||
                            { name, description, notFound, project },
 | 
			
		||||
                            i
 | 
			
		||||
                        ) => (
 | 
			
		||||
                        ({ name, description, notFound, project }, i) => (
 | 
			
		||||
                            <ConditionallyRender
 | 
			
		||||
                                key={`toggle_conditional_${name}`}
 | 
			
		||||
                                condition={notFound}
 | 
			
		||||
@ -97,7 +112,7 @@ function ApplicationView({
 | 
			
		||||
                                    i,
 | 
			
		||||
                                })}
 | 
			
		||||
                                elseShow={foundListItem({
 | 
			
		||||
                                    viewUrl: getTogglePath(project, name),
 | 
			
		||||
                                    viewUrl: getTogglePath(project, name, true),
 | 
			
		||||
                                    name,
 | 
			
		||||
                                    description,
 | 
			
		||||
                                    Icon: FlagRounded,
 | 
			
		||||
@ -143,7 +158,17 @@ function ApplicationView({
 | 
			
		||||
                <hr />
 | 
			
		||||
                <List>
 | 
			
		||||
                    {instances.map(
 | 
			
		||||
                        ({ instanceId, clientIp, lastSeen, sdkVersion }) => (
 | 
			
		||||
                        ({
 | 
			
		||||
                            instanceId,
 | 
			
		||||
                            clientIp,
 | 
			
		||||
                            lastSeen,
 | 
			
		||||
                            sdkVersion,
 | 
			
		||||
                        }: {
 | 
			
		||||
                            instanceId: string;
 | 
			
		||||
                            clientIp: string;
 | 
			
		||||
                            lastSeen: string;
 | 
			
		||||
                            sdkVersion: string;
 | 
			
		||||
                        }) => (
 | 
			
		||||
                            <ListItem key={`${instanceId}`}>
 | 
			
		||||
                                <ListItemAvatar>
 | 
			
		||||
                                    <Timeline />
 | 
			
		||||
@ -152,16 +177,18 @@ function ApplicationView({
 | 
			
		||||
                                    primary={
 | 
			
		||||
                                        <ConditionallyRender
 | 
			
		||||
                                            key={`${instanceId}_conditional`}
 | 
			
		||||
                                            condition={sdkVersion}
 | 
			
		||||
                                            show={`${instanceId} (${sdkVersion})`}
 | 
			
		||||
                                            elseShow={instanceId}
 | 
			
		||||
                                            condition={Boolean(sdkVersion)}
 | 
			
		||||
                                            show={<span>{instanceId} {(sdkVersion)}</span>}
 | 
			
		||||
                                            elseShow={<span>{instanceId}</span>}
 | 
			
		||||
                                        />
 | 
			
		||||
                                    }
 | 
			
		||||
                                    secondary={
 | 
			
		||||
                                        <span>
 | 
			
		||||
                                            {clientIp} last seen at{' '}
 | 
			
		||||
                                            <small>
 | 
			
		||||
                                                {formatFullDateTime(lastSeen)}
 | 
			
		||||
                                                {formatFullDateTimeWithLocale(
 | 
			
		||||
                                                    lastSeen
 | 
			
		||||
                                                )}
 | 
			
		||||
                                            </small>
 | 
			
		||||
                                        </span>
 | 
			
		||||
                                    }
 | 
			
		||||
@ -173,17 +200,6 @@ function ApplicationView({
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </Grid>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ApplicationView.propTypes = {
 | 
			
		||||
    createUrl: PropTypes.string,
 | 
			
		||||
    name: PropTypes.string,
 | 
			
		||||
    permission: PropTypes.string,
 | 
			
		||||
    instances: PropTypes.array.isRequired,
 | 
			
		||||
    seenToggles: PropTypes.array.isRequired,
 | 
			
		||||
    strategies: PropTypes.array.isRequired,
 | 
			
		||||
    hasAccess: PropTypes.func.isRequired,
 | 
			
		||||
    formatFullDateTime: PropTypes.func.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ApplicationView;
 | 
			
		||||
@ -19,7 +19,7 @@ import {
 | 
			
		||||
    formatDateWithLocale,
 | 
			
		||||
} from '../common/util';
 | 
			
		||||
import { UPDATE_APPLICATION } from '../providers/AccessProvider/permissions';
 | 
			
		||||
import ApplicationView from './application-view';
 | 
			
		||||
import ApplicationView from './ApplicationView';
 | 
			
		||||
import ApplicationUpdate from './application-update';
 | 
			
		||||
import TabNav from '../common/TabNav/TabNav';
 | 
			
		||||
import Dialogue from '../common/Dialogue';
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
import useSWR, { mutate, SWRConfiguration } from 'swr';
 | 
			
		||||
import { useState, useEffect } from 'react';
 | 
			
		||||
import { formatApiPath } from '../../../../utils/format-path';
 | 
			
		||||
import handleErrorResponses from '../httpErrorResponseHandler';
 | 
			
		||||
 | 
			
		||||
const useApplication = (name: string, options: SWRConfiguration = {}) => {
 | 
			
		||||
    const fetcher = async () => {
 | 
			
		||||
        const path = formatApiPath(`api/admin/metrics/applications/${name}`);
 | 
			
		||||
        return fetch(path, {
 | 
			
		||||
            method: 'GET',
 | 
			
		||||
        })
 | 
			
		||||
            .then(handleErrorResponses('Application'))
 | 
			
		||||
            .then(res => res.json());
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const FEATURE_CACHE_KEY = `api/admin/metrics/applications/${name}`;
 | 
			
		||||
 | 
			
		||||
    const { data, error } = useSWR(FEATURE_CACHE_KEY, fetcher, {
 | 
			
		||||
        ...options,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const [loading, setLoading] = useState(!error && !data);
 | 
			
		||||
 | 
			
		||||
    const refetchApplication = () => {
 | 
			
		||||
        mutate(FEATURE_CACHE_KEY);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        setLoading(!error && !data);
 | 
			
		||||
    }, [data, error]);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        application: data || {
 | 
			
		||||
            appName: name,
 | 
			
		||||
            color: null,
 | 
			
		||||
            createdAt: '2022-02-02T21:04:00.268Z',
 | 
			
		||||
            descriotion: '',
 | 
			
		||||
            instances: [],
 | 
			
		||||
            strategies: [],
 | 
			
		||||
            seenToggles: [],
 | 
			
		||||
            url: '',
 | 
			
		||||
        },
 | 
			
		||||
        error,
 | 
			
		||||
        loading,
 | 
			
		||||
        refetchApplication,
 | 
			
		||||
        FEATURE_CACHE_KEY,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default useApplication;
 | 
			
		||||
@ -0,0 +1,41 @@
 | 
			
		||||
import useSWR, { mutate, SWRConfiguration } from 'swr';
 | 
			
		||||
import { useState, useEffect } from 'react';
 | 
			
		||||
import { formatApiPath } from '../../../../utils/format-path';
 | 
			
		||||
import handleErrorResponses from '../httpErrorResponseHandler';
 | 
			
		||||
 | 
			
		||||
const useApplications = (options: SWRConfiguration = {}) => {
 | 
			
		||||
    const fetcher = async () => {
 | 
			
		||||
        const path = formatApiPath('api/admin/metrics/applications');
 | 
			
		||||
        return fetch(path, {
 | 
			
		||||
            method: 'GET',
 | 
			
		||||
        })
 | 
			
		||||
            .then(handleErrorResponses('Context data'))
 | 
			
		||||
            .then(res => res.json());
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const FEATURE_CACHE_KEY = 'api/admin/metrics/applications';
 | 
			
		||||
 | 
			
		||||
    const { data, error } = useSWR(FEATURE_CACHE_KEY, fetcher, {
 | 
			
		||||
        ...options,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const [loading, setLoading] = useState(!error && !data);
 | 
			
		||||
 | 
			
		||||
    const refetchApplications = () => {
 | 
			
		||||
        mutate(FEATURE_CACHE_KEY);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        setLoading(!error && !data);
 | 
			
		||||
    }, [data, error]);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        applications: data?.applications || {},
 | 
			
		||||
        error,
 | 
			
		||||
        loading,
 | 
			
		||||
        refetchApplications,
 | 
			
		||||
        FEATURE_CACHE_KEY,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default useApplications;
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user