Skip to content

Commit

Permalink
feat: real rollout list/quick edit/delete (#1857)
Browse files Browse the repository at this point in the history
* feat(wip): rollout list ui + quickedit

* chore: update some styles

* chore: fix selected segment

* feat: finish update/delete of rollout list

* chore: fix linter

* chore: add percent icon, hide slider in mobile

* feat: make reset work:
  • Loading branch information
markphelps committed Jul 12, 2023
1 parent d4ff07a commit db0fd10
Show file tree
Hide file tree
Showing 18 changed files with 712 additions and 410 deletions.
4 changes: 2 additions & 2 deletions ui/src/app/flags/Evaluation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import Button from '~/components/forms/buttons/Button';
import Modal from '~/components/Modal';
import DeletePanel from '~/components/panels/DeletePanel';
import EditRuleForm from '~/components/rules/EditRuleForm';
import NewRule from '~/components/rules/NewRule';
import Rule from '~/components/rules/Rule';
import RuleForm from '~/components/rules/RuleForm';
import SortableRule from '~/components/rules/SortableRule';
import Slideover from '~/components/Slideover';
Expand Down Expand Up @@ -297,7 +297,7 @@ export default function Evaluation() {
</SortableContext>
<DragOverlay>
{activeRule ? (
<NewRule
<Rule
namespace={namespace}
totalRules={rules.length}
rule={activeRule}
Expand Down
76 changes: 69 additions & 7 deletions ui/src/app/flags/rollouts/Rollouts.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PlusIcon } from '@heroicons/react/24/outline';
import { InformationCircleIcon, PlusIcon } from '@heroicons/react/24/outline';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { selectReadonly } from '~/app/meta/metaSlice';
Expand All @@ -8,6 +8,7 @@ import Button from '~/components/forms/buttons/Button';
import Modal from '~/components/Modal';
import DeletePanel from '~/components/panels/DeletePanel';
import RolloutForm from '~/components/rollouts/RolloutForm';
import SortableRollout from '~/components/rollouts/SortableRollout';
import Slideover from '~/components/Slideover';
import { deleteRollout, listRollouts, listSegments } from '~/data/api';
import { IFlag } from '~/types/Flag';
Expand All @@ -27,10 +28,9 @@ export default function Rollouts(props: RolloutsProps) {
const [rolloutsVersion, setRolloutsVersion] = useState(0);
const [showRolloutForm, setShowRolloutForm] = useState<boolean>(false);

const [editingRollout, setEditingRollout] = useState<IRollout | null>(null);
const [showDeleteRolloutModal, setShowDeleteRolloutModal] =
useState<boolean>(false);
const [deletingRollout] = useState<IRollout | null>(null);
const [deletingRollout, setDeletingRollout] = useState<IRollout | null>(null);

const rolloutFormRef = useRef(null);

Expand Down Expand Up @@ -70,7 +70,7 @@ export default function Rollouts(props: RolloutsProps) {
<RolloutForm
flagKey={flag.key}
segments={segments}
rollout={editingRollout || undefined}
// rollout={editingRollout || undefined}
rank={(rollouts?.length || 0) + 1}
setOpen={setShowRolloutForm}
onSuccess={() => {
Expand Down Expand Up @@ -122,7 +122,7 @@ export default function Rollouts(props: RolloutsProps) {
disabled={readOnly}
title={readOnly ? 'Not allowed in Read-Only mode' : undefined}
onClick={() => {
setEditingRollout(null);
// setEditingRollout(null);
setShowRolloutForm(true);
}}
>
Expand All @@ -137,13 +137,75 @@ export default function Rollouts(props: RolloutsProps) {
</div>
<div className="mt-10">
{rollouts && rollouts.length > 0 ? (
<></>
<div className="flex lg:space-x-5">
<div className="hidden w-1/4 flex-col space-y-7 pr-3 lg:flex">
<p className="text-sm text-gray-500">
Rules are evaluated in order from{' '}
<span className="font-semibold">top to bottom</span>. The
first rule that matches will be applied.
</p>
<p className="text-sm text-gray-500">
<InformationCircleIcon className="mr-1 inline-block h-4 w-4 text-violet-300" />
You can re-arrange rules by{' '}
<span className="font-semibold">dragging and dropping</span>{' '}
them into place.
</p>
</div>
<div
className="pattern-boxes w-full border p-4 pattern-bg-gray-50 pattern-gray-100 pattern-opacity-100 pattern-size-2 dark:pattern-bg-black dark:pattern-gray-900
lg:w-3/4 lg:p-6"
>
{/* <DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
>
<SortableContext
items={rules.map((rule) => rule.id)}
strategy={verticalListSortingStrategy}
> */}
<ul role="list" className="flex-col space-y-6 p-2 md:flex">
{rollouts &&
rollouts.length > 0 &&
rollouts.map((rollout) => (
<SortableRollout
key={rollout.id}
flagKey={flag.key}
rollout={rollout}
segments={segments}
onQuickEditSuccess={incrementRolloutsVersion}
onEdit={() => {
// setEditingRollout(rollout);
//setShowEditRolloutForm(true);
}}
onDelete={() => {
setDeletingRollout(rollout);
setShowDeleteRolloutModal(true);
}}
readOnly={readOnly}
/>
))}
</ul>
{/* </SortableContext>
<DragOverlay>
{activeRule ? (
<NewRule
namespace={namespace}
totalRules={rules.length}
rule={activeRule}
/>
) : null}
</DragOverlay>
</DndContext> */}
</div>
</div>
) : (
<EmptyState
text="New Rollout"
disabled={readOnly}
onClick={() => {
setEditingRollout(null);
//setEditingRollout(null);
setShowRolloutForm(true);
}}
/>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/forms/Combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default function Combobox<T extends IFilterable>(
<div className="relative flex w-full flex-row">
<C.Input
id={id}
className="w-full rounded-md border py-2 pl-3 pr-10 shadow-sm border-gray-300 focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 sm:text-sm"
className="w-full rounded-md border py-2 pl-3 pr-10 shadow-sm bg-gray-50 border-gray-300 focus:outline-none focus:ring-1 focus:ring-violet-500 focus:border-violet-500 sm:text-sm"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
}}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/forms/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function Select(props: SelectProps) {
{...field}
id={id}
name={name}
className={`${className} block rounded-md py-2 pl-3 pr-10 text-base text-gray-900 bg-gray-50 border-gray-300 focus:outline-none focus:ring-violet-300 focus:border-violet-300 sm:text-sm`}
className={`block rounded-md py-2 pl-3 pr-10 text-base text-gray-900 bg-gray-50 border-gray-300 focus:outline-none focus:ring-violet-300 focus:border-violet-300 sm:text-sm ${className}`}
value={value}
onChange={onChange || field.onChange}
>
Expand Down
40 changes: 40 additions & 0 deletions ui/src/components/forms/buttons/TextButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { classNames } from '~/utils/helpers';

export type ButtonProps = {
children: React.ReactNode;
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
type?: 'button' | 'submit' | 'reset';
className?: string;
title?: string;
disabled?: boolean;
};

export default function TextButton(props: ButtonProps) {
const {
className,
onClick,
children,
type = 'button',
title,
disabled = false
} = props;

return (
<button
type={type}
onClick={(e) => {
!disabled && onClick && onClick(e);
}}
className={classNames(
disabled ? 'cursor-not-allowed' : 'cursor-hand',
`mb-1 inline-flex items-center justify-center rounded-md border-0 text-sm font-medium text-gray-300
focus:outline-none
enabled:text-gray-500 enabled:hover:text-gray-600 ${className}`
)}
disabled={disabled}
title={title}
>
{children}
</button>
);
}
Loading

0 comments on commit db0fd10

Please sign in to comment.