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

feat: add UI support for flag metadata #3717

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4cc9107
feat: add MetadataForm component and flag metadata types
devin-ai-integration[bot] Dec 11, 2024
ccc3b9e
feat: integrate MetadataForm into FlagForm
devin-ai-integration[bot] Dec 11, 2024
88bf310
feat: update RTK Query endpoints for flag metadata
devin-ai-integration[bot] Dec 11, 2024
2f10060
chore: add testing dependencies for MetadataForm tests
devin-ai-integration[bot] Dec 11, 2024
7920bb7
test: add MetadataForm component tests
devin-ai-integration[bot] Dec 11, 2024
c318134
chore: update jest config for React and TypeScript testing
devin-ai-integration[bot] Dec 11, 2024
d0ea297
chore: update testing dependencies and babel config
devin-ai-integration[bot] Dec 11, 2024
c824b5e
chore: update jest configuration and dependencies
devin-ai-integration[bot] Dec 11, 2024
1706d47
chore: add babel-jest for React component testing
devin-ai-integration[bot] Dec 11, 2024
8908d00
test: enhance React testing configuration
devin-ai-integration[bot] Dec 11, 2024
edb1d5a
test: relocate MetadataForm test file
devin-ai-integration[bot] Dec 11, 2024
f60c386
test: improve MetadataForm test selectors and type handling
devin-ai-integration[bot] Dec 11, 2024
bb32cb4
chore: ignore coverage directory
devin-ai-integration[bot] Dec 11, 2024
fba571e
chore: remove coverage directory
devin-ai-integration[bot] Dec 11, 2024
4a56d35
test: update MetadataForm test formatting
devin-ai-integration[bot] Dec 11, 2024
b9321dd
chore: update ui/.gitignore
devin-ai-integration[bot] Dec 11, 2024
7fa0d46
fix: resolve linting issues and move test dependencies
devin-ai-integration[bot] Dec 11, 2024
4e46fee
fix: move testing libraries to devDependencies
devin-ai-integration[bot] Dec 11, 2024
3c5a91c
test: add test setup and mock files
devin-ai-integration[bot] Dec 11, 2024
a1b6702
chore: prepare for test file cleanup
devin-ai-integration[bot] Dec 11, 2024
0746a01
chore: remove unit test files in favor of e2e tests
devin-ai-integration[bot] Dec 11, 2024
1603164
test: add playwright tests for flag metadata
devin-ai-integration[bot] Dec 11, 2024
13d816e
chore: origin add back ui/data tests
markphelps Dec 11, 2024
011356f
chore: revert ui test config
markphelps Dec 11, 2024
941f38d
chore: delete unneeded tests configs, add back helpers tests
markphelps Dec 11, 2024
a697b33
chore: redo package.json
markphelps Dec 11, 2024
e0ade7c
Merge branch 'main' into devin/1733937099-flag-metadata
markphelps Dec 13, 2024
8ebddfa
chore: support objects and primitives in metadata
markphelps Dec 14, 2024
961bd3c
chore: handle arrays
markphelps Dec 14, 2024
e195131
chore: simplify
markphelps Dec 14, 2024
d219155
chore: only show types/subtypes for new fields
markphelps Dec 14, 2024
05ee8c9
chore: fix lint issues
markphelps Dec 14, 2024
3c6ce5b
Merge branch 'main' into devin/1733937099-flag-metadata
markphelps Dec 14, 2024
973c775
Merge branch 'main' into devin/1733937099-flag-metadata
markphelps Dec 15, 2024
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
3 changes: 2 additions & 1 deletion ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ dist-ssr
/playwright/.cache/
.packagehash
/screenshots/
.env
.env
coverage
5 changes: 3 additions & 2 deletions ui/src/app/console/Console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useListAuthProvidersQuery } from '~/app/auth/authApi';
import { useListFlagsQuery } from '~/app/flags/flagsApi';
import { selectCurrentNamespace } from '~/app/namespaces/namespacesSlice';
import { selectCurrentRef } from '~/app/refs/refsSlice';
import { ContextEditor } from '~/components/console/ContextEditor';
import { JsonEditor } from '~/components/json/JsonEditor';
import EmptyState from '~/components/EmptyState';
import { Button } from '~/components/ui/button';
import Combobox from '~/components/forms/Combobox';
Expand Down Expand Up @@ -286,8 +286,9 @@ export default function Console() {
Request Context
</label>
<div className="mt-1 text-sm">
<ContextEditor
<JsonEditor
id="context"
value={formik.values.context}
setValue={(v) => {
formik.setFieldValue('context', v);
}}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/flags/flagsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ export const flagsApi = createApi({
{ namespaceKey: string; flagKey: string; values: IFlagBase }
>({
query({ namespaceKey, flagKey, values }) {
// create new object 'values' to remap defaultVariant to defaultVariantId
const update = {
defaultVariantId: values.defaultVariant?.id || null,
metadata: values.metadata || [],
...values
};
delete update.defaultVariant;
Expand Down
64 changes: 0 additions & 64 deletions ui/src/components/console/lint.ts

This file was deleted.

38 changes: 33 additions & 5 deletions ui/src/components/flags/forms/FlagForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CheckIcon, ClipboardDocumentIcon } from '@heroicons/react/20/solid';
import { CheckIcon, ClipboardDocumentIcon } from '@heroicons/react/24/outline';
import { Form, Formik } from 'formik';
import { useState } from 'react';
import { useSelector } from 'react-redux';
Expand All @@ -14,6 +14,7 @@ import Button from '~/components/forms/buttons/Button';
import Input from '~/components/forms/Input';
import Toggle from '~/components/forms/Toggle';
import Loading from '~/components/Loading';
import { MetadataForm } from '~/components/flags/forms/MetadataForm';
import { useError } from '~/data/hooks/error';
import { useSuccess } from '~/data/hooks/success';
import { keyValidation, requiredValidation } from '~/data/validations';
Expand All @@ -37,7 +38,8 @@ const flagTypes = [

const flagValidationSchema = Yup.object({
key: keyValidation,
name: requiredValidation
name: requiredValidation,
metadata: Yup.object()
});

export default function FlagForm(props: { flag?: IFlag }) {
Expand All @@ -61,14 +63,14 @@ export default function FlagForm(props: { flag?: IFlag }) {
if (isNew) {
return createFlag({
namespaceKey: namespace.key,
values: values
values
}).unwrap();
}

return updateFlag({
namespaceKey: namespace.key,
flagKey: flag?.key,
values: values
values
}).unwrap();
};

Expand All @@ -78,7 +80,8 @@ export default function FlagForm(props: { flag?: IFlag }) {
description: flag?.description || '',
type: flag?.type || FlagType.VARIANT,
enabled: flag?.enabled || false,
defaultVariant: flag?.defaultVariant
defaultVariant: flag?.defaultVariant,
metadata: flag?.metadata || {}
};

const [keyCopied, setKeyCopied] = useState(false);
Expand Down Expand Up @@ -285,6 +288,31 @@ export default function FlagForm(props: { flag?: IFlag }) {
disabled={readOnly}
/>
</div>
<div className="col-span-3">
<div className="flex justify-between">
<label
htmlFor="metadata"
className="block text-sm font-medium text-gray-700"
>
Metadata
</label>
<span
className="text-xs text-gray-500"
id="metadata-optional"
>
Optional
</span>
</div>
<div className="mt-1">
<MetadataForm
metadata={formik.values.metadata}
onChange={(metadata) =>
formik.setFieldValue('metadata', metadata)
}
disabled={readOnly}
/>
</div>
</div>
</div>
<div className="flex justify-end">
<Button type="button" onClick={() => navigate(-1)}>
Expand Down
Loading
Loading