diff --git a/source/javascripts/components/ConfigurationYmlSource/ConfigurationYmlSourceDialog.tsx b/source/javascripts/components/ConfigurationYmlSource/ConfigurationYmlSourceDialog.tsx index 3f45d65fb..991750466 100644 --- a/source/javascripts/components/ConfigurationYmlSource/ConfigurationYmlSourceDialog.tsx +++ b/source/javascripts/components/ConfigurationYmlSource/ConfigurationYmlSourceDialog.tsx @@ -26,7 +26,7 @@ import { AppConfig } from '@/models/AppConfig'; import DateFormatter from '@/utils/dateFormatter'; import { segmentTrack } from '@/utils/segmentTracking'; import BitriseYmlApi from '@/core/api/BitriseYmlApi'; -import { useFormattedYml } from '../common/RepoYmlStorageActions'; +import useFormattedYml from '@/hooks/useFormattedYml'; const ErrorNotification = ({ status, message }: { status?: number; message: string }) => { let action: NotificationProps['action']; diff --git a/source/javascripts/components/UpdateConfigurationDialog/UpdateConfigurationDialog.tsx b/source/javascripts/components/UpdateConfigurationDialog/UpdateConfigurationDialog.tsx index c4fcb6258..4019f3708 100644 --- a/source/javascripts/components/UpdateConfigurationDialog/UpdateConfigurationDialog.tsx +++ b/source/javascripts/components/UpdateConfigurationDialog/UpdateConfigurationDialog.tsx @@ -3,10 +3,10 @@ import { Box, Button, Dialog, DialogBody, DialogFooter, Notification, Text, useT import CopyToClipboard from 'react-copy-to-clipboard'; import { AppConfig } from '@/models/AppConfig'; import { segmentTrack } from '@/utils/segmentTracking'; +import useFormattedYml from '@/hooks/useFormattedYml'; import useGetAppConfigFromRepoCallback from '../../hooks/api/useGetAppConfigFromRepoCallback'; import YmlNotFoundInRepositoryError from '../common/notifications/YmlNotFoundInRepositoryError'; import YmlInRepositoryInvalidError from '../common/notifications/YmlInRepositoryInvalidError'; -import { useFormattedYml } from '../common/RepoYmlStorageActions'; type UpdateConfigurationDialogProps = { onClose: () => void; diff --git a/source/javascripts/components/common/InlineLink.tsx b/source/javascripts/components/common/InlineLink.tsx deleted file mode 100644 index bf445aad2..000000000 --- a/source/javascripts/components/common/InlineLink.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FC } from 'react'; -import { Link, Text, TextProps, TypeColors } from '@bitrise/bitkit'; - -type InlineLinkProps = { - text: string; - url: string; - color?: TypeColors; - underline?: boolean; -} & TextProps; - -const InlineLink: FC = (props: InlineLinkProps) => { - const { text, url, color = 'grape-3', underline, ...rest } = props; - - return ( - - - {text} - - - ); -}; - -export default InlineLink; diff --git a/source/javascripts/components/common/RepoYmlStorageActions.tsx b/source/javascripts/components/common/RepoYmlStorageActions.tsx deleted file mode 100644 index a150d60fc..000000000 --- a/source/javascripts/components/common/RepoYmlStorageActions.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { useEffect, useRef, useState } from 'react'; -import { Box, Icon, Link, Notification, Text } from '@bitrise/bitkit'; -import CopyToClipboard from 'react-copy-to-clipboard'; - -import { AppConfig } from '@/models/AppConfig'; -import BitriseYmlApi from '@/core/api/BitriseYmlApi'; -import useMonolithApiCallback from '@/hooks/api/useMonolithApiCallback'; - -type RepoYmlStorageActionsProps = { - appConfig: AppConfig | string; -}; - -const identityParser = (result: string): any => result; - -export const useFormattedYml = (appConfig: AppConfig): string => { - const [yml, setYml] = useState(typeof appConfig === 'string' ? appConfig : ''); - const formatAppConfigRef = useRef<(options?: RequestInit) => void>(); - const { failed, result, call } = useMonolithApiCallback( - '/api/cli/format', - { - method: 'POST', - headers: { - Accept: 'application/x-yaml, application/json', - }, - }, - identityParser, - ); - - // NOTE: call function isn't referentially stable - useEffect(() => { - formatAppConfigRef.current = call; - }); - - // Set the js-yaml value as fallback, kick off format endpoint - useEffect(() => { - const yaml = BitriseYmlApi.toYml(appConfig); - setYml(yaml); - - if (typeof appConfig === 'object') { - formatAppConfigRef.current?.({ - body: JSON.stringify({ - app_config_datastore_yaml: yaml, - }), - }); - } - }, [appConfig]); - - // When result finally comes in override the fallback value - useEffect(() => { - if (result && !failed) { - setYml(result); - } - }, [result, failed]); - - return yml; -}; - -const RepoYmlStorageActions = ({ appConfig }: RepoYmlStorageActionsProps): JSX.Element => { - const [actionSelected, setActionSelected] = useState(null); - const [clearActionTimeout, setClearActionTimeout] = useState(); - - const yml = useFormattedYml(appConfig); - - const selectAction = (actionName: string): void => { - setActionSelected(actionName); - - if (clearActionTimeout) { - window.clearTimeout(clearActionTimeout); - } - - setClearActionTimeout(window.setTimeout(() => setActionSelected(null), 5000)); - }; - - return ( - - - selectAction('clipboard')}> - - - Copy the content of the current bitrise.yml file to the clipboard - - - - selectAction('download')} - > - - - Download the bitrise.yml file - - - - - {actionSelected && ( - - {actionSelected === 'clipboard' - ? 'Copied the content of the current bitrise.yml file to the clipboard. ' - : 'Downloading bitrise.yml. '} - Commit the file to the app's repository before updating the setting. - - )} - - ); -}; - -export default RepoYmlStorageActions; diff --git a/source/javascripts/components/common/notifications/CreatingYmlOnWebsiteProgress.tsx b/source/javascripts/components/common/notifications/CreatingYmlOnWebsiteProgress.tsx deleted file mode 100644 index 6c0a827a8..000000000 --- a/source/javascripts/components/common/notifications/CreatingYmlOnWebsiteProgress.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { Notification } from '@bitrise/bitkit'; - -const CreatingYmlOnWebsiteProgress = (): JSX.Element => ( - {window.strings.yml.store_on_website.loading} -); - -export default CreatingYmlOnWebsiteProgress; diff --git a/source/javascripts/components/common/notifications/LookingForYmlInRepoProgress.tsx b/source/javascripts/components/common/notifications/LookingForYmlInRepoProgress.tsx deleted file mode 100644 index abf2154a8..000000000 --- a/source/javascripts/components/common/notifications/LookingForYmlInRepoProgress.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { Notification } from '@bitrise/bitkit'; - -const LookingForYmlInRepoProgress = (): JSX.Element => ( - {window.strings.yml.store_in_repository.loading} -); - -export default LookingForYmlInRepoProgress; diff --git a/source/javascripts/components/common/notifications/ValidatingYmlInRepoProgress.tsx b/source/javascripts/components/common/notifications/ValidatingYmlInRepoProgress.tsx deleted file mode 100644 index 25f932492..000000000 --- a/source/javascripts/components/common/notifications/ValidatingYmlInRepoProgress.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { Notification } from '@bitrise/bitkit'; - -const ValidatingYmlInRepoProgress = (): JSX.Element => ( - {window.strings.yml.store_in_repository.validation_loading} -); - -export default ValidatingYmlInRepoProgress; diff --git a/source/javascripts/hooks/api/useGetAppConfigCallback.ts b/source/javascripts/hooks/api/useGetAppConfigCallback.ts deleted file mode 100644 index 7314b7af3..000000000 --- a/source/javascripts/hooks/api/useGetAppConfigCallback.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AppConfig } from '../../models/AppConfig'; -import useMonolithApiCallback, { MonolithError } from './useMonolithApiCallback'; - -export interface FetchResponse { - appConfig: AppConfig | undefined; - getAppConfigStatus?: number; - getAppConfigLoading: boolean; - getAppConfigFailed: MonolithError | undefined; - getAppConfig: () => void; -} - -export default function useGetAppConfigCallback(appSlug: string): FetchResponse { - const { - statusCode: getAppConfigStatus, - loading: getAppConfigLoading, - failed: getAppConfigFailed, - call: getAppConfig, - result: appConfig, - } = useMonolithApiCallback(`/api/app/${appSlug}/config`); - - return { - getAppConfigStatus, - getAppConfigLoading, - getAppConfigFailed, - getAppConfig, - appConfig, - }; -} diff --git a/source/javascripts/hooks/useFormattedYml.ts b/source/javascripts/hooks/useFormattedYml.ts new file mode 100644 index 000000000..4061d7286 --- /dev/null +++ b/source/javascripts/hooks/useFormattedYml.ts @@ -0,0 +1,52 @@ +import { useEffect, useRef, useState } from 'react'; + +import { AppConfig } from '@/models/AppConfig'; +import BitriseYmlApi from '@/core/api/BitriseYmlApi'; +import useMonolithApiCallback from '@/hooks/api/useMonolithApiCallback'; + +const identityParser = (result: string): any => result; + +const useFormattedYml = (appConfig: AppConfig): string => { + const [yml, setYml] = useState(typeof appConfig === 'string' ? appConfig : ''); + const formatAppConfigRef = useRef<(options?: RequestInit) => void>(); + const { failed, result, call } = useMonolithApiCallback( + '/api/cli/format', + { + method: 'POST', + headers: { + Accept: 'application/x-yaml, application/json', + }, + }, + identityParser, + ); + + // NOTE: call function isn't referentially stable + useEffect(() => { + formatAppConfigRef.current = call; + }); + + // Set the js-yaml value as fallback, kick off format endpoint + useEffect(() => { + const yaml = BitriseYmlApi.toYml(appConfig); + setYml(yaml); + + if (typeof appConfig === 'object') { + formatAppConfigRef.current?.({ + body: JSON.stringify({ + app_config_datastore_yaml: yaml, + }), + }); + } + }, [appConfig]); + + // When result finally comes in override the fallback value + useEffect(() => { + if (result && !failed) { + setYml(result); + } + }, [result, failed]); + + return yml; +}; + +export default useFormattedYml; diff --git a/source/javascripts/utils/changeCase.ts b/source/javascripts/utils/changeCase.ts deleted file mode 100644 index df7eece52..000000000 --- a/source/javascripts/utils/changeCase.ts +++ /dev/null @@ -1,29 +0,0 @@ -import camelCase from 'lodash/camelCase'; -import snakeCase from 'lodash/snakeCase'; -import reduce from 'lodash/reduce'; -import isArray from 'lodash/isArray'; -import isPlainObject from 'lodash/isPlainObject'; - -type UnknownObject = { [s: string]: unknown }; - -const transformKeysDeep = (input: unknown, transformer: (key: string) => string): unknown => { - if (isArray(input)) { - return input.map((child) => transformKeysDeep(child, transformer)); - } - - if (isPlainObject(input)) { - return reduce( - input as UnknownObject, - (result: UnknownObject, value: unknown, key: string) => ({ - ...result, - [transformer(key)]: transformKeysDeep(value, transformer), - }), - {}, - ); - } - - return input; -}; - -export const camelCaseKeys = (input: unknown): T => transformKeysDeep(input, camelCase) as T; -export const snakeCaseKeys = (input: unknown): T => transformKeysDeep(input, snakeCase) as T;