diff --git a/src/components/Form/CodeEditor/CodeEditor.tsx b/src/components/Form/CodeEditor/CodeEditor.tsx index e0ad33d42c6ab8305d69c99c2e39fd112dd55867..b395f8bd50fb790838349f8bbf1d159f0c3a63b3 100644 --- a/src/components/Form/CodeEditor/CodeEditor.tsx +++ b/src/components/Form/CodeEditor/CodeEditor.tsx @@ -4,7 +4,7 @@ import { useController } from 'react-hook-form'; import Editor from 'react-simple-code-editor'; /* eslint-disable react/react-in-jsx-scope */ -export const CodeEditor = ({ control, name, required }: CodeEditorProps) => { +export const CodeEditor = ({ control, name, required, disabled = false }: CodeEditorProps) => { const { field, // fieldState: { invalid, isTouched, isDirty }, @@ -25,6 +25,7 @@ export const CodeEditor = ({ control, name, required }: CodeEditorProps) => { preClassName="font-mono whitespace-normal font-light" textareaClassName="font-mono overflow-auto font-light" className="font-mono text-sm font-light" + disabled={disabled} /> </> ); @@ -34,4 +35,5 @@ type CodeEditorProps = { control: any; name: string; required?: boolean; + disabled?: boolean; }; diff --git a/src/components/Tabs/Tabs.tsx b/src/components/Tabs/Tabs.tsx index 850dc1779b6bf76805d6e098822f586976aadaf6..92a1852f6a4466f4b11114ba44722025cb6724a8 100644 --- a/src/components/Tabs/Tabs.tsx +++ b/src/components/Tabs/Tabs.tsx @@ -2,11 +2,14 @@ import React, { useState } from 'react'; import { TabPanel } from './TabPanel'; import { TabsProps } from './types'; -export const Tabs = ({ tabs }: TabsProps) => { +export const Tabs = ({ tabs, onTabClick }: TabsProps) => { const [activeTabIndex, setActiveTabIndex] = useState<number>(0); const handleTabPress = (index: number) => () => { setActiveTabIndex(index); + if (onTabClick) { + onTabClick(index); + } }; function classNames(...classes: any) { diff --git a/src/components/Tabs/types.ts b/src/components/Tabs/types.ts index 342266acd220d0ea74eb7af77183e8df4ab466f2..00584fd15fc4710b35ad50251954b8e4f08624db 100644 --- a/src/components/Tabs/types.ts +++ b/src/components/Tabs/types.ts @@ -6,6 +6,7 @@ type Tab = { export interface TabsProps { tabs: Tab[]; + onTabClick?: (index: number) => void; } export interface TabPanelProps { diff --git a/src/modules/apps/components/AdvancedTab/AdvancedTab.tsx b/src/modules/apps/components/AdvancedTab/AdvancedTab.tsx index d538172d9c0267a848f8abd529b0620293804353..384392e041f4a590aedb5d6c2280ec8bae3604d7 100644 --- a/src/modules/apps/components/AdvancedTab/AdvancedTab.tsx +++ b/src/modules/apps/components/AdvancedTab/AdvancedTab.tsx @@ -1,20 +1,33 @@ -import React, { Fragment } from 'react'; +import React from 'react'; +import _ from 'lodash'; import Editor from 'react-simple-code-editor'; -import { Menu, Transition } from '@headlessui/react'; -import { ChevronDownIcon } from '@heroicons/react/solid'; +// import { Menu, Transition } from '@headlessui/react'; +// import { ChevronDownIcon } from '@heroicons/react/solid'; import { highlight, languages } from 'prismjs'; import 'prismjs/components/prism-clike'; import 'prismjs/components/prism-yaml'; import 'prismjs/themes/prism.css'; +import { showToast } from 'src/common/util/show-toast'; +import { useApps } from 'src/services/apps'; import { initialEditorYaml } from '../../consts'; -// import { Secrets } from './components'; - -function classNames(...classes: any) { - return classes.filter(Boolean).join(' '); -} export const AdvancedTab = () => { const [code, setCode] = React.useState(initialEditorYaml); + const { app, editApp } = useApps(); + + const resetCode = () => { + setCode(initialEditorYaml); + showToast('Code was reset.'); + }; + + const vertifyCode = () => { + // call yaml verification (only format) + // const result = validateSchema(code, {}); + }; + + const saveChanges = () => { + editApp({ ...app, configuration: code }); + }; return ( <> @@ -22,41 +35,24 @@ export const AdvancedTab = () => { <h1 className="text-2xl leading-6 font-medium text-gray-900">Configuration</h1> </div> <div className="grid grid-flow-col grid-cols-2 gap-8"> - <div> - <div className="bg-gray-100 overflow-hidden rounded-lg"> - <div className="px-4 h-16 sm:px-6 bg-gray-200 flex items-center"> - <span className="text-gray-600 text-lg leading-6 font-medium">Current Configuration</span> - </div> - <div className="px-4 py-5 sm:p-6 overflow-x-auto"> - <pre className="font-mono text-sm font-light"> - {`luck: except -natural: still -near: though -search: - - feature - - - 1980732354.689713 - - hour - - butter: - ordinary: 995901949.8974948 - teeth: true - whole: - - -952367353 - - - talk: -1773961379 - temperature: false - oxygen: true - laugh: - flag: - in: 2144751662 - hospital: -1544066384.1973226 - law: congress - great: stomach`} - </pre> - </div> + <div className="bg-gray-100 overflow-hidden rounded-lg"> + <div className="px-4 h-16 sm:px-6 bg-gray-200 flex items-center"> + <span className="text-gray-600 text-lg leading-6 font-medium">Current Configuration</span> + </div> + <div className="px-4 py-5 sm:p-6 overflow-x-auto"> + <Editor + value={initialEditorYaml} + onValueChange={_.noop} + highlight={(value) => highlight(value, languages.js, 'yaml')} + preClassName="font-mono text-sm font-light" + textareaClassName="font-mono overflow-auto font-light" + className="font-mono text-sm font-light" + disabled + /> </div> </div> - <div> - <div> - <div className="px-4 h-16 sm:px-6 bg-gray-200 flex justify-between items-center rounded-t-lg"> + <div className="overflow-hidden rounded-lg"> + {/* <div className="px-4 h-16 sm:px-6 bg-gray-200 flex justify-between items-center rounded-t-lg"> <span className="text-gray-600 text-lg leading-6 font-medium">Edit Configuration</span> <Menu as="div" className="relative inline-block text-left"> @@ -121,30 +117,34 @@ search: </Menu.Items> </Transition> </Menu> - </div> - <div className="px-4 py-5 sm:p-6 border border-t-0 border-gray-200"> - <Editor - value={code} - onValueChange={(value) => setCode(value)} - highlight={(value) => highlight(value, languages.js, 'yaml')} - preClassName="font-mono whitespace-normal font-light" - textareaClassName="font-mono overflow-auto font-light" - className="font-mono text-sm font-light" - /> - </div> + </div> */} + <div className="px-4 h-16 sm:px-6 bg-gray-200 flex items-center"> + <span className="text-gray-600 text-lg leading-6 font-medium">Edit Configuration</span> + </div> + <div className="px-4 py-5 sm:p-6 border border-t-0 border-gray-200"> + <Editor + value={code} + onValueChange={(value) => setCode(value)} + highlight={(value) => highlight(value, languages.js, 'yaml')} + preClassName="font-mono whitespace-normal font-light" + textareaClassName="font-mono overflow-auto font-light" + className="font-mono text-sm font-light" + /> </div> </div> </div> <div className="flex justify-end mt-10"> <button type="button" + onClick={resetCode} className="mr-3 inline-flex items-center px-4 py-2 border border-gray-200 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500" > - Cancel + Reset </button> <button type="button" + onClick={vertifyCode} className="mr-3 inline-flex items-center px-4 py-2 shadow-sm text-sm font-medium rounded-md text-primary-700 bg-primary-100 hover:bg-primary-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500" > Verify @@ -152,6 +152,7 @@ search: <button type="button" + onClick={saveChanges} className="inline-flex items-center px-4 py-2 shadow-sm text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500" > Save changes diff --git a/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx b/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx index 3c6f7eec178e8fdf4e34883217f9e94d120fbf5d..42d0ad48b6cd4c6c8a0f7107b9325177ea7cc921 100644 --- a/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx +++ b/src/modules/apps/components/AppInstallModal/AppInstallModal.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import _ from 'lodash'; -import { AppForm, useApps } from 'src/services/apps'; -import { Modal, Tabs } from 'src/components'; -import { CodeEditor, Input } from 'src/components/Form'; +import { App, useApps } from 'src/services/apps'; +import { Modal } from 'src/components'; +import { Input } from 'src/components/Form'; import { appAccessList } from 'src/components/UserModal/consts'; import { AppInstallModalProps } from './types'; import { initialAppForm, initialCode } from './consts'; @@ -12,7 +12,7 @@ export const AppInstallModal = ({ open, onClose, appSlug }: AppInstallModalProps const [appName, setAppName] = useState(''); const { app, appLoading, installApp, loadApp, clearSelectedApp } = useApps(); - const { control, reset, handleSubmit } = useForm<AppForm>({ + const { control, reset, handleSubmit } = useForm<App>({ defaultValues: initialAppForm, }); @@ -62,36 +62,6 @@ export const AppInstallModal = ({ open, onClose, appSlug }: AppInstallModalProps } }; - const renderSubdomain = () => { - return ( - <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6"> - <div className="sm:col-span-3"> - <Input control={control} name="subdomain" label="Subdomain" onKeyPress={handleKeyPress} required={false} /> - </div> - </div> - ); - }; - - const renderConfiguration = () => { - return ( - <div> - <div className="bg-gray-100 overflow-hidden rounded-lg"> - <div className="px-4 h-16 sm:px-6 bg-gray-200 flex items-center"> - <span className="text-gray-600 text-lg leading-6 font-medium">App Configuration</span> - </div> - <div className="px-4 py-5 sm:p-6 overflow-x-auto"> - <CodeEditor control={control} name="configuration" /> - </div> - </div> - </div> - ); - }; - - const tabs = [ - { name: 'Subdomain', component: renderSubdomain() }, - { name: 'Advanced Configuration', component: renderConfiguration() }, - ]; - return ( <> <Modal onClose={handleClose} open={open} onSave={handleSave} isLoading={appLoading} useCancelButton> @@ -102,8 +72,16 @@ export const AppInstallModal = ({ open, onClose, appSlug }: AppInstallModalProps <h3 className="text-lg leading-6 font-medium text-gray-900">Install app {appName}</h3> </div> - <div className="px-4 py-5 sm:p-6"> - <Tabs tabs={tabs} /> + <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6"> + <div className="sm:col-span-3"> + <Input + control={control} + name="subdomain" + label="Subdomain" + onKeyPress={handleKeyPress} + required={false} + /> + </div> </div> </div> </div> diff --git a/src/modules/apps/components/AppInstallModal/consts.ts b/src/modules/apps/components/AppInstallModal/consts.ts index ee4b0b4682866a8763eb8dd5cfec1e8694824692..c3d5fa9dc111f7caef2e2592db075b9e9680dd80 100644 --- a/src/modules/apps/components/AppInstallModal/consts.ts +++ b/src/modules/apps/components/AppInstallModal/consts.ts @@ -1,4 +1,4 @@ -import { AppForm } from 'src/services/apps'; +import { App } from 'src/services/apps'; export const initialCode = `luck: except natural: still @@ -24,5 +24,4 @@ search: export const initialAppForm = { subdomain: '', - configuration: initialCode, -} as AppForm; +} as App; diff --git a/src/modules/apps/consts.tsx b/src/modules/apps/consts.tsx index 4172b9c6eafa68ef14618ea75d13c1ca063b3a07..16380078fce7fab2032df74d5379eb1e2f2ef867 100644 --- a/src/modules/apps/consts.tsx +++ b/src/modules/apps/consts.tsx @@ -3,8 +3,7 @@ import { CogIcon, PlusCircleIcon } from '@heroicons/react/outline'; import _ from 'lodash'; import { AppStatus } from 'src/services/apps'; -export const initialEditorYaml = () => { - return `luck: except +export const initialEditorYaml = `luck: except natural: still near: though search: @@ -25,7 +24,6 @@ search: hospital: -1544066384.1973226 law: congress great: stomach`; -}; const tableConsts = [ { diff --git a/src/services/apps/transformations.ts b/src/services/apps/transformations.ts index 0d66b28da62cabb628ce275d592569e52efd66e4..aa4f0ede8ae8ca21f490b3eb8cfca69ec3ea9ae1 100644 --- a/src/services/apps/transformations.ts +++ b/src/services/apps/transformations.ts @@ -1,4 +1,4 @@ -import { App, AppStatus, AppForm } from './types'; +import { App, AppStatus } from './types'; const transformAppStatus = (status: string) => { switch (status) { @@ -24,13 +24,14 @@ export const transformApp = (response: any): App => { }; }; -export const transformAppRequest = (data: AppForm) => { +export const transformAppRequest = (data: App) => { return { automatic_updates: data.automaticUpdates, + configuration: data.configuration, }; }; -export const transformInstallAppRequest = (data: AppForm) => { +export const transformInstallAppRequest = (data: App) => { return { subdomain: data.subdomain, configuration: data.configuration, diff --git a/src/services/apps/types.ts b/src/services/apps/types.ts index e3af6aad53f81ca5b0fdca84372cf19288b036c1..317f1718be6db86dcd0006fed0f978c60f6b548d 100644 --- a/src/services/apps/types.ts +++ b/src/services/apps/types.ts @@ -5,10 +5,7 @@ export interface App { status?: AppStatus; subdomain?: string; automaticUpdates: boolean; -} - -export interface AppForm extends App { - configuration: string; + configuration?: string; } export interface DisableAppForm {