diff --git a/resources/src/App.tsx b/resources/src/App.tsx
index d15d9ca..970128e 100644
--- a/resources/src/App.tsx
+++ b/resources/src/App.tsx
@@ -6,6 +6,7 @@ import { AppLoader } from './AppLoader'
import { ErrorMessage } from './ErrorMessage'
import { AppFooter } from './AppFooter'
import { IconActions } from './IconActions'
+import { SelectHighlights } from './IconActionHighlight'
import 'inter-ui/inter.css'
import './App.css'
@@ -26,7 +27,11 @@ const GeistApp = () => {
tldr translation progress
- } error={}>
+ }
+ error={}
+ selection={}
+ >
diff --git a/resources/src/Data.tsx b/resources/src/Data.tsx
index e85c102..cddf7c0 100644
--- a/resources/src/Data.tsx
+++ b/resources/src/Data.tsx
@@ -1,4 +1,11 @@
-import { ReactElement, createContext, useEffect, useState, PropsWithChildren } from 'react'
+import {
+ createContext,
+ PropsWithChildren,
+ ReactElement,
+ useEffect,
+ useState,
+ useTransition,
+} from 'react'
// https://reactjs.org/docs/faq-ajax.html
// https://reactjs.org/docs/hooks-reference.html#usecontext
@@ -32,13 +39,21 @@ const DataContext = createContext<{
error: string | null
highlighted: Set
setHighlighted: (languages: Language[]) => void
-}>({ data: null, error: null, highlighted: new Set(), setHighlighted: () => {} })
-
-const DataFetcher = (props: PropsWithChildren<{ error: ReactElement; loading: ReactElement }>) => {
+}>({
+ data: null,
+ error: null,
+ highlighted: new Set(['en']),
+ setHighlighted: () => {},
+})
+
+const DataFetcher = (
+ props: PropsWithChildren<{ error: ReactElement; loading: ReactElement; selection: ReactElement }>,
+) => {
const [error, setError] = useState(null)
const [isLoaded, setIsLoaded] = useState(false)
const [data, setData] = useState(null)
- const [highlighted, setHighlighted] = useState>(new Set())
+ const [highlighted, setHighlighted] = useState>(new Set(['en']))
+ const [isPending, startTransition] = useTransition()
const webStorageHighlightedKey = 'language-highlighted'
// Fetch the data.json file
@@ -53,12 +68,16 @@ const DataFetcher = (props: PropsWithChildren<{ error: ReactElement; loading: Re
})
.then(
(result) => {
- setData(result as TranslationData)
- setIsLoaded(true)
+ startTransition(() => {
+ setData(result as TranslationData)
+ setIsLoaded(true)
+ })
},
(error) => {
- setError(error.toString())
- setIsLoaded(true)
+ startTransition(() => {
+ setError(error.toString())
+ setIsLoaded(true)
+ })
},
)
}, [])
@@ -68,14 +87,16 @@ const DataFetcher = (props: PropsWithChildren<{ error: ReactElement; loading: Re
useEffect(() => {
const stored = localStorage.getItem(webStorageHighlightedKey)
if (stored) {
- setHighlighted(new Set(JSON.parse(stored)))
+ let languages: Set = new Set(JSON.parse(stored))
+ languages.add('en')
+ startTransition(() => setHighlighted(new Set(languages)))
}
}, [])
const setHighlightedExternal = (languages: Language[]) => {
// Convert the array to a set for better performance and broadcast the change
// See: https://stackoverflow.com/a/57277566/4106848
- setHighlighted(new Set(languages))
+ startTransition(() => setHighlighted(new Set(languages)))
// Persist the user selection of highlighted columns
localStorage.setItem(webStorageHighlightedKey, JSON.stringify(Array.from(languages)))
}
@@ -90,7 +111,7 @@ const DataFetcher = (props: PropsWithChildren<{ error: ReactElement; loading: Re
return {props.error}
}
- if (!isLoaded) {
+ if (!isLoaded || isPending) {
return props.loading
}
@@ -100,7 +121,11 @@ const DataFetcher = (props: PropsWithChildren<{ error: ReactElement; loading: Re
highlighted: highlighted,
setHighlighted: setHighlightedExternal,
}
- return {props.children}
+ return (
+
+ {highlighted.size < 2 ? props.selection : props.children}
+
+ )
}
export { DataFetcher, DataContext, TranslationStatus }
diff --git a/resources/src/IconActionHighlight.tsx b/resources/src/IconActionHighlight.tsx
index 44a05ed..f3bd3e8 100644
--- a/resources/src/IconActionHighlight.tsx
+++ b/resources/src/IconActionHighlight.tsx
@@ -1,6 +1,6 @@
-import { useContext, useState, useEffect } from 'react'
-import { Checkbox, Grid, Modal, Tooltip, useModal } from '@geist-ui/core'
-import { Bookmark } from '@geist-ui/icons'
+import { useContext, useState } from 'react'
+import { Button, Checkbox, Grid, Modal, Text, Tooltip, useModal } from '@geist-ui/core'
+import { MessageCircle, Save } from '@geist-ui/icons'
import { useEscClose } from './useEscClose'
import { DataContext, Language } from './Data'
@@ -12,7 +12,9 @@ const HighlightCheckboxes = (props: {
const checkboxes = data!.languages.map((language) => (
- {language}
+
+ {language}
+
))
@@ -25,6 +27,28 @@ const HighlightCheckboxes = (props: {
)
}
+const SelectHighlights = (props: {}) => {
+ // Columns which are being highlighted
+ const { highlighted, setHighlighted } = useContext(DataContext)
+ // We only want to apply the highlight selection once it has been confirmed, so we create a temporary store
+ const [tmpHighlighted, setTmpHighlighted] = useState(Array.from(highlighted))
+
+ return (
+ <>
+ Select languages to show
+
+ setTmpHighlighted(selected)}
+ />
+
+ } onClick={() => setHighlighted(tmpHighlighted)}>
+ Continue
+
+ >
+ )
+}
+
const IconActionHighlight = (props: { side?: boolean }) => {
const { visible, setVisible, bindings } = useModal()
useEscClose(visible, setVisible)
@@ -33,23 +57,13 @@ const IconActionHighlight = (props: { side?: boolean }) => {
const { highlighted, setHighlighted } = useContext(DataContext)
// We only want to apply the highlight selection once it has been confirmed, so we create a temporary store
const [tmpHighlighted, setTmpHighlighted] = useState(Array.from(highlighted))
- // An extra state to begin saving the selection and applying it to the table
- const [saving, setSaving] = useState(false)
-
- useEffect(() => {
- if (saving) {
- setHighlighted(tmpHighlighted)
- setVisible(false)
- setSaving(false)
- }
- }, [saving, setHighlighted, setVisible, tmpHighlighted])
const placement = props.side ? 'left' : 'top'
return (
<>
-
-
+ {
@@ -60,8 +74,8 @@ const IconActionHighlight = (props: { side?: boolean }) => {
/>
- Highlight columns
- Choose columns to highlight
+ Select Languages
+ Choose languages to display
{
{
- setSaving(true)
+ setVisible(false)
+ setHighlighted(tmpHighlighted)
}}
- loading={saving}
>
Save
@@ -89,4 +103,4 @@ const IconActionHighlight = (props: { side?: boolean }) => {
)
}
-export { IconActionHighlight }
+export { IconActionHighlight, SelectHighlights }
diff --git a/resources/src/Table.tsx b/resources/src/Table.tsx
index f3f7358..f0d794a 100644
--- a/resources/src/Table.tsx
+++ b/resources/src/Table.tsx
@@ -15,21 +15,20 @@ const DataTableHeader = () => {
// We're applying the sticky class to each , because Chrome does not support sticky on and
// https://bugs.chromium.org/p/chromium/issues/detail?id=702927
- const languageRows = data?.languages.map((lang) => {
- let classNames = 'vertical-padding sticky bg-white-transparent'
- if (lang.length > 3) {
- classNames += ' small-font'
- }
- if (highlighted.has(lang)) {
- classNames += ' highlighted'
- }
+ const languageRows = data?.languages
+ .filter((lang) => highlighted.has(lang))
+ .map((lang) => {
+ let classNames = 'vertical-padding sticky bg-white-transparent'
+ if (lang.length > 3) {
+ classNames += ' small-font'
+ }
- return (
-
- {lang}
- |
- )
- })
+ return (
+
+ {lang}
+ |
+ )
+ })
return (
@@ -58,19 +57,17 @@ const DataTableOSHeader = (props: { os: OperatingSystem }) => {
const { data, highlighted } = useContext(DataContext)
const osProgress = data!.entries[props.os].progress
- const percentages = data!.languages.map((lang) => {
- let classNames = 'vertical-padding small-font'
+ const percentages = data!.languages
+ .filter((lang) => highlighted.has(lang))
+ .map((lang) => {
+ let classNames = 'vertical-padding small-font'
- if (highlighted.has(lang)) {
- classNames += ' highlighted'
- }
-
- return (
-
- {osProgress[lang]}%
- |
- )
- })
+ return (
+
+ {osProgress[lang]}%
+ |
+ )
+ })
return (
@@ -105,41 +102,39 @@ const DataTableOSPageRow = (props: { os: OperatingSystem; pageName: string }) =>
}
// Pick symbols from: https://rsms.me/inter/#charset
- const cells = data!.languages.map((lang) => {
- let classNames = 'cursor-pointer'
- let onClick = null
- let symbol = '?'
-
- if (lang in pageData.status) {
- const status = pageData.status[lang]
- switch (status) {
- case TranslationStatus.Translated:
- classNames += ' background-green'
- onClick = () => handleClick(FileAction.View, lang)
- symbol = '✓'
- break
- case TranslationStatus.Outdated:
- classNames += ' background-yellow'
- onClick = () => handleClick(FileAction.View, lang)
- symbol = '◇'
- break
+ const cells = data!.languages
+ .filter((lang) => highlighted.has(lang))
+ .map((lang) => {
+ let classNames = 'cursor-pointer'
+ let onClick = null
+ let symbol = '?'
+
+ if (lang in pageData.status) {
+ const status = pageData.status[lang]
+ switch (status) {
+ case TranslationStatus.Translated:
+ classNames += ' background-green'
+ onClick = () => handleClick(FileAction.View, lang)
+ symbol = '✓'
+ break
+ case TranslationStatus.Outdated:
+ classNames += ' background-yellow'
+ onClick = () => handleClick(FileAction.View, lang)
+ symbol = '◇'
+ break
+ }
+ } else {
+ classNames += ' background-red'
+ onClick = () => handleClick(FileAction.Create, lang)
+ symbol = '✗'
}
- } else {
- classNames += ' background-red'
- onClick = () => handleClick(FileAction.Create, lang)
- symbol = '✗'
- }
-
- if (highlighted.has(lang)) {
- classNames += ' highlighted'
- }
- return (
-
- {symbol}
- |
- )
- })
+ return (
+
+ {symbol}
+ |
+ )
+ })
return (
|