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

chore(vendor): update @lightbase/internal-management #406

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion vendor/internal-management/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ Props:
- `tenantOrigin`: optional tenant origin, to send to tenant aware backends.

```tsx
// In pages/_tenants/[tenant]/_lightbase/[...management].tsx
// In pages/_tenants/[tenant]/_lightbase/[[...management]].tsx
// Or in app/%5Flightbase/[[...management]]/page.tsx
// ^ _ directories are not turned in to routes by default

"use client";

import { InternalManagement } from "@lightbase/internal-management";

Expand Down
18 changes: 10 additions & 8 deletions vendor/internal-management/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@
"main": "./src/index.tsx",
"dependencies": {
"@emotion/hash": "^0.9.1",
"@emotion/react": "11.11.0",
"@headlessui/react": "1.7.14",
"@tanstack/react-query": "4.29.5",
"axios": "1.4.0",
"jwt-decode": "3.1.2",
"@emotion/react": "11.11.3",
"@headlessui/react": "1.7.17",
"axios": "1.6.5",
"jwt-decode": "4.0.0",
"nookies": "^2.5.2",
"react-hook-form": "7.43.9",
"react-router-dom": "6.11.1",
"react-hook-form": "7.49.2",
"react-router-dom": "6.21.1",
"twind": "0.16.19"
},
"peerDependencies": {
"@tanstack/react-query": "*"
},
"files": [
"README.md",
"src"
],
"gitHead": "4dcfe0922a124f2c944f6dc24411c73dcdc2819b"
"gitHead": "4410a3e0201f455092576429e5e95e6ae20990b6"
}
2 changes: 1 addition & 1 deletion vendor/internal-management/src/auth/cookies.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import jwtDecode from "jwt-decode";
import { jwtDecode } from "jwt-decode";
import { destroyCookie, parseCookies, setCookie } from "nookies";
import type { AuthTokenPair } from "../generated/common/types";

Expand Down
2 changes: 1 addition & 1 deletion vendor/internal-management/src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const sizes = {

const variants = {
primary: "border-transparent text-white bg-blue-600 hover:bg-blue-700 focus:ring-blue-500",
default: "bg-gray-50",
default: "bg-gray-50 hover:bg-gray-100",
};

export type ButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Transition, Dialog, Portal } from "@headlessui/react";
import { Dialog, Portal, Transition } from "@headlessui/react";
import { Fragment } from "react";
import { useForm } from "react-hook-form";
import { tw } from "twind";
import Button from "../components/Button";
import type { ManagementFeatureFlagItem } from "../generated/common/types";
import { useManagementFeatureFlagUpdate } from "../generated/managementFeatureFlag/reactQueries";

export default function EditFeatureFlagModal({
export default function EditDescriptionFFModal({
show,
onClose,
flag,
Expand All @@ -15,7 +15,7 @@ export default function EditFeatureFlagModal({
onClose: () => void;
flag: ManagementFeatureFlagItem;
}) {
const { mutate, isLoading, error } = useManagementFeatureFlagUpdate(
const { mutate, status, error } = useManagementFeatureFlagUpdate(
{
onSuccess: () => {
onClose();
Expand Down Expand Up @@ -61,12 +61,13 @@ export default function EditFeatureFlagModal({
>
<Dialog.Panel
as="form"
data-testid="FeatureFlag.modal"
data-testid="DescriptionFeatureFlag.modal"
onSubmit={handleSubmit(({ description }) => {
mutate({
featureFlagId: flag.id,
description,
globalValue: flag.globalValue,
tenantValues: flag.tenantValues,
});
})}
className={tw`relative w-full transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:max-w-lg`}
Expand Down Expand Up @@ -111,10 +112,17 @@ export default function EditFeatureFlagModal({
</div>
</div>
<div className={tw`border-t px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6`}>
<Button data-testid="FeatureFlag.modal.submit" type="submit" isLoading={isLoading}>
<Button
data-testid="DescriptionFeatureFlag.modal.submit"
type="submit"
isLoading={
// Compatible between RQ4 & RQ5
["loading", "pending"].includes(status as string)
}
>
Save
</Button>
<Button variant="default" className="ml-2 lg:ml-0 lg:mr-2" onClick={onClose}>
<Button variant="default" className={tw`ml-2 lg:ml-0 lg:mr-2`} onClick={onClose}>
Cancel
</Button>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import { Dialog, Portal, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";
import { tw } from "twind";
import Button from "../components/Button";
import type { ManagementFeatureFlagItem } from "../generated/common/types";
import { useManagementFeatureFlagUpdate } from "../generated/managementFeatureFlag/reactQueries";

export default function EditTenantSettingsFFModal({
show,
onClose,
flag,
tenants,
}: {
show: boolean;
onClose: () => void;
flag: ManagementFeatureFlagItem;
tenants: string[];
}) {
const { mutate, status, error } = useManagementFeatureFlagUpdate(
{
onSuccess: () => {
onClose();
},
},
{ invalidateQueries: true },
);

const [tenantValues, setTenantValues] = useState({
...(flag.tenantValues ?? {}),
});

return (
<Portal>
<Transition.Root show={show} as={Fragment}>
<Dialog as="div" className={tw`relative z-10`} onClose={onClose}>
<Transition.Child
as={Fragment}
enter={tw`ease-out duration-300`}
enterFrom={tw`opacity-0`}
enterTo={tw`opacity-100`}
leave={tw`ease-in duration-200`}
leaveFrom={tw`opacity-100`}
leaveTo={tw`opacity-0`}
>
<div className={tw`fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity`} />
</Transition.Child>

<div className={tw`fixed inset-0 z-10 overflow-y-auto`}>
<div
className={tw`flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0`}
>
<Transition.Child
as={Fragment}
enter={tw`ease-out duration-300`}
enterFrom={tw`opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95`}
enterTo={tw`opacity-100 translate-y-0 sm:scale-100`}
leave={tw`ease-in duration-200`}
leaveFrom={tw`opacity-100 translate-y-0 sm:scale-100`}
leaveTo={tw`opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95`}
>
<Dialog.Panel
as="form"
data-testid="TenantSettingsFeatureFlag.modal"
onSubmit={e => {
e.preventDefault();
mutate({
featureFlagId: flag.id,
tenantValues,
globalValue: flag.globalValue,
description: flag.description,
});
}}
className={tw`relative w-full transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:max-w-lg`}
>
<div className={tw`bg-white`}>
<div className={tw`border-b bg-white p-4 shadow-sm`}>
<Dialog.Title className={tw`font-medium`}>Edit feature flag</Dialog.Title>
</div>
<div className={tw`p-4 sm:p-6`}>
<div className={tw`space-y-4`}>
{tenants.map((tenant, index) => (
<div key={`${flag.name}-${index}`} className={tw`group space-y-1`}>
<h3 className={tw`mb-2 font-semibold text-sm text-gray-900`}>{tenant}</h3>
<ul
className={tw`items-center w-full text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-lg sm:flex`}
>
<li className={tw`w-full border-b border-gray-200 sm:border-b-0 sm:border-r`}>
<div className={tw`flex items-center pl-3`}>
<input
id={`list-radio-${tenant}-${index}-global-value`}
type="radio"
name={`list-radio-${tenant}-${index}-global-value`}
checked={!tenantValues.hasOwnProperty(tenant)}
onClick={() => {
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
const { [tenant]: remove, ...rest } = tenantValues;
setTenantValues(rest);
}}
className={tw`w-4 h-4 text-blue-600 bg-gray-100 border-gray-300`}
/>
<label
htmlFor={`list-radio-${tenant}-${index}-global-value`}
className={tw`w-full py-3 ml-2 text-sm font-medium text-gray-900 select-none`}
>
Global value
</label>
</div>
</li>
<li className={tw`w-full border-b border-gray-200 sm:border-b-0 sm:border-r`}>
<div className={tw`flex items-center pl-3`}>
<input
id={`list-radio-${tenant}-${index}-enabled`}
type="radio"
name={`list-radio-${tenant}-${index}-enabled`}
checked={tenantValues.hasOwnProperty(tenant) && tenantValues[tenant]}
onClick={() => setTenantValues({ ...tenantValues, [tenant]: true })}
className={tw`w-4 h-4 text-blue-600 bg-gray-100 border-gray-300`}
/>
<label
htmlFor={`list-radio-${tenant}-${index}-enabled`}
className={tw`w-full py-3 ml-2 text-sm font-medium text-gray-900 select-none`}
>
Enabled
</label>
</div>
</li>
<li className={tw`w-full border-b border-gray-200 sm:border-b-0`}>
<div className={tw`flex items-center pl-3`}>
<input
id={`list-radio-${tenant}-${index}-disabled`}
type="radio"
name={`list-radio-${tenant}-${index}-disabled`}
checked={tenantValues.hasOwnProperty(tenant) && !tenantValues[tenant]}
onClick={() => setTenantValues({ ...tenantValues, [tenant]: false })}
className={tw`w-4 h-4 text-blue-600 bg-gray-100 border-gray-300`}
/>
<label
htmlFor={`list-radio-${tenant}-${index}-disabled`}
className={tw`w-full py-3 ml-2 text-sm font-medium text-gray-900 select-none`}
>
Disabled
</label>
</div>
</li>
</ul>
</div>
))}
{!!error && (
<div className={tw`rounded-md bg-red-50`}>
<p className={tw`p-4 text-sm font-medium text-red-800`} role="alert">
Something went wrong
</p>
{!!error.response?.data && (
<div
className={tw`max-h-[100px] overflow-y-auto p-4 shadow-inner`}
aria-hidden="true"
>
<pre className={tw`whitespace-pre-line text-sm text-red-800`}>
{JSON.stringify(error.response.data)}
</pre>
</div>
)}
</div>
)}
</div>
</div>
</div>
<div className={tw`border-t px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6`}>
<Button
data-testid="TenantSettingsFeatureFlag.modal.submit"
type="submit"
isLoading={
// Compatible between RQ4 & RQ5
["loading", "pending"].includes(status as string)
}
>
Save
</Button>
<Button
variant="default"
className={tw`ml-2 lg:ml-0 lg:mr-2`}
onClick={() => {
onClose();
}}
>
Cancel
</Button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
</Portal>
);
}
4 changes: 2 additions & 2 deletions vendor/internal-management/src/components/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FeatureFlags } from "../pages/FeatureFlags";
import { Login } from "../pages/Login";
import { TokenAuth } from "../pages/TokenAuth";

export function Router() {
export function Router({ tenants }: { tenants?: string[] }) {
const [isMounted, setIsMounted] = useState(false);

useEffect(() => {
Expand All @@ -19,7 +19,7 @@ export function Router() {
[
{
path: "/",
element: <FeatureFlags />,
element: <FeatureFlags tenants={tenants} />,
errorElement: <ErrorBoundary />,
},
{
Expand Down
4 changes: 2 additions & 2 deletions vendor/internal-management/src/components/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default function SideBar() {
to="/"
className={({ isActive }) =>
isActive
? tw`block bg-[#f1f1f1] py-3 px-6 text-sm font-medium text-gray-800`
: tw`block py-3 px-6 text-sm font-medium text-gray-600 hover:text-gray-800`
? tw`block bg-[#f1f1f1] px-6 py-3 text-sm font-medium text-gray-800`
: tw`block px-6 py-3 text-sm font-medium text-gray-600 hover:text-gray-800`
}
>
Feature flags
Expand Down
21 changes: 21 additions & 0 deletions vendor/internal-management/src/generated/auth/apiClient.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading