From c790ad2e15f8fb8c9096acb96519bdd1ab01d0d0 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Tue, 21 Mar 2023 17:31:25 +0000 Subject: [PATCH 1/9] Moves modals to separate components --- src/components/DeleteModal.tsx | 25 ++++++++++++ src/components/LineItem.tsx | 69 ++++++++++++++++++++++------------ src/components/SdkModal.tsx | 20 ++++++++++ 3 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 src/components/DeleteModal.tsx create mode 100644 src/components/SdkModal.tsx diff --git a/src/components/DeleteModal.tsx b/src/components/DeleteModal.tsx new file mode 100644 index 0000000..72033b5 --- /dev/null +++ b/src/components/DeleteModal.tsx @@ -0,0 +1,25 @@ +import { Modal, Button } from '@wordpress/components'; +const DeleteModal = (props: any): JSX.Element => { + const { closeModal, item, handleDeleteFlag } = props; + return ( + +

+ Are you sure want to delete flag "{item.name} + "? +

+ + +
+ ); +}; + +export default DeleteModal; diff --git a/src/components/LineItem.tsx b/src/components/LineItem.tsx index ab2cf37..4f31203 100644 --- a/src/components/LineItem.tsx +++ b/src/components/LineItem.tsx @@ -4,11 +4,12 @@ import { Flex, FlexItem, Button, - Modal, BaseControl, } from '@wordpress/components'; import { useState } from '@wordpress/element'; import { Flag } from '../../types'; +import DeleteModal from './DeleteModal'; +import SdkModal from './SdkModal'; const LineItem = ({ flags, @@ -18,6 +19,8 @@ const LineItem = ({ }: any): JSX.Element => { const [isOpen, setOpen] = useState(false); + const [isSdkOpen, setIsSdkOpen] = useState(false); + const [hasError, setHasError] = useState(false); const handleDeleteFlag = (flagId: number) => { @@ -58,6 +61,12 @@ const LineItem = ({ }; const closeModal = () => setOpen(false); + const openSdkModal = () => { + setIsSdkOpen(true); + }; + + const closeSdkModal = () => setIsSdkOpen(false); + const handleDeleteModal = (flag: Flag) => { if (flag.name) { openModal(); @@ -66,6 +75,10 @@ const LineItem = ({ handleDeleteFlag(flag.id); }; + const handleSdkModal = () => { + openSdkModal(); + }; + return ( <>
@@ -76,13 +89,24 @@ const LineItem = ({ onChange={(value) => handleFlagEdit(value, item.id)} /> - + handleFlagToggle(item.id)} /> - + + + +
{isOpen && ( - -

- Are you sure want to delete flag "{item.name} - "? -

- - -
+ + )} + {isSdkOpen && ( + + // + //

{` + + // + // )} ); diff --git a/src/components/SdkModal.tsx b/src/components/SdkModal.tsx new file mode 100644 index 0000000..dc73cd5 --- /dev/null +++ b/src/components/SdkModal.tsx @@ -0,0 +1,20 @@ +import { Modal, Button } from '@wordpress/components'; + +const SdkModal = (props: any): JSX.Element => { + const { item, closeSdkModal } = props; + return ( + +

{` + + + + ); +}; + +export default SdkModal; From 92d89a2312bdd07af71a64921398989e3cf94101 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Tue, 21 Mar 2023 19:22:24 +0000 Subject: [PATCH 2/9] optimise flag check for server and client side --- helper/Helper.php | 2 +- includes/FeatureFlags.php | 38 -------------- package.json | 1 + src/components/SdkModal.tsx | 12 ++--- src/index.ts | 8 +-- types/window.d.ts | 16 +++++- yarn.lock | 102 +++++++++++++++++++++++++++++++++++- 7 files changed, 127 insertions(+), 52 deletions(-) diff --git a/helper/Helper.php b/helper/Helper.php index 98643ea..d7a8d93 100644 --- a/helper/Helper.php +++ b/helper/Helper.php @@ -28,7 +28,7 @@ class Helper { */ public static function search_flag( $flags, $field, $flag ) { foreach ( $flags as $key => $value ) { - if ( $value[ $field ] === $flag ) { + if ( $value[ $field ] === $flag && true === $value['enabled'] ) { return $value; } } diff --git a/includes/FeatureFlags.php b/includes/FeatureFlags.php index 7913646..30aaf73 100644 --- a/includes/FeatureFlags.php +++ b/includes/FeatureFlags.php @@ -42,42 +42,4 @@ public static function is_enabled( string $flag ): bool { return false; } - /** - * Adds provided flag if it does not exists. - * - * @param string $flag name of the flag. - * @return bool - * @throws \Error Throws error if flag already exists. - * @since 1.0.0 - */ - public static function add_flag( string $flag ): bool { - - $flags = get_option( self::$option_name ); - - if ( is_array( $flags ) && Helper::search_flag( $flags, 'name', $flag ) ) { - throw new \Error( "Flag \"{$flag}\" already exists" ); - } - - $flag_key = 1; - - if ( is_array( $flags ) && count( $flags ) ) { - $flag_key = count( $flags ) + 1; - } - - // $flag_key = count( $flags ) ? count( $flags ) + 1 : 1; - // ddd( $flag_key ); - $new_flag = [ - 'id' => $flag_key, - 'name' => $flag, - 'enabled' => false, - ]; - - if ( $flags ) { - array_push( $flags, $new_flag ); - return update_option( self::$option_name, $flags ); - } - - return add_option( self::$option_name, [ $new_flag ] ); - - } } diff --git a/package.json b/package.json index b674c83..c5b0aa3 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@wordpress/data": "^8.6.0", "@wordpress/i18n": "^4.29.0", "@wordpress/notices": "^3.29.0", + "react-syntax-highlighter": "^15.5.0", "ts-loader": "^9.4.2", "typescript": "^5.0.2" } diff --git a/src/components/SdkModal.tsx b/src/components/SdkModal.tsx index dc73cd5..b5cd450 100644 --- a/src/components/SdkModal.tsx +++ b/src/components/SdkModal.tsx @@ -4,12 +4,12 @@ const SdkModal = (props: any): JSX.Element => { const { item, closeSdkModal } = props; return ( -

{` - +

{`if (window.mrFeatureFlags.isEnabled('DeskNet')) { + render(, document.getElementById('desknet_settings')); +}`}

+

{`if ( \MR\FeatureFlags\FeatureFlags::is_enabled( 'Teal' ) ) { + add_theme_support('menus'); +}`}

diff --git a/src/index.ts b/src/index.ts index 93216f0..ff76419 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,12 @@ const { mrFeatureFlags } = window; +import { Flag } from '../types'; mrFeatureFlags.isEnabled = (flag: string) => { - const isFlagExist = mrFeatureFlags.flags.find( - (item: { name: string; enabled: boolean }) => - item.name === flag && item.enabled === true + const isFlagExist: Flag[] = mrFeatureFlags.flags.filter( + (item: Flag) => item.name === flag && item.enabled === true ); - if (isFlagExist) return true; + if (isFlagExist[0]?.name) return true; return false; }; diff --git a/types/window.d.ts b/types/window.d.ts index 133b4e6..29ce5d3 100644 --- a/types/window.d.ts +++ b/types/window.d.ts @@ -1,7 +1,19 @@ -export {}; +declare namespace mrFeatureFlag { + interface flags { + id: number; + name: string; + enabled: boolean; + } + export interface FeatureFlagProps { + isEnabled: (flag: string) => boolean; + flags: flags[]; + } +} declare global { interface Window { - mrFeatureFlags: any; + mrFeatureFlags: mrFeatureFlag.FeatureFlagProps; } } + +export {}; diff --git a/yarn.lock b/yarn.lock index 0f6d7be..f0d65af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -996,7 +996,7 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== @@ -1866,6 +1866,13 @@ dependencies: "@types/node" "*" +"@types/hast@^2.0.0": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" + integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + dependencies: + "@types/unist" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" @@ -3899,6 +3906,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== + commander@^2.19.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -5259,6 +5271,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== + dependencies: + format "^0.2.0" + faye-websocket@~0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -5428,6 +5447,11 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== + fraction.js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" @@ -5814,6 +5838,22 @@ has@^1.0.0, has@^1.0.3: dependencies: function-bind "^1.1.1" +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== + +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + header-case@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063" @@ -5832,6 +5872,11 @@ highlight-words-core@^1.2.2: resolved "https://registry.yarnpkg.com/highlight-words-core/-/highlight-words-core-1.2.2.tgz#1eff6d7d9f0a22f155042a00791237791b1eeaaa" integrity sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg== +highlight.js@^10.4.1, highlight.js@~10.7.0: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -7312,6 +7357,14 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lowlight@^1.17.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" + integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== + dependencies: + fault "^1.0.0" + highlight.js "~10.7.0" + lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -8641,6 +8694,16 @@ pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +prismjs@^1.27.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + +prismjs@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" + integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== + progress@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" @@ -8668,6 +8731,13 @@ prop-types@^15.7.0, prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +property-information@^5.0.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" + integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== + dependencies: + xtend "^4.0.0" + proxy-compare@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.3.0.tgz#ac9633ae52918ff9c9fcc54dfe6316c7a02d20ee" @@ -8841,6 +8911,17 @@ react-shallow-renderer@^16.13.1: object-assign "^4.1.1" react-is "^16.12.0 || ^17.0.0 || ^18.0.0" +react-syntax-highlighter@^15.5.0: + version "15.5.0" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz#4b3eccc2325fa2ec8eff1e2d6c18fa4a9e07ab20" + integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "^10.4.1" + lowlight "^1.17.0" + prismjs "^1.27.0" + refractor "^3.6.0" + react-test-renderer@^17.0.0: version "17.0.2" resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c" @@ -8970,6 +9051,15 @@ redux@^4.1.0, redux@^4.1.2: dependencies: "@babel/runtime" "^7.9.2" +refractor@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" + integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== + dependencies: + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.27.0" + regenerate-unicode-properties@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" @@ -9579,6 +9669,11 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + spawnd@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/spawnd/-/spawnd-5.0.0.tgz#ea72200bdc468998e84e1c3e7b914ce85fc1c32c" @@ -10835,6 +10930,11 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" From 122dd359bc42a36508c649988ba275d216dae965 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Tue, 21 Mar 2023 20:07:32 +0000 Subject: [PATCH 3/9] adds code highlighter component --- package.json | 1 + src/components/SdkModal.tsx | 19 +++++++++++++------ src/components/Snippet.tsx | 13 +++++++++++++ yarn.lock | 7 +++++++ 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 src/components/Snippet.tsx diff --git a/package.json b/package.json index c5b0aa3..1e1f5fb 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "author": "Mohan Raj ", "license": "ISC", "dependencies": { + "@types/react-syntax-highlighter": "^15.5.6", "@types/wordpress__components": "^23.0.1", "@wordpress/api-fetch": "^6.26.0", "@wordpress/components": "^23.6.0", diff --git a/src/components/SdkModal.tsx b/src/components/SdkModal.tsx index b5cd450..7b0a1e8 100644 --- a/src/components/SdkModal.tsx +++ b/src/components/SdkModal.tsx @@ -1,15 +1,22 @@ import { Modal, Button } from '@wordpress/components'; +import Snippet from './Snippet'; const SdkModal = (props: any): JSX.Element => { const { item, closeSdkModal } = props; + + const jsSnippet = `if (window.mrFeatureFlags.isEnabled('${item.name}')) { + // js code goes here... +}`; + + const phpSnippet = `if ( /\MR/\FeatureFlags/\FeatureFlags::is_enabled( '${item.name}' ) ) { + // php code goes here... +}`; return ( -

{`if (window.mrFeatureFlags.isEnabled('DeskNet')) { - render(, document.getElementById('desknet_settings')); -}`}

-

{`if ( \MR\FeatureFlags\FeatureFlags::is_enabled( 'Teal' ) ) { - add_theme_support('menus'); -}`}

+

JS Snippet

+ +

PHP Snippet

+ diff --git a/src/components/Snippet.tsx b/src/components/Snippet.tsx new file mode 100644 index 0000000..6af55ae --- /dev/null +++ b/src/components/Snippet.tsx @@ -0,0 +1,13 @@ +import SyntaxHighlighter from 'react-syntax-highlighter'; +import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; + +const Snippet = (props: any) => { + const { data } = props; + return ( + + {data} + + ); +}; + +export default Snippet; diff --git a/yarn.lock b/yarn.lock index f0d65af..070478f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1968,6 +1968,13 @@ dependencies: "@types/react" "*" +"@types/react-syntax-highlighter@^15.5.6": + version "15.5.6" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.6.tgz#77c95e6b74d2be23208fcdcf187b93b47025f1b1" + integrity sha512-i7wFuLbIAFlabTeD2I1cLjEOrG/xdMa/rpx2zwzAoGHuXJDhSqp9BSfDlMHSh9JSuNfxHk9eEmMX6D55GiyjGg== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@^18.0.21": version "18.0.28" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.28.tgz#accaeb8b86f4908057ad629a26635fe641480065" From eed55b1d7a763e26b25130504f79f6f0cdff93fc Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Wed, 22 Mar 2023 07:45:56 +0000 Subject: [PATCH 4/9] adds header --- src/components/Header.tsx | 19 +++++++++++++++++++ src/components/Layout.tsx | 30 +++++++++++++++++++----------- src/components/LineItem.tsx | 2 +- src/components/SubmitControls.tsx | 7 ++++++- 4 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 src/components/Header.tsx diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..01be3bd --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,19 @@ +import { Flex, FlexItem } from '@wordpress/components'; +export default function (): JSX.Element { + return ( + + +

Flag Name

+
+ +

Prod

+
+ +

SDK Settings

+
+ +

Delete Flag

+
+
+ ); +} diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 1e92cdf..14cd50d 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -4,6 +4,7 @@ import LineItem from './LineItem'; import { Flag } from '../../types'; import SubmitControls from './SubmitControls'; import { getFlags } from '../utils'; +import Header from './Header'; const Layout = (): JSX.Element => { const [flags, setFlags] = useState(undefined); @@ -35,6 +36,20 @@ const Layout = (): JSX.Element => { ); } + + const MapFlags = ({ flagsData }: any): any => { + return flagsData?.map((flag: Flag) => { + return ( + + ); + }); + }; return ( <>
@@ -46,17 +61,10 @@ const Layout = (): JSX.Element => {
) : ( - flags?.map((flag: Flag) => { - return ( - - ); - }) + <> +
+ {flags && } + )} {!isLoading && ( diff --git a/src/components/LineItem.tsx b/src/components/LineItem.tsx index 4f31203..635c007 100644 --- a/src/components/LineItem.tsx +++ b/src/components/LineItem.tsx @@ -106,7 +106,7 @@ const LineItem = ({ SDK - + - // )} ); diff --git a/src/components/SubmitControls.tsx b/src/components/SubmitControls.tsx index 8bbc9f0..9c09dc1 100644 --- a/src/components/SubmitControls.tsx +++ b/src/components/SubmitControls.tsx @@ -6,7 +6,7 @@ import Notices from './Snackbar'; import { dispatch } from '@wordpress/data'; const SubmitControls = (props: any): JSX.Element => { - const { isNew, flags, setFlags, lastFlag, disableSave } = props; + const { isNew, flags, setFlags, lastFlag, disableSave, env } = props; const [isSaving, setIsSaving] = useState(false); const handleNewFlag = () => { @@ -17,6 +17,7 @@ const SubmitControls = (props: any): JSX.Element => { preProdEnabled: true, }; const clonedFlags = [...flags, newFlag]; + setFlags(clonedFlags); }; @@ -25,7 +26,11 @@ const SubmitControls = (props: any): JSX.Element => { const cleanFlags: Flag[] = flags.filter( (item: Flag) => item.name !== '' ); - await updateFlags(cleanFlags); + const latestEnv: string = env; + + console.log({ env: latestEnv, flags: cleanFlags }); + // return; + await updateFlags({ env: latestEnv, flags: cleanFlags }); setIsSaving(false); diff --git a/src/utils/index.ts b/src/utils/index.ts index cf051e4..f478286 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,18 +1,16 @@ import apiFetch from '@wordpress/api-fetch'; import { FEATURE_FLAG_NAMESPACE, FEATURE_FLAG_ROUTE } from '../constants'; -import { Flag } from '../../types'; -export const getFlags = async (): Promise => { - const result: Flag[] | Error = await apiFetch({ +export const getFlags = async (): Promise => { + const result: any = await apiFetch({ method: 'GET', path: `${FEATURE_FLAG_NAMESPACE}/${FEATURE_FLAG_ROUTE}`, }); - return result; }; export const updateFlags = async ( - flags: Flag[] + flags: any ): Promise<{ status: number; success: boolean } | Error> => { const result: { status: number; success: boolean } | Error = await apiFetch( { diff --git a/types/index.ts b/types/index.ts index 5d20de7..c97faa3 100644 --- a/types/index.ts +++ b/types/index.ts @@ -2,4 +2,10 @@ export interface Flag { id: number; name: string; enabled: boolean; + preProdEnabled?: boolean; +} + +export interface FlagProps { + env: string; + flags: Flag[]; } From 69ed7834796e05446ea612039a1d915d65a35279 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Thu, 23 Mar 2023 09:20:52 +0000 Subject: [PATCH 6/9] env based changes --- includes/FeatureFlags.php | 4 ++-- plugin.php | 38 +++++++++++++++++++++++-------- src/components/Layout.tsx | 30 ++---------------------- src/components/SdkModal.tsx | 12 ++++++++-- src/components/SubmitControls.tsx | 12 ++++++++-- src/index.ts | 15 ++++++++---- src/styles/settings.scss | 4 ++++ 7 files changed, 67 insertions(+), 48 deletions(-) diff --git a/includes/FeatureFlags.php b/includes/FeatureFlags.php index 6d5d0e3..0a7160b 100644 --- a/includes/FeatureFlags.php +++ b/includes/FeatureFlags.php @@ -23,7 +23,7 @@ class FeatureFlags { * * @var string $option_name */ - public static $option_name = 'mr_feature_flags'; + public static $option_name = 'mr_feature_flags1'; /** * Name of flag environment. @@ -42,7 +42,7 @@ class FeatureFlags { public static function is_enabled( string $flag ): bool { $flags = get_option( self::$option_name ); - if ( Helper::search_flag( $flags, 'name', $flag ) ) { + if ( isset( $flags['env'] ) && Helper::search_flag( $flags['env'], 'name', $flag ) ) { return true; } diff --git a/plugin.php b/plugin.php index 92f6ccc..c625f3f 100644 --- a/plugin.php +++ b/plugin.php @@ -80,6 +80,16 @@ function load_settings_scripts(): void { $plugin_url = plugin_dir_url( MR_FEATURE_FLAGS_PLUGIN_PATH ); $settings_asset_file = require_once plugin_dir_path( MR_FEATURE_FLAGS_PLUGIN_PATH ) . 'build/settings.asset.php'; // @phpcs:ignore + // $feature_flag_meta = get_option( FeatureFlags::$option_name ); + // $feature_flag_env = 'prod'; + // if(isset($feature_flag_meta['env'])) { + // $feature_flag_env = $feature_flag_meta['env']; + // } + + + // if($feature_flag_meta['env'] === '') { + // $feature_flag_env = 'prod'; + // } wp_enqueue_script( 'mr-feature-flags', $plugin_url . 'build/settings.js', @@ -90,14 +100,6 @@ function load_settings_scripts(): void { wp_enqueue_style( 'wp-edit-blocks' ); - wp_localize_script( - 'mr-feature-flags', - 'mrFeatureFlags', - [ - 'flags' => get_option( FeatureFlags::$option_name ), - ] - ); - wp_enqueue_style( 'mr-feature-flags', $plugin_url . 'build/settings.css', @@ -121,14 +123,30 @@ function(string $page): void { true ); + $feature_flag_env = 'prod'; + + $feature_flag_meta = get_option( FeatureFlags::$option_name ); + $feature_flags_list = []; + if(isset($feature_flag_meta['flags'])) { + $feature_flags_list = $feature_flag_meta['flags']; + } + if(isset($feature_flag_meta['env'])) { + $feature_flag_env = $feature_flag_meta['env']; + } + // $feature_flag_env = $feature_flag_meta['env']; + + // if($feature_flag_meta['env'] === '') { + // $feature_flag_env = 'prod'; + // } + wp_localize_script( 'mr-feature-flags-script', 'mrFeatureFlags', [ - 'flags' => get_option( FeatureFlags::$option_name ), - 'env' => get_option( FeatureFlags::$env_option_name ) + 'flags' => $feature_flags_list, + 'env' => $feature_flag_env ] ); diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index cdbc6cc..b6c5740 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -15,7 +15,7 @@ const Layout = (): JSX.Element => { useEffect(() => { const logFlags = async () => { const result = await getFlags(); - console.log(result); + // console.log(result); if (result.env) { setEnv(result.env); } @@ -31,39 +31,13 @@ const Layout = (): JSX.Element => { const lastFlag = flags?.at(-1)?.id || 0; - if (!lastFlag && !isLoading) { - return ( - <> -

- Welcome to feature flag dashboard. You can add new flags - `Add flags` action. -

- - - ); - } - - // const MapFlags = ({ flagsData }: any): any => { - // return flagsData?.map((flag: Flag) => { - // return ( - // - // ); - // }); - // }; return ( <>

Feature Flags settings

-

Manage all feature flags.

-
+ {lastFlag ?
: ''} {isLoading ? (
diff --git a/src/components/SdkModal.tsx b/src/components/SdkModal.tsx index 7b0a1e8..68a3f83 100644 --- a/src/components/SdkModal.tsx +++ b/src/components/SdkModal.tsx @@ -4,9 +4,17 @@ import Snippet from './Snippet'; const SdkModal = (props: any): JSX.Element => { const { item, closeSdkModal } = props; - const jsSnippet = `if (window.mrFeatureFlags.isEnabled('${item.name}')) { + const jsSnippet = ` +//For Pre production environment +if (window.mrFeatureFlags.isEnabled('${item.name}', 'pre-prod')) { // js code goes here... -}`; +} + +//For Production environment +if (window.mrFeatureFlags.isEnabled('${item.name}')) { + // js code goes here... +} +`; const phpSnippet = `if ( /\MR/\FeatureFlags/\FeatureFlags::is_enabled( '${item.name}' ) ) { // php code goes here... diff --git a/src/components/SubmitControls.tsx b/src/components/SubmitControls.tsx index 9c09dc1..0fdaa4e 100644 --- a/src/components/SubmitControls.tsx +++ b/src/components/SubmitControls.tsx @@ -16,9 +16,17 @@ const SubmitControls = (props: any): JSX.Element => { enabled: false, preProdEnabled: true, }; - const clonedFlags = [...flags, newFlag]; - setFlags(clonedFlags); + let latestFlags = []; + + if (flags?.length) { + latestFlags = [...flags, newFlag]; + } else { + latestFlags = [newFlag]; + } + // const clonedFlags = [...flags, newFlag]; + + setFlags(latestFlags); }; const handleSave = async () => { diff --git a/src/index.ts b/src/index.ts index ff76419..d287761 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,19 @@ const { mrFeatureFlags } = window; import { Flag } from '../types'; -mrFeatureFlags.isEnabled = (flag: string) => { - const isFlagExist: Flag[] = mrFeatureFlags.flags.filter( - (item: Flag) => item.name === flag && item.enabled === true +mrFeatureFlags.isEnabled = (flag: string, env = 'prod') => { + let envFlag = 'enabled'; + if (env === 'pre-prod') { + envFlag = 'preProdEnabled'; + } + const isFlagExist: Flag | undefined = mrFeatureFlags.flags.find( + (item: Flag) => { + //@ts-ignore + return item.name === flag && item[envFlag] === true; + } ); - if (isFlagExist[0]?.name) return true; + if (isFlagExist?.name) return true; return false; }; diff --git a/src/styles/settings.scss b/src/styles/settings.scss index 6ec52ff..3b90bab 100644 --- a/src/styles/settings.scss +++ b/src/styles/settings.scss @@ -17,3 +17,7 @@ height: 20px; } } + +#mr-feature-flag-submit-controls { + margin-top: 20px; +} From 6023f769e190f4acc1902f811efd42d431a6cc33 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Thu, 23 Mar 2023 15:22:35 +0000 Subject: [PATCH 7/9] Adds clipboard --- helper/Helper.php | 10 +-- includes/Api/FlagOptions.php | 17 +---- includes/FeatureFlags.php | 10 +-- includes/Settings.php | 1 + plugin.php | 50 ++++---------- src/components/Environment.tsx | 28 -------- src/components/Header.tsx | 11 ++-- src/components/Layout.tsx | 15 ++--- src/components/LineItem.tsx | 12 +--- src/components/SdkModal.tsx | 105 +++++++++++++++++++++++++----- src/components/SubmitControls.tsx | 9 +-- src/index.ts | 11 +--- 12 files changed, 122 insertions(+), 157 deletions(-) delete mode 100644 src/components/Environment.tsx diff --git a/helper/Helper.php b/helper/Helper.php index 223e30f..c1f1a58 100644 --- a/helper/Helper.php +++ b/helper/Helper.php @@ -37,14 +37,8 @@ class Helper { public static function search_flag( $flags, $field, $flag ) { if ( is_array( $flags ) ) { foreach ( $flags as $key => $value ) { - $current_env = get_option( self::$env_option_name ); - $env_field = 'enabled'; - if( $current_env === 'pre-prod' ) { - $env_field = 'preProdEnabled'; - } - - if ( $value[ $field ] === $flag && true === $value[ $env_field] ) { - return $value; + if ( $value[ $field ] === $flag && true === $value['enabled'] ) { + return true; } } } diff --git a/includes/Api/FlagOptions.php b/includes/Api/FlagOptions.php index 0b45060..86641e1 100644 --- a/includes/Api/FlagOptions.php +++ b/includes/Api/FlagOptions.php @@ -23,7 +23,7 @@ class FlagOptions { * * @var string $option_name */ - public static $option_name = 'mr_feature_flags1'; + public static $option_name = 'mr_feature_flags'; /** * Name of flag environment. @@ -83,10 +83,8 @@ function () { public function get_all_flags() { $flags = get_option( self::$option_name ); - // die(var_dump($flags)); - if ( empty( $flags ) ) { - return rest_ensure_response( [ 'message' => 'no flags found' ] ); + return rest_ensure_response( [] ); } return rest_ensure_response( $flags ); @@ -102,17 +100,6 @@ public function get_all_flags() { public function post_flags( $request ) { $flags = $request->get_json_params(); - // var_dump($flags); - - // $existing_meta = get_option( self::$option_name ); - - - - // if ( is_array( $existing_meta[1]['flags'] ) ) { - // $existing_meta[1]['flags'] = $flags; - // } - - if ( is_array( $flags ) ) { $result = update_option( self::$option_name, $flags ); return rest_ensure_response( diff --git a/includes/FeatureFlags.php b/includes/FeatureFlags.php index 0a7160b..b121689 100644 --- a/includes/FeatureFlags.php +++ b/includes/FeatureFlags.php @@ -23,14 +23,8 @@ class FeatureFlags { * * @var string $option_name */ - public static $option_name = 'mr_feature_flags1'; + public static $option_name = 'mr_feature_flags'; - /** - * Name of flag environment. - * - * @var string $env_option_name - */ - public static $env_option_name = 'mr_feature_flags_env'; /** * Check if given feature is enabled or not. @@ -42,7 +36,7 @@ class FeatureFlags { public static function is_enabled( string $flag ): bool { $flags = get_option( self::$option_name ); - if ( isset( $flags['env'] ) && Helper::search_flag( $flags['env'], 'name', $flag ) ) { + if ( Helper::search_flag( $flags, 'name', $flag ) ) { return true; } diff --git a/includes/Settings.php b/includes/Settings.php index 585e496..9e057a5 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -53,3 +53,4 @@ public function render_page() { echo '
'; } } + diff --git a/plugin.php b/plugin.php index c625f3f..c557c75 100644 --- a/plugin.php +++ b/plugin.php @@ -51,11 +51,18 @@ function(): void { ); + $feature_flag_meta = get_option( FeatureFlags::$option_name ); + $flags_list = []; + if(is_array($feature_flag_meta)) { + $flags_list = $feature_flag_meta; + } + + wp_localize_script( 'mr-feature-flags-script', 'mrFeatureFlags', [ - 'flags' => get_option( FeatureFlags::$option_name ), + 'flags' => $flags_list, ] ); @@ -80,16 +87,6 @@ function load_settings_scripts(): void { $plugin_url = plugin_dir_url( MR_FEATURE_FLAGS_PLUGIN_PATH ); $settings_asset_file = require_once plugin_dir_path( MR_FEATURE_FLAGS_PLUGIN_PATH ) . 'build/settings.asset.php'; // @phpcs:ignore - // $feature_flag_meta = get_option( FeatureFlags::$option_name ); - // $feature_flag_env = 'prod'; - // if(isset($feature_flag_meta['env'])) { - // $feature_flag_env = $feature_flag_meta['env']; - // } - - - // if($feature_flag_meta['env'] === '') { - // $feature_flag_env = 'prod'; - // } wp_enqueue_script( 'mr-feature-flags', $plugin_url . 'build/settings.js', @@ -123,30 +120,18 @@ function(string $page): void { true ); - $feature_flag_env = 'prod'; - $feature_flag_meta = get_option( FeatureFlags::$option_name ); - $feature_flags_list = []; - if(isset($feature_flag_meta['flags'])) { - $feature_flags_list = $feature_flag_meta['flags']; + $flags_list = []; + if(is_array($feature_flag_meta)) { + $flags_list = $feature_flag_meta; } - if(isset($feature_flag_meta['env'])) { - $feature_flag_env = $feature_flag_meta['env']; - } - // $feature_flag_env = $feature_flag_meta['env']; - - // if($feature_flag_meta['env'] === '') { - // $feature_flag_env = 'prod'; - // } - wp_localize_script( 'mr-feature-flags-script', 'mrFeatureFlags', [ - 'flags' => $feature_flags_list, - 'env' => $feature_flag_env + 'flags' => $flags_list, ] ); @@ -160,15 +145,6 @@ function(string $page): void { $mr_feature_flags_register_api->register_flags_endpoints(); -// add_action ('init', function() { - -// $request = new \WP_REST_Request( 'GET', '/feature-flags/v1/flags' ); -// $request->set_query_params( [] ); -// $response = rest_do_request( $request ); -// ddd(rest_get_server()->response_to_data( $response, false )); - -// }); - add_filter( 'plugin_action_links_mr-feature-flags/plugin.php', function ( $links ) { @@ -192,4 +168,4 @@ function(string $page): void { ); -// update_option( 'mr_feature_flags1', [ 'env' => 'pre-prod', 'flags' => [["id" => 1, "name" => "Test", "preProdEnabled" => true, "enabled" => false]]] ); +// update_option( 'mr_feature_flags', [ ["id" => 1, "name" => "login", "enabled" => false],["id" => 2, "name" => "Reg", "enabled" => false]] ); diff --git a/src/components/Environment.tsx b/src/components/Environment.tsx deleted file mode 100644 index c02de2d..0000000 --- a/src/components/Environment.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { SelectControl } from '@wordpress/components'; - -export default function ({ env, setEnv }: { env: string; setEnv: any }) { - return ( -
- setEnv(value)} - value={env} - options={[ - { - disabled: true, - label: 'Set environment', - value: '', - }, - { - label: 'Pre Production', - value: 'pre-prod', - }, - { - label: 'Production', - value: 'prod', - }, - ]} - /> -
- ); -} diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 5b72f5c..6a75094 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -5,16 +5,13 @@ export default function (): JSX.Element {

Flag Name

- -

Pre-Prod

+ +

Status

- -

Prod

-
- +

SDK Settings

- +

Delete Flag

diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index b6c5740..cdf87aa 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -5,22 +5,17 @@ import { Flag } from '../../types'; import SubmitControls from './SubmitControls'; import { getFlags } from '../utils'; import Header from './Header'; -import Environment from './Environment'; const Layout = (): JSX.Element => { const [flags, setFlags] = useState(undefined); const [isLoading, setIsLoading] = useState(true); - const [env, setEnv] = useState(''); useEffect(() => { const logFlags = async () => { - const result = await getFlags(); - // console.log(result); - if (result.env) { - setEnv(result.env); - } - if (result.flags) { - setFlags(result.flags); + const fetchedFlags = await getFlags(); + + if (fetchedFlags) { + setFlags(fetchedFlags); } setIsLoading(false); }; @@ -36,7 +31,6 @@ const Layout = (): JSX.Element => {

Feature Flags settings

- {lastFlag ?
: ''} {isLoading ? (
@@ -63,7 +57,6 @@ const Layout = (): JSX.Element => { isNew={false} lastFlag={lastFlag} disableSave={disableSave} - env={env} /> )}
diff --git a/src/components/LineItem.tsx b/src/components/LineItem.tsx index 093c341..ae6bdca 100644 --- a/src/components/LineItem.tsx +++ b/src/components/LineItem.tsx @@ -93,14 +93,6 @@ const LineItem = ({ onChange={(value) => handleFlagEdit(value, item.id)} /> - - - handleFlagToggle(item.id, 'preProd') - } - /> - - + diff --git a/src/components/SdkModal.tsx b/src/components/SdkModal.tsx index 68a3f83..93d24e3 100644 --- a/src/components/SdkModal.tsx +++ b/src/components/SdkModal.tsx @@ -1,33 +1,102 @@ import { Modal, Button } from '@wordpress/components'; import Snippet from './Snippet'; +import { useMemo, useState, useEffect } from '@wordpress/element'; +import { useCopyToClipboard } from '@wordpress/compose'; const SdkModal = (props: any): JSX.Element => { const { item, closeSdkModal } = props; + const [hasJsCopied, setHasJsCopied] = useState(false); + const [hasPhpCopied, setHasPhpCopied] = useState(false); - const jsSnippet = ` -//For Pre production environment -if (window.mrFeatureFlags.isEnabled('${item.name}', 'pre-prod')) { - // js code goes here... -} + useEffect(() => { + let jsTimeout: number | null = null; + let phpTimeout: number | null = null; -//For Production environment -if (window.mrFeatureFlags.isEnabled('${item.name}')) { - // js code goes here... -} -`; + if (hasJsCopied) { + jsTimeout = setTimeout(() => { + setHasJsCopied(false); + }, 4000); + } - const phpSnippet = `if ( /\MR/\FeatureFlags/\FeatureFlags::is_enabled( '${item.name}' ) ) { + if (hasPhpCopied) { + phpTimeout = setTimeout(() => { + setHasPhpCopied(false); + }, 4000); + } + return () => { + if (jsTimeout) { + window.clearTimeout(jsTimeout); + } + if (phpTimeout) { + window.clearTimeout(phpTimeout); + } + }; + }, [hasJsCopied, hasPhpCopied]); + + const jsSnippet = useMemo(() => { + return `import domReady from '@wordpress/dom-ready'; +domReady(function () { + if (window.mrFeatureFlags.isEnabled('${item.name}')) { + // js code goes here... + } + });`; + }, [item.name]); + + const phpSnippet = useMemo(() => { + return `if ( MR\\FeatureFlags\\FeatureFlags::is_enabled( '${item.name}' ) ) { // php code goes here... }`; + }, [item.name]); + + const jsRef = useCopyToClipboard(jsSnippet, onJsCopy); + + function onJsCopy() { + setHasJsCopied(true); + } + + const phpRef = useCopyToClipboard(phpSnippet, onPhpCopy); + + function onPhpCopy() { + setHasPhpCopied(true); + } + return ( -

JS Snippet

- -

PHP Snippet

- - +
+

PHP Snippet

+
+
+

JS Snippet

+
); }; diff --git a/src/components/SubmitControls.tsx b/src/components/SubmitControls.tsx index 0fdaa4e..838beaf 100644 --- a/src/components/SubmitControls.tsx +++ b/src/components/SubmitControls.tsx @@ -6,7 +6,7 @@ import Notices from './Snackbar'; import { dispatch } from '@wordpress/data'; const SubmitControls = (props: any): JSX.Element => { - const { isNew, flags, setFlags, lastFlag, disableSave, env } = props; + const { isNew, flags, setFlags, lastFlag, disableSave } = props; const [isSaving, setIsSaving] = useState(false); const handleNewFlag = () => { @@ -14,7 +14,6 @@ const SubmitControls = (props: any): JSX.Element => { id: lastFlag + 1, name: '', enabled: false, - preProdEnabled: true, }; let latestFlags = []; @@ -24,7 +23,6 @@ const SubmitControls = (props: any): JSX.Element => { } else { latestFlags = [newFlag]; } - // const clonedFlags = [...flags, newFlag]; setFlags(latestFlags); }; @@ -34,11 +32,8 @@ const SubmitControls = (props: any): JSX.Element => { const cleanFlags: Flag[] = flags.filter( (item: Flag) => item.name !== '' ); - const latestEnv: string = env; - console.log({ env: latestEnv, flags: cleanFlags }); - // return; - await updateFlags({ env: latestEnv, flags: cleanFlags }); + await updateFlags({ ...cleanFlags }); setIsSaving(false); diff --git a/src/index.ts b/src/index.ts index d287761..ff873d4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,19 +1,14 @@ const { mrFeatureFlags } = window; import { Flag } from '../types'; -mrFeatureFlags.isEnabled = (flag: string, env = 'prod') => { - let envFlag = 'enabled'; - if (env === 'pre-prod') { - envFlag = 'preProdEnabled'; - } +mrFeatureFlags.isEnabled = (flag: string) => { const isFlagExist: Flag | undefined = mrFeatureFlags.flags.find( (item: Flag) => { - //@ts-ignore - return item.name === flag && item[envFlag] === true; + return item.name === flag && item.enabled === true; } ); - if (isFlagExist?.name) return true; + if (isFlagExist) return true; return false; }; From ba3a90429bb81b7d812069917223cd386e4a8162 Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Thu, 23 Mar 2023 16:58:50 +0000 Subject: [PATCH 8/9] Adds focus for new flag name --- src/components/Layout.tsx | 1 + src/components/LineItem.tsx | 11 ++++++++++- src/components/SdkModal.tsx | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index cdf87aa..9e61a9b 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -17,6 +17,7 @@ const Layout = (): JSX.Element => { if (fetchedFlags) { setFlags(fetchedFlags); } + setIsLoading(false); }; logFlags(); diff --git a/src/components/LineItem.tsx b/src/components/LineItem.tsx index ae6bdca..e338bd5 100644 --- a/src/components/LineItem.tsx +++ b/src/components/LineItem.tsx @@ -6,7 +6,7 @@ import { Button, BaseControl, } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import { useState, useRef, useEffect } from '@wordpress/element'; import { Flag } from '../../types'; import DeleteModal from './DeleteModal'; import SdkModal from './SdkModal'; @@ -23,6 +23,14 @@ const LineItem = ({ const [hasError, setHasError] = useState(false); + const inputRef = useRef(null); + + useEffect(() => { + if (inputRef.current && '' === item.name) { + inputRef.current.focus(); + } + }, [inputRef, item]); + const handleDeleteFlag = (flagId: number) => { const updatedFlags = flags.filter((flag: Flag) => flag.id !== flagId); setFlags(updatedFlags); @@ -89,6 +97,7 @@ const LineItem = ({ handleFlagEdit(value, item.id)} /> diff --git a/src/components/SdkModal.tsx b/src/components/SdkModal.tsx index 93d24e3..bf1fc1f 100644 --- a/src/components/SdkModal.tsx +++ b/src/components/SdkModal.tsx @@ -71,7 +71,7 @@ domReady(function () { right: 40, width: 40, height: 40, - bottom: 45, + top: 142, color: 'darkgray', }} isPressed={false} From a24209530c0698f733c1f8ff4ad1cd59db074eef Mon Sep 17 00:00:00 2001 From: Mohan Raj Date: Thu, 23 Mar 2023 17:29:59 +0000 Subject: [PATCH 9/9] Adds type for layout component --- src/components/LineItem.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/LineItem.tsx b/src/components/LineItem.tsx index e338bd5..f851220 100644 --- a/src/components/LineItem.tsx +++ b/src/components/LineItem.tsx @@ -11,12 +11,19 @@ import { Flag } from '../../types'; import DeleteModal from './DeleteModal'; import SdkModal from './SdkModal'; +interface LineItemProps { + flags: Flag[]; + setFlags: (flags: Flag[]) => void; + item: Flag; + setDisableSave: (toggle: boolean) => void; +} + const LineItem = ({ flags, setFlags, item, setDisableSave, -}: any): JSX.Element => { +}: LineItemProps): JSX.Element => { const [isOpen, setOpen] = useState(false); const [isSdkOpen, setIsSdkOpen] = useState(false); @@ -135,13 +142,13 @@ const LineItem = ({ {} {}