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: small ui tweaks for rules/rollouts #1890

Merged
merged 13 commits into from
Jul 19, 2023
6 changes: 3 additions & 3 deletions ui/src/app/flags/Evaluation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,13 @@ export default function Evaluation() {
</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 in the header and{' '}
You can re-arrange rules by clicking on a rule header and{' '}
<span className="font-semibold">dragging and dropping</span>{' '}
them into place.
it 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
className="border-gray-200 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
Expand Down
8 changes: 4 additions & 4 deletions ui/src/app/flags/rollouts/Rollouts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,13 @@ export default function Rollouts(props: RolloutsProps) {
</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 in the header and{' '}
<span className="font-semibold">dragging and dropping</span>{' '}
them into place.
You can re-arrange rollouts by clicking on a rollout header and{' '}
<span className="font-semibold">dragging and dropping</span> it
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
className="border-gray-200 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:p-6"
>
{rollouts && rollouts.length > 0 && (
Expand Down
8 changes: 4 additions & 4 deletions 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="bg-gray-50 border-gray-300 w-full rounded-md border py-2 pl-3 pr-10 shadow-sm focus:border-violet-500 focus:outline-none focus:ring-1 focus:ring-violet-500 sm:text-sm"
className="text-gray-900 bg-gray-50 border-gray-300 w-full rounded-md border py-2 pl-3 pr-10 shadow-sm focus:border-violet-500 focus:outline-none focus:ring-1 focus:ring-violet-500 sm:text-sm"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
}}
Expand Down Expand Up @@ -79,7 +79,7 @@ export default function Combobox<T extends IFilterable>(
value={v}
className={({ active }) =>
classNames(
'text-gray-900 relative w-full cursor-default select-none py-2 pl-3 pr-9',
'relative w-full cursor-default select-none py-2 pl-3 pr-9',
active ? 'bg-violet-100' : ''
)
}
Expand All @@ -98,8 +98,8 @@ export default function Combobox<T extends IFilterable>(
)}
<span
className={classNames(
'truncate',
selected ? 'font-semibold' : ''
selected ? 'font-semibold' : '',
'text-gray-700 truncate'
)}
>
{v?.filterValue}
Expand Down
5 changes: 4 additions & 1 deletion ui/src/components/rollouts/Rollout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ const Rollout = forwardRef(
{rolloutTypeToLabel(rollout.type)} Rollout
</h3>
<Menu as="div" className="hidden sm:flex">
<Menu.Button className="text-gray-600 ml-4 block hover:text-gray-900">
<Menu.Button
data-testid="rollout-menu-button"
className="text-gray-600 ml-4 block hover:text-gray-900"
>
<EllipsisVerticalIcon className="h-5 w-5" aria-hidden="true" />
</Menu.Button>
{!readOnly && (
Expand Down
5 changes: 4 additions & 1 deletion ui/src/components/rules/Rule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ const Rule = forwardRef(
Rule
</h3>
<Menu as="div" className="hidden sm:flex">
<Menu.Button className="text-gray-600 ml-4 block hover:text-gray-900">
<Menu.Button
data-testid="rule-menu-button"
className="text-gray-600 ml-4 block hover:text-gray-900"
>
<EllipsisVerticalIcon className="h-5 w-5" aria-hidden="true" />
</Menu.Button>
{!readOnly && (
Expand Down
13 changes: 4 additions & 9 deletions ui/src/components/rules/forms/MultiDistributionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ export default function MultiDistributionFormInputs(
</label>
</div>
<div className="relative sm:col-span-1">
<div className="text-black pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
%
</div>
<input
type="number"
className="border-gray-300 block w-full rounded-md pl-7 pr-12 shadow-sm focus:border-violet-300 focus:ring-violet-300 sm:text-sm"
className="text-gray-900 bg-gray-50 border-gray-300 block w-full rounded-md pl-10 shadow-sm focus:border-violet-300 focus:ring-violet-300 sm:text-sm"
value={dist.rollout}
name={dist.variantKey}
// eslint-disable-next-line react/no-unknown-property
Expand All @@ -52,14 +55,6 @@ export default function MultiDistributionFormInputs(
setDistributions(newDistributions);
}}
/>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
<span
className="text-gray-500 sm:text-sm"
id={`percentage-${dist.variantKey}`}
>
%
</span>
</div>
</div>
</div>
))}
Expand Down
6 changes: 3 additions & 3 deletions ui/src/components/rules/forms/RuleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const distTypes = [
},
{
id: DistributionType.Multi,
name: 'Multi-Variant',
name: 'Multi-Variate',
description: 'Returns different variants based on percentages'
}
];
Expand Down Expand Up @@ -288,8 +288,8 @@ export default function RuleForm(props: RuleFormProps) {
/>
)}
{!distributionsValid && ruleType === DistributionType.Multi && (
<p className="text-gray-500 mt-1 px-4 text-center text-sm sm:px-6 sm:py-5">
Multi-variant rules must have distributions that add up to
<p className="text-red-500 mt-1 px-4 text-center text-sm sm:px-6 sm:py-5">
Multi-variate rules must have distributions that add up to
100% or less.
</p>
)}
Expand Down
38 changes: 25 additions & 13 deletions ui/tests/rollouts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,7 @@ test.describe('Rollouts', () => {

test('can edit rollout', async ({ page }) => {
await page.getByRole('link', { name: 'test-boolean' }).click();
await page
.getByRole('list')
.locator('[id="headlessui-menu-button-\\:r4\\:"]')
.first()
.click();
await page.getByTestId('rollout-menu-button').click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('textbox').click();
await page.getByRole('textbox').fill('test2');
Expand All @@ -62,18 +58,34 @@ test.describe('Rollouts', () => {

test('can delete rollout', async ({ page }) => {
await page.getByRole('link', { name: 'test-boolean' }).click();
await expect(
page.getByRole('button', { name: 'Threshold Rollout' })
).toBeVisible();
await page
.getByRole('list')
.locator('[id="headlessui-menu-button-\\:r4\\:"]')
.first()
.click();
await page.getByTestId('rollout-menu-button').click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
await expect(
page.getByRole('button', { name: 'Threshold Rollout' })
).toBeHidden();
});
});

test.describe('Rollouts - Read Only', () => {
test.beforeEach(async ({ page }) => {
await page.route(/\/meta\/config/, async (route) => {
const response = await route.fetch();
const json = await response.json();
json.storage = { type: 'git' };
// Fulfill using the original response, while patching the
// response body with our changes to mock git storage for read only mode
await route.fulfill({ response, json });
});

await page.goto('/');
await page.getByRole('link', { name: 'Flags' }).click();
await page.getByRole('link', { name: 'test-boolean' }).click();
});

test('cannot create rollout', async ({ page }) => {
await expect(
page.getByRole('button', { name: 'New Rollout' })
).toBeDisabled();
});
});
10 changes: 5 additions & 5 deletions ui/tests/rules.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ test.describe('Rules', () => {
await page.getByRole('link', { name: 'Evaluation' }).click();
await page.getByRole('button', { name: 'New Rule' }).click();

await page.locator('#segmentKey-select-button').click();
await page.getByText('test-rule').click();
await page.getByLabel('Multi-Variant').check();
await page.getByRole('combobox').type('test-rule');
await page.getByRole('option', { name: 'test-rule' }).click();
await page.getByLabel('Multi-Variate').check();
await page.getByRole('button', { name: 'Create' }).click();
await expect(page.getByText('Successfully created rule')).toBeVisible();
});
Expand Down Expand Up @@ -92,14 +92,14 @@ test.describe('Rules - Read Only', () => {
test('can not update rule', async ({ page }) => {
await page.getByRole('link', { name: 'test-rule' }).click();
await page.getByRole('link', { name: 'Evaluation' }).click();
await page.locator('[id="headlessui-menu-button-\\:r4\\:"]').click();
await page.getByTestId('rule-menu-button').click();
await expect(page.getByRole('link', { name: 'Edit' })).toBeHidden();
});

test('can not delete rule', async ({ page }) => {
await page.getByRole('link', { name: 'test-rule' }).click();
await page.getByRole('link', { name: 'Evaluation' }).click();
await page.locator('[id="headlessui-menu-button-\\:r4\\:"]').click();
await page.getByTestId('rule-menu-button').click();
await expect(page.getByRole('link', { name: 'Delete' })).toBeHidden();
});
});