Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/cascader #313

Open
wants to merge 52 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
26e12a4
create cascader context and childsMenu component with adding a mock d…
aymanesarrar Feb 14, 2024
01bdc0e
wip: rendering children
aymanesarrar Feb 15, 2024
a175e3b
wip(menu): stacking menus with each other
aymanesarrar Feb 15, 2024
b167f9d
refactor cascader item into a single component
aymanesarrar Feb 16, 2024
2c26b3e
handling checkbox and radios
aymanesarrar Feb 16, 2024
aac99a5
add radio to the cascaderItem component
aymanesarrar Feb 16, 2024
9732451
opening childMenus when clicking an item
aymanesarrar Feb 16, 2024
52ecac9
toggling menu when mouseenter an item
aymanesarrar Feb 16, 2024
f086ad5
calling toggleMenu only when there is children
aymanesarrar Feb 16, 2024
c641ce5
fix open nested menus
aymanesarrar Feb 17, 2024
49a8695
remove unused vars and comments
aymanesarrar Feb 17, 2024
057c45d
handing parent menu
aymanesarrar Feb 18, 2024
4778889
fix radio group problem and passing parent name to every child
aymanesarrar Feb 18, 2024
ee415e9
using click to open menu (wip)
aymanesarrar Feb 19, 2024
db0e197
handling number of checked items
aymanesarrar Feb 19, 2024
12f88c3
fix cascader, fix open and close cascader
aymanesarrar Feb 22, 2024
c1e4f36
fix closing cascader, rendering cascader and remove sidebar, fix imag…
aymanesarrar Feb 23, 2024
a02e130
add filters icon and fix cascader positioning, with adding filter ico…
aymanesarrar Feb 23, 2024
6c5ae7b
adding box shadow
aymanesarrar Feb 23, 2024
57f1017
introducing a new way of handling selected items on the menu
aymanesarrar Feb 23, 2024
ca315e4
handle radio
aymanesarrar Feb 23, 2024
575fba9
fix number of selected items
aymanesarrar Feb 23, 2024
1395323
displaying current selected radio item
aymanesarrar Feb 23, 2024
0015f89
fix handling Radio
aymanesarrar Feb 23, 2024
b3f0d15
handle platform change
aymanesarrar Feb 23, 2024
1d95bc8
handle radio initial value
aymanesarrar Feb 23, 2024
616b5cd
fix dynamic data
aymanesarrar Feb 24, 2024
a7de6be
add versions filter
aymanesarrar Feb 26, 2024
5833b0a
add modloaders filters
aymanesarrar Feb 26, 2024
505cdeb
categories filter
aymanesarrar Feb 26, 2024
6aa441f
fix categories filter
aymanesarrar Feb 26, 2024
27bd1d5
remove logs, comments, unused vars
aymanesarrar Feb 26, 2024
8945202
add instances to the menu
aymanesarrar Feb 27, 2024
ef0b7e3
categories, modloader, gameversions filters for mods
aymanesarrar Feb 27, 2024
e29185b
instances filter
aymanesarrar Feb 27, 2024
5c3b2b8
remove search from parent menu
aymanesarrar Feb 27, 2024
c2b1893
fix instance seletion radio when selection an item with the same label
aymanesarrar Feb 28, 2024
89ad300
fix: add nested categories
aymanesarrar Mar 15, 2024
e800860
fix curseforge filters
aymanesarrar Mar 15, 2024
73d530e
remove logs, comments
aymanesarrar Mar 15, 2024
bdcc2e9
fix lint
aymanesarrar Mar 15, 2024
8fc207a
making all categories checkboxes
aymanesarrar Mar 25, 2024
b56bf61
fix checked item
aymanesarrar Mar 25, 2024
7024620
fix z index
aymanesarrar Mar 26, 2024
a896fe2
wip
aymanesarrar Mar 26, 2024
2f08949
wip
aymanesarrar Mar 27, 2024
7dc0ec5
fix modloaders
aymanesarrar Mar 27, 2024
cfb7889
fix platform bug
aymanesarrar Mar 27, 2024
da988b0
fix lint
aymanesarrar Mar 27, 2024
bcdf4ac
wip
aymanesarrar Mar 28, 2024
e3e4d09
fix infinite call
aymanesarrar Mar 28, 2024
f503a00
Merge branch 'develop' into feat/cascader
blarfoon Apr 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
406 changes: 208 additions & 198 deletions apps/desktop/packages/mainWindow/src/components/Sidebar/modpacks.tsx

Large diffs are not rendered by default.

652 changes: 377 additions & 275 deletions apps/desktop/packages/mainWindow/src/components/Sidebar/mods.tsx

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions apps/desktop/packages/mainWindow/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import App from "@/app";
import { ModalProvider } from "@/managers/ModalsManager";
import "virtual:uno.css";
import "@gd/ui/style.css";
import { ContextMenuProvider, NotificationsProvider } from "@gd/ui";
import { NotificationsProvider, ContextMenuProvider } from "@gd/ui";
import { NavigationManager } from "./managers/NavigationManager";
import { ContextCascaderProvider } from "@gd/ui";
// import { ContextMenuProvider } from "./components/ContextMenu/ContextMenuContext";
import RiveAppWapper from "./utils/RiveAppWrapper";
import GDAnimation from "./gd_logo_animation.riv";
Expand Down Expand Up @@ -195,11 +196,15 @@ const TransWrapper = (props: TransWrapperProps) => {
<TransProvider instance={_i18nInstance}>
<Router source={hashIntegration()}>
<NavigationManager>
<ContextMenuProvider>
<ModalProvider>
<App createInvalidateQuery={props.createInvalidateQuery} />
</ModalProvider>
</ContextMenuProvider>
<NotificationsProvider>
<ContextCascaderProvider>
<ContextMenuProvider>
<ModalProvider>
<App createInvalidateQuery={props.createInvalidateQuery} />
</ModalProvider>
</ContextMenuProvider>
</ContextCascaderProvider>
</NotificationsProvider>
</NavigationManager>
</Router>
</TransProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
NoMoreModpacks
} from "./ModpacksStatus";
import { useInfiniteModsQuery } from "@/components/InfiniteScrollModsQueryWrapper";
import Sidebar from "@/components/Sidebar/modpacks";

const ModpackBrowser = () => {
const [t] = useTransContext();
Expand Down Expand Up @@ -97,6 +98,7 @@ const ModpackBrowser = () => {
</Match>
<Match when={hasFiltersData()}>
<div class="flex items-center justify-between gap-3 pb-4 flex-wrap">
<Sidebar />
<Input
placeholder="Type Here"
value={infiniteQuery?.query.searchQuery || ""}
Expand Down
19 changes: 8 additions & 11 deletions apps/desktop/packages/mainWindow/src/pages/Modpacks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import Sidebar from "@/components/Sidebar/modpacks";
import { Outlet } from "@solidjs/router";
import ContentWrapper from "@/components/ModpackBrowserWrapper";
import InfiniteScrollModsLayout from "@/components/InfiniteScrollModsQueryWrapper";

function ModpacksLayout() {
return (
<div class="flex w-full h-full">
<InfiniteScrollModsLayout type="modPack">
<>
<Sidebar />
<ContentWrapper>
<Outlet />
</ContentWrapper>
</>
</InfiniteScrollModsLayout>
</div>
<InfiniteScrollModsLayout type="modPack">
<>
{/* <Sidebar /> */}
<ContentWrapper>
<Outlet />
</ContentWrapper>
</>
</InfiniteScrollModsLayout>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import DefaultImg from "/assets/images/default-instance-img.png";
import { useGDNavigate } from "@/managers/NavigationManager";
import { getInstanceImageUrl } from "@/utils/instances";
import { setInstanceId, instanceId as _instanceId } from "@/utils/browser";
import Sidebar from "@/components/Sidebar/mods";

const ModsBrowser = () => {
const [t] = useTransContext();
Expand Down Expand Up @@ -186,6 +187,7 @@ const ModsBrowser = () => {
</div>
</Show>
<div class="flex items-center justify-between gap-3 flex-wrap pb-4">
<Sidebar />
<Input
placeholder={t("mods.search_mods")}
icon={<div class="i-ri:search-line" />}
Expand Down
19 changes: 8 additions & 11 deletions apps/desktop/packages/mainWindow/src/pages/Mods/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import Sidebar from "@/components/Sidebar/mods";
import { Outlet } from "@solidjs/router";
import ContentWrapper from "@/components/ModpackBrowserWrapper";
import InfiniteScrollModsLayout from "@/components/InfiniteScrollModsQueryWrapper";

function ModpacksLayout() {
return (
<div class="flex w-full h-full">
<InfiniteScrollModsLayout type="mod">
<>
<Sidebar />
<ContentWrapper>
<Outlet />
</ContentWrapper>
</>
</InfiniteScrollModsLayout>
</div>
<InfiniteScrollModsLayout type="mod">
<>
{/* <Sidebar /> */}
<ContentWrapper>
<Outlet />
</ContentWrapper>
</>
</InfiniteScrollModsLayout>
);
}

Expand Down
12 changes: 9 additions & 3 deletions apps/desktop/packages/mainWindow/src/utils/instances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ export const getInactiveState = (status: LaunchState | undefined) => {
return status.value.failed_task;
}
};

export const getValideInstance = (
status: ListInstanceStatus
): ValidListInstance | undefined => {
if (status.status === "valid") return status.value;
};
export const isSubTaskDownload = (input: FESubtask): input is FESubtask => {
return typeof input === "object" && "download" in input;
};
Expand Down Expand Up @@ -158,8 +162,10 @@ export const CategoryIcon = (props: {
);
};

export const PlatformIcon = (props: { modpack: "curseforge" | "modrinth" }) => {
return <img class="h-4 w-4" src={getModpackPlatformIcon(props.modpack)} />;
export const PlatformIcon = (props: {
platform: "curseforge" | "modrinth";
}) => {
return <img class="h-4 w-4" src={getModpackPlatformIcon(props.platform)} />;
};

export const [importedInstances, setImportedInstances] = createSignal<number[]>(
Expand Down
1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@unocss/eslint-config": "^0.53.1",
"@unocss/transformer-directives": "^0.55.0",
"babel-loader": "^9.1.2",
"class-variance-authority": "^0.7.0",
"concurrently": "^8.2.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0",
Expand Down
44 changes: 44 additions & 0 deletions packages/ui/src/Cascader/CascaderContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
Accessor,
createContext,
createSignal,
JSX,
useContext,
} from "solid-js";

type ContextCascaderContextValue = {
openCascader: Accessor<HTMLElement | null>;
setOpenCascader: (_target: HTMLElement | null) => void;
closeCascader: () => void;
};

const ContextCascaderContext = createContext<ContextCascaderContextValue>();

type ContextCascaderProviderProps = {
children: JSX.Element;
};

const ContextCascaderProvider = (props: ContextCascaderProviderProps) => {
const [openCascader, setOpenCascader] = createSignal<HTMLElement | null>(
null
);

const closeCascader = () => {
setOpenCascader(null);
};
const value = { openCascader, setOpenCascader, closeCascader };

return (
<ContextCascaderContext.Provider value={value}>
{props.children}
</ContextCascaderContext.Provider>
);
};

const useContextCascader = () => {
return useContext(ContextCascaderContext);
};

export { ContextCascaderProvider, useContextCascader };

export const Exported = 5;
171 changes: 171 additions & 0 deletions packages/ui/src/Cascader/CascaderItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import { Accessor, Setter, Show, createEffect, createSignal } from "solid-js";
import { Checkbox } from "../Checkbox";
import ChildsMenu, { ChildsMenuProps } from "./ChildsMenu";
import { Radio } from "../Radio";
import _ from "lodash";

const CascaderItem = (props: {
label: string;
children?: ChildsMenuProps;
name?: string;
value?: string;
isCheckbox?: boolean;
isOpen: boolean;
isParent: boolean;
onToggleMenu: () => void;
img?: any;
id?: string | number;
selectedItems: Accessor<string[]>;
setSelectedItems: Setter<string[]>;
parentLabel?: string;
items: {
label: string;
img: any;
id?: string | number;
children?: ChildsMenuProps;
}[];
}) => {
const [numberOfCheckedItems, setNumberOfCheckedItems] = createSignal(0);
const [currentSelectedItem, setCurrentSelectedItem] = createSignal("None");

createEffect(() => {
if (props.children?.isCheckbox) {
setNumberOfCheckedItems(
props
.selectedItems()
.filter((item) =>
item?.includes(props.children?.parentLabel as string)
).length
);
}
});
const handleRadio = (val: string | number | string[] | undefined) => {
props.setSelectedItems((prev) => {

Check warning on line 43 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / windows_x64

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored

Check warning on line 43 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / mac_universal

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored

Check warning on line 43 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / ubuntu_x64

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored
const newItems = [...prev];
const index = newItems.findIndex((item) =>
item.includes(props.parentLabel as string)
);
let newValue = "";
const findElement = props.items.find(
(item) => item.id === val || item.label === val
);
if (findElement) {
newValue = `${props.parentLabel}//${findElement.label}`;
} else {
newValue = `${props.parentLabel}//${val}`;
}

if (index === -1) {
newItems.push(newValue);
} else {
newItems[index] = newValue;
}

return newItems;
});
};
createEffect(() => {
if (props.children) {
const index = props
.selectedItems()
.findIndex((item) =>
item.includes(props.children?.parentLabel as string)
);
if (index === -1) {
setCurrentSelectedItem("None");
} else {
setCurrentSelectedItem(
props.selectedItems()[index].split("//")[1] || "None"
);
}
}
});
return (
<div
class="w-full flex justify-between p-2 items-center hover:bg-[#1D2028]"
onMouseEnter={() => props.children && props.onToggleMenu()}
>
<Show when={!props.isCheckbox && props.isParent}>
<div>
<span class="text-white">{props.label}</span>
</div>
</Show>
<Show when={props.isCheckbox && !props.isParent}>
<Checkbox
onChange={() => {
if (
props.selectedItems().filter((item) => item.includes(props.label))
.length > 0
) {
props.setSelectedItems((prev) =>

Check warning on line 100 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / windows_x64

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored

Check warning on line 100 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / mac_universal

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored

Check warning on line 100 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / ubuntu_x64

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored
prev.filter((item) => !item.includes(props.label))
);
} else {
props.setSelectedItems((prev) => [

Check warning on line 104 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / windows_x64

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored

Check warning on line 104 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / mac_universal

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored

Check warning on line 104 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / ubuntu_x64

This function should be passed to a tracked scope (like createEffect) or an event handler because it contains reactivity, or else changes will be ignored
...prev,
props.parentLabel + "//" + props.label,
]);
}
}}
checked={
props
.selectedItems()
.filter((item) => item.split("//")[1] === props.label).length > 0
}
children={
<div class="flex items-center gap-2">
{props.img && props.img}
<span class="text-[#8A8B8F]">{props.label}</span>
</div>
}
/>
</Show>
<Show when={!props.isCheckbox && !props.isParent}>
<Radio
onChange={handleRadio}
checked={
props
.selectedItems()
.filter((item) => item.split("//")[1] === props.label).length > 0
}
value={props.id || props.label}
children={
<div class="flex items-center gap-2">
{props.img && props.img}
<span class="text-[#8A8B8F]">{props.label}</span>
</div>
}
/>
</Show>
<Show when={props.children && props.isOpen}>
<ChildsMenu
items={props.children!.items}
hasSearch={props.children!.hasSearch}
isCheckbox={props.children!.isCheckbox}
isParent={props.children!.isParent}
parentLabel={props.children!.parentLabel}
selectedItems={props.selectedItems}
setSelectedItems={props.setSelectedItems}
hasChildren={props.children!.hasChildren}
/>
</Show>

<div class="flex items-center">
<Show
when={props.isParent && props.children && !props.children.isCheckbox}
>
<span class="text-[#8A8B8F]">{currentSelectedItem()}</span>
</Show>
<Show when={props.children && props.children.isCheckbox}>
<span class="text-[#8A8B8F]">
{numberOfCheckedItems()}/{props.children?.items.length}
</span>
</Show>
<Show when={props.children}>
<div class="text-[#8A8B8F] i-ri-arrow-right-s-line"></div>

Check warning on line 165 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / windows_x64

Empty components are self-closing

Check warning on line 165 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / mac_universal

Empty components are self-closing

Check warning on line 165 in packages/ui/src/Cascader/CascaderItem.tsx

View workflow job for this annotation

GitHub Actions / ubuntu_x64

Empty components are self-closing
</Show>
</div>
</div>
);
};
export default CascaderItem;
Loading
Loading