mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 07:05:24 +00:00
feat: hide installed plugins in the browse tab by default
This commit is contained in:
1 parent
11f4674bd2
commit
9c63d8d433
4 files changed
+53
-9
No files matched your search
@@ -14,6 +14,7 @@
|
|||||||
- Every language is now fully translated, in Termix and in every plugin, and stays up to date with each release
|
- Every language is now fully translated, in Termix and in every plugin, and stays up to date with each release
|
||||||
- Languages with more than two plural forms, like Russian, Polish and Arabic, now use the right one
|
- Languages with more than two plural forms, like Russian, Polish and Arabic, now use the right one
|
||||||
- The Plugins tab shows how many times each plugin was downloaded, in a Downloads column
|
- The Plugins tab shows how many times each plugin was downloaded, in a Downloads column
|
||||||
|
- Plugins, Browse hides plugins you already have. Turn on Show installed to see them
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -2085,6 +2085,9 @@
|
|||||||
"noneInstalled": "No plugins installed yet. Browse to add some.",
|
"noneInstalled": "No plugins installed yet. Browse to add some.",
|
||||||
"nothingHere": "Nothing here.",
|
"nothingHere": "Nothing here.",
|
||||||
"nothingHereHint": "Try another category or search.",
|
"nothingHereHint": "Try another category or search.",
|
||||||
|
"showInstalled": "Show installed",
|
||||||
|
"allInstalled": "Everything here is already installed.",
|
||||||
|
"allInstalledHint": "Turn on Show installed to see them.",
|
||||||
"communitySubmit": "How to submit",
|
"communitySubmit": "How to submit",
|
||||||
"registries": {
|
"registries": {
|
||||||
"intro": "Registries are lists of plugins you can install. The official one is always on. You can turn on the community registry or add your own.",
|
"intro": "Registries are lists of plugins you can install. The official one is always on. You can turn on the community registry or add your own.",
|
||||||
|
|||||||
@@ -952,6 +952,12 @@ function BrowseSection({
|
|||||||
const [category, setCategory] = useState<string | null>(null);
|
const [category, setCategory] = useState<string | null>(null);
|
||||||
const [registry, setRegistry] = useState<string | null>(null);
|
const [registry, setRegistry] = useState<string | null>(null);
|
||||||
const [sort, setSort] = useState<SortKey>("popular");
|
const [sort, setSort] = useState<SortKey>("popular");
|
||||||
|
const [installedChoice, setInstalledChoice] = useStoredChoice(
|
||||||
|
"pluginsTab.browseInstalled",
|
||||||
|
["hide", "show"],
|
||||||
|
"hide",
|
||||||
|
);
|
||||||
|
const showInstalled = installedChoice === "show";
|
||||||
const categories = useMemo(() => categoriesOf(plugins), [plugins]);
|
const categories = useMemo(() => categoriesOf(plugins), [plugins]);
|
||||||
const registries = manager.registries;
|
const registries = manager.registries;
|
||||||
const registryFilter = registries.some((entry) => entry.id === registry)
|
const registryFilter = registries.some((entry) => entry.id === registry)
|
||||||
@@ -961,6 +967,7 @@ function BrowseSection({
|
|||||||
const rows = sortPlugins(
|
const rows = sortPlugins(
|
||||||
plugins.filter(
|
plugins.filter(
|
||||||
(p) =>
|
(p) =>
|
||||||
|
(showInstalled || !p.installed) &&
|
||||||
matchesQuery(p, query) &&
|
matchesQuery(p, query) &&
|
||||||
(category === null || p.category === category) &&
|
(category === null || p.category === category) &&
|
||||||
(registryFilter === null || p.registryId === registryFilter),
|
(registryFilter === null || p.registryId === registryFilter),
|
||||||
@@ -968,6 +975,9 @@ function BrowseSection({
|
|||||||
sort,
|
sort,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const allInstalledHidden =
|
||||||
|
!showInstalled && plugins.length > 0 && plugins.every((p) => p.installed);
|
||||||
|
|
||||||
const listColumns: DataColumn<PluginEntry>[] = [
|
const listColumns: DataColumn<PluginEntry>[] = [
|
||||||
{
|
{
|
||||||
key: "name",
|
key: "name",
|
||||||
@@ -1029,6 +1039,15 @@ function BrowseSection({
|
|||||||
placeholder={t("plugins.manager.searchPlugins")}
|
placeholder={t("plugins.manager.searchPlugins")}
|
||||||
>
|
>
|
||||||
<div className="ml-auto flex items-center gap-2">
|
<div className="ml-auto flex items-center gap-2">
|
||||||
|
<label className="flex items-center gap-1.5">
|
||||||
|
<span className="text-xs text-muted-foreground">
|
||||||
|
{t("plugins.manager.showInstalled")}
|
||||||
|
</span>
|
||||||
|
<FakeSwitch
|
||||||
|
checked={showInstalled}
|
||||||
|
onChange={(v) => setInstalledChoice(v ? "show" : "hide")}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
{registries.length > 1 && (
|
{registries.length > 1 && (
|
||||||
<Select
|
<Select
|
||||||
value={registryFilter ?? "__all"}
|
value={registryFilter ?? "__all"}
|
||||||
@@ -1084,15 +1103,23 @@ function BrowseSection({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{rows.length === 0 ? (
|
{rows.length === 0 ? (
|
||||||
<EmptyState
|
allInstalledHidden ? (
|
||||||
icon={Puzzle}
|
<EmptyState
|
||||||
title={t("plugins.manager.nothingHere")}
|
icon={Puzzle}
|
||||||
hint={
|
title={t("plugins.manager.allInstalled")}
|
||||||
plugins.length === 0
|
hint={t("plugins.manager.allInstalledHint")}
|
||||||
? undefined
|
/>
|
||||||
: t("plugins.manager.nothingHereHint")
|
) : (
|
||||||
}
|
<EmptyState
|
||||||
/>
|
icon={Puzzle}
|
||||||
|
title={t("plugins.manager.nothingHere")}
|
||||||
|
hint={
|
||||||
|
plugins.length === 0
|
||||||
|
? undefined
|
||||||
|
: t("plugins.manager.nothingHereHint")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<PluginCollection
|
<PluginCollection
|
||||||
plugins={rows}
|
plugins={rows}
|
||||||
|
|||||||
@@ -73,6 +73,19 @@ describe("PluginsTab", () => {
|
|||||||
expect(link.getAttribute("href")).toBe(docsUrl("communityRegistry"));
|
expect(link.getAttribute("href")).toBe(docsUrl("communityRegistry"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("hides installed plugins in Browse until shown", async () => {
|
||||||
|
await renderTab();
|
||||||
|
fireEvent.click(screen.getByText(en.plugins.manager.tabs.browse));
|
||||||
|
|
||||||
|
expect(screen.queryByText("Demo Plugin")).toBeNull();
|
||||||
|
expect(screen.getByText(en.plugins.manager.allInstalled)).toBeTruthy();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole("switch"));
|
||||||
|
|
||||||
|
expect(screen.getByText("Demo Plugin")).toBeTruthy();
|
||||||
|
expect(localStorage.getItem("pluginsTab.browseInstalled")).toBe("show");
|
||||||
|
});
|
||||||
|
|
||||||
it("switches to a table and remembers it", async () => {
|
it("switches to a table and remembers it", async () => {
|
||||||
await renderTab();
|
await renderTab();
|
||||||
expect(screen.queryByRole("table")).toBeNull();
|
expect(screen.queryByRole("table")).toBeNull();
|
||||||
|
|||||||
Reference in new issue
Block a user