Skip to content

Commit

Permalink
feat: Rules tab (#2176)
Browse files Browse the repository at this point in the history
  • Loading branch information
markphelps authored Sep 29, 2023
1 parent 195ec9e commit f0a8d8c
Show file tree
Hide file tree
Showing 16 changed files with 121 additions and 146 deletions.
10 changes: 5 additions & 5 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { useSelector } from 'react-redux';
import { createHashRouter, RouterProvider } from 'react-router-dom';
import { SWRConfig } from 'swr';
import ErrorLayout from './app/ErrorLayout';
import EditFlag from './app/flags/EditFlag';
import Evaluation from './app/flags/Evaluation';
import Flag from './app/flags/Flag';
import NewFlag from './app/flags/NewFlag';
import Layout from './app/Layout';
Expand All @@ -19,6 +17,8 @@ import SessionProvider from './components/SessionProvider';
import { request } from './data/api';
import { Theme } from './types/Preferences';
const Flags = loadable(() => import('./app/flags/Flags'));
const Variants = loadable(() => import('./app/flags/variants/Variants'));
const Rules = loadable(() => import('./app/flags/rules/Rules'));
const Segments = loadable(() => import('./app/segments/Segments'));
const Console = loadable(() => import('./app/console/Console'));
const Login = loadable(() => import('./app/auth/Login'));
Expand Down Expand Up @@ -53,11 +53,11 @@ const namespacesRoutes = [
children: [
{
path: '',
element: <EditFlag />
element: <Variants />
},
{
path: 'evaluation',
element: <Evaluation />
path: 'rules',
element: <Rules />
}
]
},
Expand Down
8 changes: 4 additions & 4 deletions ui/src/app/Support.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function Support() {
className="text-white bg-violet-500 mb-1 inline-flex items-center justify-center rounded-md border border-transparent px-4 py-2 text-sm font-medium shadow-sm hover:bg-violet-600 hover:cursor-pointer focus:outline-none focus:ring-1 focus:ring-violet-500 focus:ring-offset-1"
target="_blank"
rel="noreferrer"
href="https://www.flipt.io/docs/"
href="https://www.flipt.io/docs?utm_source=app"
>
<span>Documentation</span>
<ArrowUpRightIcon
Expand Down Expand Up @@ -50,7 +50,7 @@ export default function Support() {
</div>
<div className="mt-4 flex grow items-end sm:mt-0">
<a
className="border-gray-200 rounded-md border px-2 py-1 hover:border-gray-300 hover:shadow-sm hover:shadow-gray-400 sm:px-3 sm:py-2"
className="border-gray-200 rounded-md border px-2 py-1 hover:border-gray-300 hover:shadow-sm hover:shadow-violet-300 sm:px-3 sm:py-2"
href="https://github.com/flipt-io/flipt/issues/new/choose"
>
<span className="text-gray-700 text-sm">
Expand All @@ -73,7 +73,7 @@ export default function Support() {
</div>
<div className="mt-4 flex grow items-end sm:mt-0">
<a
className="border-gray-200 rounded-md border px-2 py-1 hover:border-gray-300 hover:shadow-sm hover:shadow-gray-400 sm:px-3 sm:py-2"
className="border-gray-200 rounded-md border px-2 py-1 hover:border-gray-300 hover:shadow-sm hover:shadow-violet-300 sm:px-3 sm:py-2"
href="mailto:[email protected]?subject=Slack Connect Request&body=Hi there! I'd like to request a Slack Connect channel for our team."
>
<span className="text-gray-700 text-sm">
Expand All @@ -96,7 +96,7 @@ export default function Support() {
</div>
<div className="mt-4 flex grow items-end sm:mt-0">
<a
className="border-gray-200 rounded-md border px-2 py-1 hover:border-gray-300 hover:shadow-sm hover:shadow-gray-400 sm:px-3 sm:py-2"
className="border-gray-200 rounded-md border px-2 py-1 hover:border-gray-300 hover:shadow-sm hover:shadow-violet-300 sm:px-3 sm:py-2"
href="mailto:[email protected]?subject=Support Inquiry"
>
<span className="text-gray-700 text-sm">Send Email</span>
Expand Down
42 changes: 0 additions & 42 deletions ui/src/app/flags/EditFlag.tsx

This file was deleted.

78 changes: 62 additions & 16 deletions ui/src/app/flags/Flag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,26 @@ import {
import { formatDistanceToNowStrict, parseISO } from 'date-fns';
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { Outlet, useNavigate, useParams } from 'react-router-dom';
import { NavLink, Outlet, useNavigate, useParams } from 'react-router-dom';
import { selectReadonly } from '~/app/meta/metaSlice';
import {
selectCurrentNamespace,
selectNamespaces
} from '~/app/namespaces/namespacesSlice';
import FlagForm from '~/components/flags/FlagForm';
import Dropdown from '~/components/forms/Dropdown';
import Loading from '~/components/Loading';
import Modal from '~/components/Modal';
import MoreInfo from '~/components/MoreInfo';
import CopyToNamespacePanel from '~/components/panels/CopyToNamespacePanel';
import DeletePanel from '~/components/panels/DeletePanel';
import TabBar from '~/components/TabBar';
import { copyFlag, deleteFlag, getFlag } from '~/data/api';
import { useError } from '~/data/hooks/error';
import { useSuccess } from '~/data/hooks/success';
import { useTimezone } from '~/data/hooks/timezone';
import { FlagType, IFlag } from '~/types/Flag';
import { classNames } from '~/utils/helpers';
import Rollouts from './rollouts/Rollouts';

export default function Flag() {
let { flagKey } = useParams();
Expand All @@ -47,6 +50,11 @@ export default function Flag() {
setFlagVersion(flagVersion + 1);
};

const tabs = [
{ name: 'Variants', to: '' },
{ name: 'Rules', to: 'rules' }
];

useEffect(() => {
if (!flagKey) return;

Expand All @@ -62,18 +70,6 @@ export default function Flag() {

if (!flag) return <Loading />;

const tabs = [
{
name: 'Details',
to: ''
},
{
name: 'Evaluation',
to: 'evaluation',
disabled: flag.type === FlagType.BOOLEAN
}
];

return (
<>
{/* flag delete modal */}
Expand Down Expand Up @@ -169,8 +165,58 @@ export default function Flag() {
/>
</div>
</div>
<TabBar tabs={tabs} />
<Outlet context={{ flag, onFlagChange: incrementFlagVersion }} />

<div className="flex flex-col">
{/* flag details */}
<div className="my-5">
<div className="md:grid md:grid-cols-3 md:gap-6">
<div className="md:col-span-1">
<p className="text-gray-500 mt-1 text-sm">
Basic information about the flag and its status.
</p>
<MoreInfo
className="mt-5"
href="https://www.flipt.io/docs/concepts#flags"
>
Learn more about flags
</MoreInfo>
</div>
<div className="mt-5 md:col-span-2 md:mt-0">
<FlagForm flag={flag} flagChanged={incrementFlagVersion} />
</div>
</div>
</div>

{flag.type === FlagType.VARIANT && (
<>
<div className="mt-3 flex flex-row sm:mt-5">
<div className="border-gray-200 border-b-2">
<nav className="-mb-px flex space-x-8">
{tabs.map((tab) => (
<NavLink
end
key={tab.name}
to={tab.to}
className={({ isActive }) =>
classNames(
isActive
? 'text-violet-600 border-violet-500'
: 'text-gray-600 border-transparent hover:text-gray-700 hover:border-gray-300',
'whitespace-nowrap border-b-2 px-1 py-2 font-medium'
)
}
>
{tab.name}
</NavLink>
))}
</nav>
</div>
</div>
<Outlet context={{ flag, incrementFlagVersion }} />
</>
)}
{flag.type === FlagType.BOOLEAN && <Rollouts flag={flag} />}
</div>
</>
);
}
3 changes: 0 additions & 3 deletions ui/src/app/flags/NewFlag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ export default function NewFlag() {
<div className="my-10">
<div className="md:grid md:grid-cols-3 md:gap-6">
<div className="md:col-span-1">
<h3 className="text-gray-900 text-lg font-medium leading-6">
Details
</h3>
<p className="text-gray-500 mt-2 text-sm">
Basic information about the flag and its status.
</p>
Expand Down
13 changes: 3 additions & 10 deletions ui/src/app/flags/rollouts/Rollouts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import {
sortableKeyboardCoordinates,
verticalListSortingStrategy
} from '@dnd-kit/sortable';
import {
InformationCircleIcon,
PlusIcon,
StarIcon
} from '@heroicons/react/24/outline';
import { PlusIcon, StarIcon } from '@heroicons/react/24/outline';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { selectReadonly } from '~/app/meta/metaSlice';
Expand Down Expand Up @@ -249,9 +245,7 @@ export default function Rollouts(props: RolloutsProps) {
<div className="mt-10">
<div className="sm:flex sm:items-center">
<div className="sm:flex-auto">
<h1 className="text-gray-900 text-lg font-medium leading-6">
Rollouts
</h1>
<h3 className="text-gray-900 font-medium leading-6">Rollouts</h3>
<p className="text-gray-500 mt-1 text-sm">
Return boolean values based on rules you define
</p>
Expand Down Expand Up @@ -284,8 +278,7 @@ export default function Rollouts(props: RolloutsProps) {
rule that matches will be applied.
</p>
<p className="text-gray-700 text-sm font-light">
<InformationCircleIcon className="text-gray-300 mr-1 inline-block h-4 w-4" />
You can re-arrange rollouts by clicking on a rollout header and{' '}
Rollouts can be rearranged by clicking on a rollout header and{' '}
<span className="font-semibold">dragging and dropping</span> it
into place.
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import {
sortableKeyboardCoordinates,
verticalListSortingStrategy
} from '@dnd-kit/sortable';
import { InformationCircleIcon, PlusIcon } from '@heroicons/react/24/outline';
import { PlusIcon } from '@heroicons/react/24/outline';
import { useCallback, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useNavigate, useOutletContext } from 'react-router-dom';
import { FlagProps } from '~/app/flags/FlagProps';
import { selectReadonly } from '~/app/meta/metaSlice';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import EmptyState from '~/components/EmptyState';
Expand All @@ -36,9 +37,8 @@ import { FlagType } from '~/types/Flag';
import { IRule, IRuleList } from '~/types/Rule';
import { ISegment, ISegmentList, SegmentOperatorType } from '~/types/Segment';
import { IVariant } from '~/types/Variant';
import { FlagProps } from './FlagProps';

export default function Evaluation() {
export default function Rules() {
const { flag } = useOutletContext<FlagProps>();

const [segments, setSegments] = useState<ISegment[]>([]);
Expand Down Expand Up @@ -242,13 +242,10 @@ export default function Evaluation() {
</Slideover>

{/* rules */}
<div className="my-10">
<div className="mt-2">
<div className="sm:flex sm:items-center">
<div className="sm:flex-auto">
<h1 className="text-gray-900 text-lg font-medium leading-6">
Rules
</h1>
<p className="text-gray-600 mt-1 text-sm">
<p className="text-gray-500 mt-1 text-sm">
Enable rich targeting and segmentation for evaluating your flags
</p>
</div>
Expand Down Expand Up @@ -280,8 +277,7 @@ export default function Evaluation() {
first rule that matches will be applied.
</p>
<p className="text-gray-700 text-sm font-light">
<InformationCircleIcon className="text-gray-300 mr-1 inline-block h-4 w-4" />
You can re-arrange rules by clicking on a rule header and{' '}
Rules can be rearranged by clicking on a rule header and{' '}
<span className="font-semibold">dragging and dropping</span>{' '}
it into place.
</p>
Expand Down
18 changes: 8 additions & 10 deletions ui/src/app/flags/variants/Variants.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { PlusIcon } from '@heroicons/react/24/outline';
import { useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { useOutletContext } from 'react-router-dom';
import { selectReadonly } from '~/app/meta/metaSlice';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import EmptyState from '~/components/EmptyState';
Expand All @@ -15,11 +16,11 @@ import { IVariant } from '~/types/Variant';

type VariantsProps = {
flag: IFlag;
flagChanged: () => void;
onFlagChange: () => void;
};

export default function Variants(props: VariantsProps) {
const { flag, flagChanged } = props;
export default function Variants() {
const { flag, onFlagChange } = useOutletContext<VariantsProps>();

const [showVariantForm, setShowVariantForm] = useState<boolean>(false);
const [editingVariant, setEditingVariant] = useState<IVariant | null>(null);
Expand Down Expand Up @@ -47,7 +48,7 @@ export default function Variants(props: VariantsProps) {
setOpen={setShowVariantForm}
onSuccess={() => {
setShowVariantForm(false);
flagChanged();
onFlagChange();
}}
/>
</Slideover>
Expand All @@ -71,18 +72,15 @@ export default function Variants(props: VariantsProps) {
deleteVariant(namespace.key, flag.key, deletingVariant?.id ?? '') // TODO: Determine impact of blank ID param
}
onSuccess={() => {
flagChanged();
onFlagChange();
}}
/>
</Modal>

{/* variants */}
<div className="mt-10">
<div className="mt-2">
<div className="sm:flex sm:items-center">
<div className="sm:flex-auto">
<h1 className="text-gray-900 text-lg font-medium leading-6">
Variants
</h1>
<p className="text-gray-500 mt-1 text-sm">
Return different values based on rules you define
</p>
Expand All @@ -108,7 +106,7 @@ export default function Variants(props: VariantsProps) {
</div>
)}
</div>
<div className="my-10">
<div className="mt-10">
{flag.variants && flag.variants.length > 0 ? (
<table className="min-w-full divide-y divide-gray-300">
<thead>
Expand Down
3 changes: 0 additions & 3 deletions ui/src/app/segments/NewSegment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ export default function NewSegment() {
<div className="my-10">
<div className="md:grid md:grid-cols-3 md:gap-6">
<div className="md:col-span-1">
<h3 className="text-gray-900 text-lg font-medium leading-6">
Details
</h3>
<p className="text-gray-500 mt-2 text-sm">
Basic information about the segment.
</p>
Expand Down
Loading

0 comments on commit f0a8d8c

Please sign in to comment.