role menu WIP
This commit is contained in:
parent
33c0e362f5
commit
d6384af097
@ -20,7 +20,7 @@
|
|||||||
"react"
|
"react"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
// "@typescript-eslint/no-unused-vars": "warn",
|
"@typescript-eslint/no-unused-vars": "off",
|
||||||
"@typescript-eslint/no-var-requires":"off",
|
"@typescript-eslint/no-var-requires":"off",
|
||||||
"react/no-unescaped-entities": "warn",
|
"react/no-unescaped-entities": "warn",
|
||||||
"react/prop-types": "off",
|
"react/prop-types": "off",
|
||||||
|
9
src/@types/Components.ts
Normal file
9
src/@types/Components.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export type DropdownBaseProps = {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DropdownItemProps = {
|
||||||
|
type?: 'select' | 'multi-select',
|
||||||
|
selected?: boolean,
|
||||||
|
onChange?: React.ReactEventHandler
|
||||||
|
} & DropdownBaseProps
|
@ -1,4 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { Children, useRef, useState } from "react";
|
||||||
|
import ClickDetector from "../util/ClickDetector";
|
||||||
|
import { DropdownBaseProps, DropdownItemProps } from "../@types/Components";
|
||||||
|
|
||||||
export const FileSelector = ({ cb }: { cb: (file: File) => void }) => {
|
export const FileSelector = ({ cb }: { cb: (file: File) => void }) => {
|
||||||
|
|
||||||
@ -35,32 +37,82 @@ export const FileSelector = ({ cb }: { cb: (file: File) => void }) => {
|
|||||||
</label>;
|
</label>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DropdownProps = {
|
|
||||||
name?: string,
|
|
||||||
multi?: boolean,
|
|
||||||
selection?: [],
|
|
||||||
children: React.ReactNode
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DropdownMenu = (props: DropdownProps) => {
|
|
||||||
|
|
||||||
return <div>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
</div>;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ToggleSwitch = ({ value, onChange, ref, children }:
|
export const ToggleSwitch = ({ value, onChange, ref, children }:
|
||||||
{ value: boolean, ref?: React.RefObject<HTMLInputElement>, onChange?: React.ChangeEventHandler, children: string }) => {
|
{ value: boolean, ref?: React.RefObject<HTMLInputElement>, onChange?: React.ChangeEventHandler, children: string }) => {
|
||||||
return <p>
|
return <p>
|
||||||
<span className="check-box check-box-row">
|
<span className="check-box check-box-row">
|
||||||
<b>{children}:</b>
|
<b>{children}</b>
|
||||||
<input ref={ref} defaultChecked={value} onChange={onChange} type='checkbox' />
|
<input ref={ref} defaultChecked={value} onChange={onChange} type='checkbox' />
|
||||||
</span>
|
</span>
|
||||||
</p>;
|
</p>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const VerticalToggleSwitch = ({ value, onChange, ref, children }:
|
||||||
|
{ value: boolean, ref?: React.RefObject<HTMLInputElement>, onChange?: React.ChangeEventHandler, children: string }) => {
|
||||||
|
return <p>
|
||||||
|
<b>{children}</b>
|
||||||
|
<span className="check-box">
|
||||||
|
<input ref={ref} defaultChecked={value} onChange={onChange} type='checkbox' />
|
||||||
|
</span>
|
||||||
|
</p>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DropdownHeader = ({children}: DropdownBaseProps) => {
|
||||||
|
return <summary className='is-vertical-align'>
|
||||||
|
{children}
|
||||||
|
</summary>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DropdownItem = ({ children, type, selected, onChange }: DropdownItemProps) => {
|
||||||
|
if (type === 'multi-select')
|
||||||
|
return <ToggleSwitch value={selected || false} onChange={onChange}>
|
||||||
|
{children as string}
|
||||||
|
</ToggleSwitch>;
|
||||||
|
return <div>
|
||||||
|
{children}
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DropdownItemList = ({ children }: DropdownBaseProps) => {
|
||||||
|
return <div className='card'>
|
||||||
|
{children}
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DropdownProps = {
|
||||||
|
name?: string,
|
||||||
|
multi?: boolean,
|
||||||
|
selection?: [],
|
||||||
|
children: React.ReactNode[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const DropdownComp = ({children, ...props}: DropdownProps) => {
|
||||||
|
|
||||||
|
console.log(props);
|
||||||
|
console.log(children);
|
||||||
|
|
||||||
|
if (!children)
|
||||||
|
throw new Error('Missing children');
|
||||||
|
|
||||||
|
if (!children.some(element => element && (element as React.ReactElement).type === DropdownHeader))
|
||||||
|
throw new Error('Missing a header');
|
||||||
|
|
||||||
|
const detailsRef = useRef<HTMLDetailsElement>(null);
|
||||||
|
|
||||||
|
return <ClickDetector callback={() => {
|
||||||
|
if(detailsRef.current) detailsRef.current.open = false;
|
||||||
|
}}>
|
||||||
|
<details ref={detailsRef} className='dropdown'>
|
||||||
|
{children}
|
||||||
|
</details>
|
||||||
|
</ClickDetector>;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const Dropdown = Object.assign(DropdownComp, {
|
||||||
|
Header: DropdownHeader,
|
||||||
|
ItemList: DropdownItemList,
|
||||||
|
Item: DropdownItem
|
||||||
|
});
|
||||||
|
|
||||||
|
export { Dropdown };
|
@ -7,7 +7,7 @@ import { Table, TableListEntry } from "../../components/Table";
|
|||||||
import { BackButton, PageButtons } from "../../components/PageControls";
|
import { BackButton, PageButtons } from "../../components/PageControls";
|
||||||
import { Permissions } from "../../views/PermissionsView";
|
import { Permissions } from "../../views/PermissionsView";
|
||||||
import { Application as App, Permissions as Perms, User as APIUser, Role } from "../../@types/ApiStructures";
|
import { Application as App, Permissions as Perms, User as APIUser, Role } from "../../@types/ApiStructures";
|
||||||
import { DropdownMenu, ToggleSwitch } from "../../components/Selectors";
|
import { Dropdown, ToggleSwitch } from "../../components/Selectors";
|
||||||
|
|
||||||
const ApplicationList = ({ apps }: { apps: App[] }) => {
|
const ApplicationList = ({ apps }: { apps: App[] }) => {
|
||||||
|
|
||||||
@ -38,16 +38,39 @@ const Application = ({ app }: { app: App }) => {
|
|||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Roles = ({ userRoles, roles }: { userRoles: Role[], roles: Role[] }) => {
|
const RoleComp = ({ role }: {role: Role}) => {
|
||||||
console.log(roles);
|
return <div className='role'>
|
||||||
return <DropdownMenu>
|
{role.name}
|
||||||
{roles.map(role => {
|
|
||||||
return <div key={role.id}>
|
|
||||||
<label>{role.name}</label>
|
|
||||||
<input defaultChecked={Boolean(userRoles.find((r: Role) => r.id === role.id))} type='checkbox' />
|
|
||||||
</div>;
|
</div>;
|
||||||
})}
|
};
|
||||||
</DropdownMenu>;
|
|
||||||
|
const Roles = ({ userRoles, roles }: { userRoles: Role[], roles: Role[] }) => {
|
||||||
|
console.log(roles, userRoles);
|
||||||
|
const roleSelected = (role: Role, selected: boolean) => {
|
||||||
|
console.log(role, selected);
|
||||||
|
};
|
||||||
|
return <Dropdown>
|
||||||
|
|
||||||
|
<Dropdown.Header>
|
||||||
|
{userRoles.map(role => <RoleComp key={role.id} role={role} />)}
|
||||||
|
</Dropdown.Header>
|
||||||
|
|
||||||
|
<Dropdown.ItemList>
|
||||||
|
|
||||||
|
{roles.map(role => <Dropdown.Item
|
||||||
|
type='multi-select' key={role.id}
|
||||||
|
selected={userRoles.some(r => r.id === role.id)}
|
||||||
|
onChange={(event) => {
|
||||||
|
const elem = event.target as HTMLInputElement;
|
||||||
|
roleSelected(role, elem.checked);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{role.name}
|
||||||
|
</Dropdown.Item>)}
|
||||||
|
|
||||||
|
</Dropdown.ItemList>
|
||||||
|
|
||||||
|
</Dropdown>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const User = ({ user, roles }: { user: APIUser, roles: Role[] }) => {
|
const User = ({ user, roles }: { user: APIUser, roles: Role[] }) => {
|
||||||
@ -99,10 +122,9 @@ const User = ({ user, roles }: { user: APIUser, roles: Role[] }) => {
|
|||||||
<label>Roles</label>
|
<label>Roles</label>
|
||||||
<Roles userRoles={user.roles} roles={roles} />
|
<Roles userRoles={user.roles} roles={roles} />
|
||||||
|
|
||||||
|
{/* <button className="button primary">
|
||||||
<button className="button primary">
|
|
||||||
Save User
|
Save User
|
||||||
</button>
|
</button> */}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user