Skip to content

Commit

Permalink
Merge pull request #1188 from Chia-Network/refactor/glossary-page
Browse files Browse the repository at this point in the history
Refactor/glossary page
  • Loading branch information
MichaelTaylor3D authored Apr 2, 2024
2 parents ae1bb48 + 44df937 commit 87061fc
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 26 deletions.
20 changes: 19 additions & 1 deletion src/renderer/components/blocks/layout/LeftNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ const LeftNav = () => {
>
<FormattedMessage id={'projects-list'} />
</div>
<div
onClick={() => handleNavigation(ROUTES.UNITS_LIST)}
className={`cursor-pointer p-3 ${isActive(ROUTES.UNITS_LIST) ? 'bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-white' : 'text-gray-700 dark:text-gray-300'} hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md text-lg font-semibold`}
>
<FormattedMessage id={'units-list'} />
</div>
<div
onClick={() => handleNavigation(ROUTES.AUDIT)}
className={`cursor-pointer p-3 ${isActive(ROUTES.AUDIT) ? 'bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-white' : 'text-gray-700 dark:text-gray-300'} hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md text-lg font-semibold`}
>
<FormattedMessage id={'audit'} />
</div>
<div
onClick={() => handleNavigation(ROUTES.GLOSSARY)}
className={`cursor-pointer p-3 ${isActive(ROUTES.GLOSSARY) ? 'bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-white' : 'text-gray-700 dark:text-gray-300'} hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md text-lg font-semibold`}
>
<FormattedMessage id={'glossary'} />
</div>
{/* Additional mobile navigation items here */}
</div>

Expand Down Expand Up @@ -69,7 +87,7 @@ const LeftNav = () => {
active={isActive(ROUTES.AUDIT)}
onClick={() => navigate(ROUTES.AUDIT)}
>
<FormattedMessage id="audits" />
<FormattedMessage id="audit" />
</Sidebar.Item>
<Sidebar.Item
style={{ cursor: 'pointer' }}
Expand Down
67 changes: 67 additions & 0 deletions src/renderer/components/blocks/widgets/OrgUidBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useState, useEffect } from 'react';
import { Toast, Tooltip } from 'flowbite-react';

interface OrgUidBadgeProps {
orgUid: string;
}

const OrgUidBadge: React.FC<OrgUidBadgeProps> = ({ orgUid }) => {
const [showToast, setShowToast] = useState(false);
const [toastVisible, setToastVisible] = useState(false);
const [toastMessage, setToastMessage] = useState('');

useEffect(() => {
let timeoutId: NodeJS.Timeout;

if (showToast) {
setToastVisible(true);
timeoutId = setTimeout(() => setShowToast(false), 3000);
} else if (!showToast && toastVisible) {
timeoutId = setTimeout(() => setToastVisible(false), 300);
}

return () => clearTimeout(timeoutId);
}, [showToast, toastVisible]);

const handleCopyToClipboard = () => {
navigator.clipboard
.writeText(orgUid)
.then(() => {
setToastMessage('Org UID copied to clipboard!');
setShowToast(true);
})
.catch((err) => {
console.error('Failed to copy Org UID: ', err);
setToastMessage('Failed to copy Org UID.');
setShowToast(true);
});
};

if (!orgUid) {
return null;
}

return (
<>
{toastVisible && (
<div
className={`absolute top-0 right-0 p-4 transition-opacity duration-300 ${showToast ? 'opacity-100' : 'opacity-0'}`}
>
<Toast className="bg-gray-900 text-white border border-gray-700">
<span className="font-medium">{toastMessage}</span>
</Toast>
</div>
)}
<Tooltip content="Click to copy Organization ID">
<span
onClick={handleCopyToClipboard}
className="cursor-pointer p-2 bg-gray-50 text-gray-700 text-xs font-mono rounded flex items-center"
>
{orgUid}
</span>
</Tooltip>
</>
);
};

export { OrgUidBadge };
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { Dropdown, SyncIndicator } from '@/components';
interface OrganizationSelectorProps {
onSelect: (organization: any | undefined) => void;
defaultOrgUid: string | undefined;
noSelectionLabel?: string
}

const OrganizationSelector: React.FC<OrganizationSelectorProps> = ({ onSelect, defaultOrgUid }) => {
const OrganizationSelector: React.FC<OrganizationSelectorProps> = ({ onSelect, defaultOrgUid, noSelectionLabel = 'Select Organization' }) => {
const { data: organizations, error, isLoading } = useGetOrganizationsListQuery({});
const [selectedOrganization, setSelectedOrganization] = useState<any | undefined>(undefined);

Expand Down Expand Up @@ -36,7 +37,7 @@ const OrganizationSelector: React.FC<OrganizationSelectorProps> = ({ onSelect, d
};

return (
<Dropdown label={selectedOrganization ? selectedOrganization.name : 'All Organizations'} inline={true}>
<Dropdown label={selectedOrganization ? selectedOrganization.name : noSelectionLabel} inline={true}>
<Dropdown.Item onClick={() => handleSelect(undefined)}>All Organizations</Dropdown.Item>
{organizations.map((organization) => (
<Dropdown.Item
Expand Down
9 changes: 4 additions & 5 deletions src/renderer/components/blocks/widgets/SyncIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,19 @@ const SyncIndicator: React.FC<SyncIndicatorProps> = ({ detailed, orgUid }) => {
}

return (
<div className={`flex items-center space-x-2 ${detailed ? 'p-2 rounded-lg shadow bg-white dark:bg-gray-800' : ''}`}>
<div className={`grid grid-cols-[auto_1fr] items-center gap-x-2 ${detailed ? 'p-2 rounded-lg shadow bg-white dark:bg-gray-800' : ''}`}>
<div className={`${isSynced ? 'bg-green-500' : 'animate-pulse bg-yellow-500'} h-4 w-4 rounded-full`}></div>
{detailed && (
<>
<div className="flex flex-col text-left">
<span className={`text-sm ${isSynced ? 'text-green-700' : 'text-yellow-600'}`}>
{isSynced ? 'Synced' : 'Syncing...'}
</span>
{!isSynced && (
// Made "sync remaining" more subtle with lighter color and smaller font
<span className="text-xs text-yellow-400">
({syncRemaining} remaining)
{syncRemaining} remaining
</span>
)}
</>
</div>
)}
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/components/blocks/widgets/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './SearchBox';
export * from './OrganizationSelector';
export * from './SyncIndicator';
export * from './SyncIndicator';
export * from './OrgUidBadge';
2 changes: 2 additions & 0 deletions src/renderer/pages/Audit/AuditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
SkeletonTable,
AuditsTable,
SearchBox,
SyncIndicator
} from '@/components';
import {FormattedMessage} from "react-intl";

Expand Down Expand Up @@ -92,6 +93,7 @@ const AuditPage: React.FC = () => {
<div className="flex flex-col md:flex-row gap-6 pl-1 my-2.5 relative z-30">
<SearchBox defaultValue={search} onChange={handleSearchChange}/>
<OrganizationSelector onSelect={handleOrganizationSelected} defaultOrgUid={orgUid}/>
<SyncIndicator detailed={true} orgUid={orgUid} />
</div>
<>
{auditLoading ? (
Expand Down
22 changes: 14 additions & 8 deletions src/renderer/pages/ProjectsList/ProjectsListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React, { useCallback } from 'react';
import { useGetProjectsQuery } from '@/api';
import { useQueryParamState, useColumnOrderHandler } from '@/hooks';
import {debounce, DebouncedFunc} from 'lodash';
import { debounce, DebouncedFunc } from 'lodash';
import {
OrganizationSelector,
IndeterminateProgressOverlay,
SkeletonTable,
ProjectsListTable,
SearchBox,
SyncIndicator
SyncIndicator,
OrgUidBadge,
} from '@/components';
import {FormattedMessage} from "react-intl";
import { FormattedMessage } from 'react-intl';

const ProjectsListPage: React.FC = () => {
const [currentPage, setCurrentPage] = useQueryParamState('page', '1');
Expand Down Expand Up @@ -50,20 +51,25 @@ const ProjectsListPage: React.FC = () => {
}

if (projectsError) {
return <FormattedMessage id={"unable-to-load-contents"}/>;
return <FormattedMessage id={'unable-to-load-contents'} />;
}

if (!projectsData){
return <FormattedMessage id={"no-records-found"}/>;
if (!projectsData) {
return <FormattedMessage id={'no-records-found'} />;
}

return (
<>
{projectsFetching && <IndeterminateProgressOverlay />}
<div className="flex flex-col md:flex-row gap-6 pl-1 my-2.5 relative z-30">
<div className="flex flex-col lg:flex-row gap-6 pl-1 my-2.5 relative z-30">
<SearchBox defaultValue={search} onChange={handleSearchChange} />
<OrganizationSelector onSelect={handleOrganizationSelected} defaultOrgUid={orgUid} />
<OrganizationSelector
onSelect={handleOrganizationSelected}
defaultOrgUid={orgUid}
noSelectionLabel="All Organizations"
/>
<SyncIndicator detailed={true} orgUid={orgUid} />
<OrgUidBadge orgUid={orgUid} />
</div>

{projectsLoading ? (
Expand Down
20 changes: 13 additions & 7 deletions src/renderer/pages/UnitsList/UnitsListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React, { useCallback } from 'react';
import { useGetUnitsQuery } from '@/api';
import { useQueryParamState, useColumnOrderHandler } from '@/hooks';
import {debounce, DebouncedFunc} from 'lodash';
import { debounce, DebouncedFunc } from 'lodash';
import {
OrganizationSelector,
IndeterminateProgressOverlay,
SkeletonTable,
SearchBox,
UnitsListTable,
SyncIndicator
SyncIndicator,
OrgUidBadge,
} from '@/components';
import {FormattedMessage} from "react-intl";
import { FormattedMessage } from 'react-intl';

const UnitsListPage: React.FC = () => {
const [currentPage, setCurrentPage] = useQueryParamState('page', '1');
Expand Down Expand Up @@ -50,20 +51,25 @@ const UnitsListPage: React.FC = () => {
}

if (unitsError) {
return <FormattedMessage id={"unable-to-load-contents"}/>;
return <FormattedMessage id={'unable-to-load-contents'} />;
}

if (!unitsData){
return <FormattedMessage id={"no-records-found"}/>;
if (!unitsData) {
return <FormattedMessage id={'no-records-found'} />;
}

return (
<>
{unitsFetching && <IndeterminateProgressOverlay />}
<div className="flex flex-col md:flex-row gap-6 pl-1 my-2.5 relative z-30">
<SearchBox defaultValue={search} onChange={handleSearchChange} />
<OrganizationSelector onSelect={handleOrganizationSelected} defaultOrgUid={orgUid} />
<OrganizationSelector
onSelect={handleOrganizationSelected}
defaultOrgUid={orgUid}
noSelectionLabel="All Organizations"
/>
<SyncIndicator detailed={true} orgUid={orgUid} />
<OrgUidBadge orgUid={orgUid} />
</div>

{unitsLoading ? (
Expand Down
1 change: 1 addition & 0 deletions src/renderer/routes/AppNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const AppNavigator: React.FC = () => {
<Route path="/" element={<Navigate to={ROUTES.PROJECTS_LIST} />} />
<Route path={ROUTES.PROJECTS_LIST} element={<Pages.ProjectsListPage />} />
<Route path={ROUTES.UNITS_LIST} element={<Pages.UnitsListPage />} />
<Route path={ROUTES.AUDIT} element={<Pages.AuditPage />} />
<Route path={ROUTES.GLOSSARY} element={<Pages.GlossaryPage />} />
<Route path="*" element={<Navigate replace to={ROUTES.PROJECTS_LIST} />} />
</Route>
Expand Down
3 changes: 1 addition & 2 deletions src/renderer/translations/tokens/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@
"covered-by-ndc": "Covered By Ndc",
"project-status": "Project Status",
"unit-metric": "Unit Metric",
"validation-body": "Validation Body",
"table": "Table",
"timestamp": "Timestamp",
"type": "Type",
"root-hash": "Root Hash",
"author": "Author",
"comment": "Comment",
"please-select-an-organization-to-view-audit-data": "Please select an organization to view audit data",
"audits": "Audits",
"audit": "Audit",
"validation-body": "Validation Body",
"glossary": "Glossary",
"term": "Term",
Expand Down

0 comments on commit 87061fc

Please sign in to comment.