From 9715d0af04fb3f9e442325f4a7fe31953feb8f8f Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Fri, 20 Dec 2024 20:15:33 +0100 Subject: [PATCH 1/4] fix props export Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> --- ui/src/components/CheckBoxComponent/CheckBoxComponent.tsx | 2 +- ui/src/components/DeleteModal/DeleteModal.tsx | 2 +- ui/src/components/EntityPage/EntityPage.tsx | 2 +- ui/src/components/TextAreaComponent/TextAreaComponent.tsx | 2 +- ui/src/components/TextComponent/TextComponent.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/src/components/CheckBoxComponent/CheckBoxComponent.tsx b/ui/src/components/CheckBoxComponent/CheckBoxComponent.tsx index 514060e82..ca9a05732 100644 --- a/ui/src/components/CheckBoxComponent/CheckBoxComponent.tsx +++ b/ui/src/components/CheckBoxComponent/CheckBoxComponent.tsx @@ -2,7 +2,7 @@ import React from 'react'; import Switch from '@splunk/react-ui/Switch'; import { isFalse } from '../../util/considerFalseAndTruthy'; -interface CheckBoxComponentProps { +export interface CheckBoxComponentProps { value: 0 | 1 | boolean; handleChange: (field: string, value: 0 | 1) => void; field: string; diff --git a/ui/src/components/DeleteModal/DeleteModal.tsx b/ui/src/components/DeleteModal/DeleteModal.tsx index c9487ecf0..7558438aa 100644 --- a/ui/src/components/DeleteModal/DeleteModal.tsx +++ b/ui/src/components/DeleteModal/DeleteModal.tsx @@ -17,7 +17,7 @@ const ModalWrapper = styled(Modal)` width: 800px; `; -interface DeleteModalProps { +export interface DeleteModalProps { page: StandardPages; handleRequestClose: () => void; serviceName: string; diff --git a/ui/src/components/EntityPage/EntityPage.tsx b/ui/src/components/EntityPage/EntityPage.tsx index dff3b1cd3..dd1b88fe2 100644 --- a/ui/src/components/EntityPage/EntityPage.tsx +++ b/ui/src/components/EntityPage/EntityPage.tsx @@ -17,7 +17,7 @@ import { StandardPages } from '../../types/components/shareableTypes'; import PageContext from '../../context/PageContext'; import { UCCButton } from '../UCCButton/UCCButton'; -interface EntityPageProps { +export interface EntityPageProps { handleRequestClose: () => void; serviceName: string; mode: Mode; diff --git a/ui/src/components/TextAreaComponent/TextAreaComponent.tsx b/ui/src/components/TextAreaComponent/TextAreaComponent.tsx index ee2b2f24b..0b6914624 100644 --- a/ui/src/components/TextAreaComponent/TextAreaComponent.tsx +++ b/ui/src/components/TextAreaComponent/TextAreaComponent.tsx @@ -6,7 +6,7 @@ const TextWrapper = styled(TextArea)` width: 320px !important; `; -interface TextAreaComponentProps { +export interface TextAreaComponentProps { id?: string; value: string | number; handleChange: (field: string, value: string) => void; diff --git a/ui/src/components/TextComponent/TextComponent.tsx b/ui/src/components/TextComponent/TextComponent.tsx index 70e63e8f0..602a74f75 100755 --- a/ui/src/components/TextComponent/TextComponent.tsx +++ b/ui/src/components/TextComponent/TextComponent.tsx @@ -6,7 +6,7 @@ const TextWrapper = styled(Text)` width: 320px !important; `; -interface TextComponentProps { +export interface TextComponentProps { // Number is expected if provided number in globalConfig.json instead of a string. value: string | number; handleChange: (field: string, value: string | number) => void; From 8f474531cc0cc959eeef29442e5b016ca7355978 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Fri, 20 Dec 2024 20:19:50 +0100 Subject: [PATCH 2/4] change interfaces to abstract classes for custom components Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> --- .../components/BaseFormView/BaseFormView.tsx | 12 ++-- .../stories/ControlWrapper.stories.ts | 2 +- .../test/ControlWrapper.test.tsx | 2 +- .../CustomControl/CustomControl.tsx | 54 ++++++---------- .../CustomControl/CustomControl.types.ts | 8 +++ .../CustomControl/CustomControlBase.ts | 43 +++++++++++++ ui/src/components/CustomTab/CustomTab.tsx | 11 +--- ui/src/components/CustomTab/CustomTabBase.ts | 19 ++++++ ui/src/types/components/BaseFormTypes.ts | 46 +------------- ui/src/types/components/CustomHookClass.ts | 61 +++++++++++++++++++ 10 files changed, 164 insertions(+), 94 deletions(-) create mode 100644 ui/src/components/CustomControl/CustomControl.types.ts create mode 100644 ui/src/components/CustomControl/CustomControlBase.ts create mode 100644 ui/src/components/CustomTab/CustomTabBase.ts create mode 100644 ui/src/types/components/CustomHookClass.ts diff --git a/ui/src/components/BaseFormView/BaseFormView.tsx b/ui/src/components/BaseFormView/BaseFormView.tsx index d74fd788e..040e2d322 100644 --- a/ui/src/components/BaseFormView/BaseFormView.tsx +++ b/ui/src/components/BaseFormView/BaseFormView.tsx @@ -37,12 +37,10 @@ import { UtilControlWrapper, ServiceGroup, OauthConfiguration, - CustomHook, AnyEntity, OAuthEntity, BasicEntity, ChangeRecord, - CustomHookClass, EntitiesAllowingModifications, } from '../../types/components/BaseFormTypes'; import { @@ -52,6 +50,7 @@ import { import { GlobalConfig } from '../../types/globalConfig/globalConfig'; import { PageContextProviderType } from '../../context/PageContext'; import { shouldHideForPlatform } from '../../util/pageContext'; +import { CustomHookConstructor, CustomHookInstance } from '../../types/components/CustomHookClass'; function onCustomHookError(params: { methodName: string; error?: CustomHookError }) { // eslint-disable-next-line no-console @@ -110,7 +109,7 @@ class BaseFormView extends PureComponent { datadict: Record; - hook?: CustomHook; + hook?: CustomHookInstance; // eslint-disable-next-line camelcase state_enabled?: boolean; @@ -1083,7 +1082,7 @@ class BaseFormView extends PureComponent { if (type === 'external') { import(/* webpackIgnore: true */ `${getBuildDirPath()}/custom/${module}.js`).then( (external) => { - const Hook = external.default; + const Hook = external.default as CustomHookConstructor; this.hook = new Hook( globalConfig, this.props.serviceName, @@ -1099,13 +1098,14 @@ class BaseFormView extends PureComponent { // @ts-expect-error should be exported to other js module and imported here __non_webpack_require__( [`app/${this.appName}/js/build/custom/${module}`], - (Hook: CustomHookClass) => { + (Hook: CustomHookConstructor) => { this.hook = new Hook( globalConfig, this.props.serviceName, this.state, this.props.mode, - this.util + this.util, + this.props.groupName ); resolve(Hook); } diff --git a/ui/src/components/ControlWrapper/stories/ControlWrapper.stories.ts b/ui/src/components/ControlWrapper/stories/ControlWrapper.stories.ts index dec319531..1e6e52a18 100644 --- a/ui/src/components/ControlWrapper/stories/ControlWrapper.stories.ts +++ b/ui/src/components/ControlWrapper/stories/ControlWrapper.stories.ts @@ -20,7 +20,7 @@ export const Base: Story = { utilCustomFunctions: { setState: () => {}, setErrorFieldMsg: () => {}, - clearAllErrorMsg: () => {}, + clearAllErrorMsg: (state) => state, setErrorMsg: () => {}, }, handleChange: () => {}, diff --git a/ui/src/components/ControlWrapper/test/ControlWrapper.test.tsx b/ui/src/components/ControlWrapper/test/ControlWrapper.test.tsx index 0c4a3569d..327f7ad53 100644 --- a/ui/src/components/ControlWrapper/test/ControlWrapper.test.tsx +++ b/ui/src/components/ControlWrapper/test/ControlWrapper.test.tsx @@ -10,7 +10,7 @@ const renderControlWrapper = (props: Partial) => { utilCustomFunctions: { setState: () => {}, setErrorFieldMsg: () => {}, - clearAllErrorMsg: () => {}, + clearAllErrorMsg: (state) => state, setErrorMsg: () => {}, }, handleChange: () => {}, diff --git a/ui/src/components/CustomControl/CustomControl.tsx b/ui/src/components/CustomControl/CustomControl.tsx index 810c7cb63..cac18bc2d 100644 --- a/ui/src/components/CustomControl/CustomControl.tsx +++ b/ui/src/components/CustomControl/CustomControl.tsx @@ -4,30 +4,12 @@ import { getUnifiedConfigs } from '../../util/util'; import { getBuildDirPath } from '../../util/script'; import { AcceptableFormValueOrNullish } from '../../types/components/shareableTypes'; import { UtilBaseForm } from '../../types/components/BaseFormTypes'; -import { GlobalConfig } from '../../types/globalConfig/globalConfig'; -import { Mode } from '../../constants/modes'; +import { invariant } from '../../util/invariant'; +import { CustomControlConstructor } from './CustomControlBase'; +import { ControlData } from './CustomControl.types'; -interface IData { - value: AcceptableFormValueOrNullish; - mode: Mode; - serviceName: string; -} - -interface ICustomCompClass { - new ( - config: GlobalConfig, - el: HTMLElement | undefined, - data: IData, - setValue: (field: string, newValue: AcceptableFormValueOrNullish) => void, - util: UtilBaseForm - ): { - render: () => void; - validation?: (submittedField: string, submittedValue: string) => void; - }; -} - -interface ICustomCompProps { - data: IData; +interface Props { + data: ControlData; field: string; handleChange: (field: string, newValue: AcceptableFormValueOrNullish) => void; controlOptions: { src: string; type: string }; @@ -38,29 +20,32 @@ interface ICustomCompProps { utilCustomFunctions: UtilBaseForm; } -interface ICustomCompState { +interface State { loading: boolean; } -class CustomControl extends React.Component { +class CustomControl extends React.Component { static loadCustomControl = ( module: string, type: string, appName: string - ): Promise => + ): Promise => new Promise((resolve) => { if (type === 'external') { import(/* webpackIgnore: true */ `${getBuildDirPath()}/custom/${module}.js`).then( - (external) => { - const Control = external.default; + async (external) => { + const Control = external.default as CustomControlConstructor; resolve(Control); } ); } else { // @ts-expect-error typeof __non_webpack_require__ is not known during bundle - __non_webpack_require__([`app/${appName}/js/build/custom/${module}`], (Control) => { - resolve(Control); - }); + __non_webpack_require__( + [`app/${appName}/js/build/custom/${module}`], + (Control: CustomControlConstructor) => { + resolve(Control); + } + ); } }); @@ -68,7 +53,7 @@ class CustomControl extends React.Component el?: HTMLElement; - constructor(props: ICustomCompProps) { + constructor(props: Props) { super(props); this.state = { loading: true, @@ -85,6 +70,7 @@ class CustomControl extends React.Component this.props.controlOptions.type, appName ).then((Control) => { + invariant(this.el !== undefined, 'Element should be defined'); const customControl = new Control( globalConfig, this.el, @@ -92,7 +78,7 @@ class CustomControl extends React.Component this.setValue, this.props.utilCustomFunctions ); - customControl?.render(); + customControl.render(); if (typeof customControl.validation === 'function') { this.props.addCustomValidator(this.props.field, customControl.validation); @@ -101,7 +87,7 @@ class CustomControl extends React.Component }); } - shouldComponentUpdate(_nextProps: ICustomCompProps, nextState: ICustomCompState) { + shouldComponentUpdate(_nextProps: Props, nextState: State) { if (!nextState.loading && this.shouldRender) { this.shouldRender = false; return true; diff --git a/ui/src/components/CustomControl/CustomControl.types.ts b/ui/src/components/CustomControl/CustomControl.types.ts new file mode 100644 index 000000000..f9d246d8e --- /dev/null +++ b/ui/src/components/CustomControl/CustomControl.types.ts @@ -0,0 +1,8 @@ +import { AcceptableFormValueOrNullish } from '../../types/components/shareableTypes'; +import { Mode } from '../../constants/modes'; + +export interface ControlData { + value: AcceptableFormValueOrNullish; + mode: Mode; + serviceName: string; +} diff --git a/ui/src/components/CustomControl/CustomControlBase.ts b/ui/src/components/CustomControl/CustomControlBase.ts new file mode 100644 index 000000000..b86e84c3f --- /dev/null +++ b/ui/src/components/CustomControl/CustomControlBase.ts @@ -0,0 +1,43 @@ +import { GlobalConfig } from '../../types/globalConfig/globalConfig'; +import { UtilBaseForm } from '../../types/components/BaseFormTypes'; +import { AcceptableFormValueOrNullish } from '../../types/components/shareableTypes'; +import { ControlData } from './CustomControl.types'; + +type ValueSetter = (newValue: AcceptableFormValueOrNullish) => void; + +export type CustomControlInstance = + InstanceType; + +export type CustomControlConstructor< + T extends typeof CustomControlBase = typeof CustomControlBase +> = new (...args: ConstructorParameters) => CustomControlInstance; + +export abstract class CustomControlBase { + protected globalConfig: GlobalConfig; + + protected el: HTMLElement; + + protected data: ControlData; + + protected setValue: ValueSetter; + + protected util: UtilBaseForm; + + constructor( + globalConfig: GlobalConfig, + el: HTMLElement, + data: ControlData, + setValue: ValueSetter, + util: UtilBaseForm + ) { + this.globalConfig = globalConfig; + this.el = el; + this.data = data; + this.setValue = setValue; + this.util = util; + } + + abstract render(): void; + + validation?(field: string, value: ControlData['value']): string | undefined; +} diff --git a/ui/src/components/CustomTab/CustomTab.tsx b/ui/src/components/CustomTab/CustomTab.tsx index f84902298..89b4e77a3 100644 --- a/ui/src/components/CustomTab/CustomTab.tsx +++ b/ui/src/components/CustomTab/CustomTab.tsx @@ -4,6 +4,7 @@ import { z } from 'zod'; import { getUnifiedConfigs } from '../../util/util'; import { getBuildDirPath } from '../../util/script'; import { TabSchema } from '../../types/globalConfig/pages'; +import { CustomTabConstructor } from './CustomTabBase'; type Tab = z.infer; @@ -11,12 +12,6 @@ interface CustomTabProps { tab: Tab; } -interface ICustomTabClass { - new (tab: Tab, ref: HTMLDivElement): { - render: () => void; - }; -} - const CustomTab: React.FC = ({ tab }) => { const [loading, setLoading] = useState(true); const divRef = useRef(null); @@ -24,7 +19,7 @@ const CustomTab: React.FC = ({ tab }) => { const globalConfig = getUnifiedConfigs(); const appName = globalConfig.meta.name; - const loadCustomTab = (): Promise => + const loadCustomTab = (): Promise => new Promise((resolve) => { if (tab.customTab?.type === 'external') { import( @@ -37,7 +32,7 @@ const CustomTab: React.FC = ({ tab }) => { // @ts-expect-error should be exported to other js module and imported here __non_webpack_require__( [`app/${appName}/js/build/custom/${tab.customTab?.src}`], - (Control: ICustomTabClass) => resolve(Control) + (Control: CustomTabConstructor) => resolve(Control) ); } }); diff --git a/ui/src/components/CustomTab/CustomTabBase.ts b/ui/src/components/CustomTab/CustomTabBase.ts new file mode 100644 index 000000000..6026fd373 --- /dev/null +++ b/ui/src/components/CustomTab/CustomTabBase.ts @@ -0,0 +1,19 @@ +export type CustomTabInstance = + InstanceType; + +export type CustomTabConstructor = new ( + ...args: ConstructorParameters +) => CustomTabInstance; + +export abstract class CustomTabBase { + protected tab: object; + + protected el: HTMLElement; + + constructor(tab: object, el: HTMLElement) { + this.tab = tab; + this.el = el; + } + + abstract render(): void; +} diff --git a/ui/src/types/components/BaseFormTypes.ts b/ui/src/types/components/BaseFormTypes.ts index f12af7687..1a727a4f4 100644 --- a/ui/src/types/components/BaseFormTypes.ts +++ b/ui/src/types/components/BaseFormTypes.ts @@ -17,7 +17,6 @@ import { TextAreaEntity, TextEntity, } from '../globalConfig/entities'; -import { GlobalConfig } from '../globalConfig/globalConfig'; import { PageContextProviderType } from '../../context/PageContext'; export type CurrentBaseFormInput = @@ -101,9 +100,9 @@ export interface SingleSelectEntityType { } export interface UtilBaseForm { - setState: (callback: (prevState: BaseFormState) => void) => void; + setState: (callback: (prevState: BaseFormState) => BaseFormState) => void; setErrorFieldMsg: (field: string, msg: string) => void; - clearAllErrorMsg: (State: BaseFormState) => unknown; + clearAllErrorMsg: (state: BaseFormState) => BaseFormState; setErrorMsg: (msg: string) => void; } @@ -131,20 +130,6 @@ export interface OauthConfiguration { authEndpointAccessTokenType: string | null; } -export interface CustomHook { - onCreate?: () => void; - onRender?: () => void; - onEditLoad?: () => void; - onSaveSuccess?: () => void; - onSaveFail?: () => void; - onChange?: ( - field: string, - targetValue: AcceptableFormValueOrNullish, - tempState: BaseFormState - ) => void; - onSave?: (datadict?: Record) => boolean; -} - export type AnyEntity = z.TypeOf | z.TypeOf; export type EntitiesAllowingModifications = @@ -172,30 +157,3 @@ export interface ChangeRecord { value?: { $set: AcceptableFormValueOrNullish }; dependencyValues?: { $set: Record }; } - -export interface CustomHookClass { - new ( - config: GlobalConfig, - serviceName: string, - state: BaseFormState, - mode: string, - util: { - setState: (callback: (prevState: BaseFormState) => void) => void; - setErrorFieldMsg: (field: string, msg: string) => void; - clearAllErrorMsg: (State: BaseFormState) => unknown; - setErrorMsg: (msg: string) => void; - } - ): { - onCreate?: () => void; - onRender?: () => void; - onEditLoad?: () => void; - onSaveSuccess?: () => void; - onSaveFail?: () => void; - onChange?: ( - field: string, - targetValue: AcceptableFormValueOrNullish, - tempState: BaseFormState - ) => void; - onSave?: (datadict?: Record) => boolean; - }; -} diff --git a/ui/src/types/components/CustomHookClass.ts b/ui/src/types/components/CustomHookClass.ts new file mode 100644 index 000000000..f8ff8abb7 --- /dev/null +++ b/ui/src/types/components/CustomHookClass.ts @@ -0,0 +1,61 @@ +import { GlobalConfig } from '../globalConfig/globalConfig'; +import { Mode } from '../../constants/modes'; +import { AcceptableFormValueOrNullish } from './shareableTypes'; +import { BaseFormState, UtilBaseForm } from './BaseFormTypes'; + +export type CustomHookInstance = + InstanceType; + +export type CustomHookConstructor = new ( + ...args: ConstructorParameters +) => CustomHookInstance; + +export abstract class CustomHookClass { + protected globalConfig: GlobalConfig; + + protected serviceName: string; + + protected state: BaseFormState; + + protected mode: Mode; + + protected util: UtilBaseForm; + + protected groupName?: string; + + constructor( + globalConfig: GlobalConfig, + serviceName: string, + state: BaseFormState, + mode: Mode, + util: UtilBaseForm, + groupName?: string + ) { + this.globalConfig = globalConfig; + this.serviceName = serviceName; + this.state = state; + this.mode = mode; + this.util = util; + this.groupName = groupName; + } + + onCreate?(): void; + + onRender?(): void; + + onChange?( + field: string, + targetValue: AcceptableFormValueOrNullish, + tempState: BaseFormState + ): void; + + onEditLoad?(): void; + + onSave?(datadict?: Record): Promise; + + onSave?(datadict?: Record): boolean; + + onSaveSuccess?(): void; + + onSaveFail?(): void; +} From 9bfa5078d3a6f46013be22ab6a88cce3338d0bd6 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Fri, 20 Dec 2024 20:20:30 +0100 Subject: [PATCH 3/4] polish package.json and add public api Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> --- .github/workflows/build-ui.yml | 2 ++ ui/package.json | 27 ++++++++++++++++++++++----- ui/src/publicApi.ts | 11 +++++++++++ ui/tsconfig.lib.json | 11 +++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 ui/src/publicApi.ts create mode 100644 ui/tsconfig.lib.json diff --git a/.github/workflows/build-ui.yml b/.github/workflows/build-ui.yml index 2e1ac0641..cce4f3de0 100644 --- a/.github/workflows/build-ui.yml +++ b/.github/workflows/build-ui.yml @@ -17,6 +17,8 @@ jobs: run: yarn run lint - name: Unit test run: yarn run test + - name: Build UCC library + run: yarn run build:lib - name: Build UCC UI run: yarn run build - name: List deps into dependencies.txt diff --git a/ui/package.json b/ui/package.json index 28d9f03cd..571b5c2b3 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,10 +1,18 @@ { - "name": "@splunk/ucc_ui_lib", - "version": "0.0.1", + "name": "@splunk/add-on-ucc-framework", + "description": "Splunk Add-on SDK formerly UCC is a build and code generation framework", + "repository": { + "type": "git", + "url": "git+https://github.com/splunk/addonfactory-ucc-generator.git", + "directory": "ui" + }, + "version": "5.55.0", "license": "Apache-2.0", - "private": true, + "author": "Splunk Inc.", + "homepage": "https://splunk.github.io/addonfactory-ucc-generator", "scripts": { "build": "cross-env NODE_ENV=production webpack --bail", + "build:lib": "cross-env NODE_ENV=production tsc --project tsconfig.lib.json", "build:watch": "webpack --watch", "format": "prettier \"src/**/*.(js|jsx|ts|tsx|css)\" --write", "format:verify": "prettier \"src/**/*.(js|jsx|ts|tsx|css)\" --list-different", @@ -18,7 +26,8 @@ "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "test-storybook": "test-storybook", - "test-storybook:update-snapshots": "yarn run test-storybook -u" + "test-storybook:update-snapshots": "yarn run test-storybook -u", + "prepublishOnly": "yarn run build:lib" }, "dependencies": { "@splunk/dashboard-action-buttons": "^27.5.0", @@ -117,6 +126,10 @@ "webpack-dev-server": "^5.1.0", "webpack-merge": "^6.0.1" }, + "peerDependencies": { + "react": "^16.14.0", + "typescript": "^5.6.3" + }, "resolutions": { "@npmcli/git": "^2.1.0", "@types/react": "^16.14.62", @@ -137,5 +150,9 @@ "workerDirectory": [ "src/public" ] - } + }, + "types": "./dist/lib/publicApi.d.ts", + "files": [ + "dist/lib" + ] } diff --git a/ui/src/publicApi.ts b/ui/src/publicApi.ts new file mode 100644 index 000000000..f9fb8442e --- /dev/null +++ b/ui/src/publicApi.ts @@ -0,0 +1,11 @@ +export { Mode } from './constants/modes'; + +export { GlobalConfig } from './types/globalConfig/globalConfig'; + +export { BaseFormState } from './types/components/BaseFormTypes'; + +export { CustomHookClass } from './types/components/CustomHookClass'; + +export { CustomControlBase } from './components/CustomControl/CustomControlBase'; + +export { CustomTabBase } from './components/CustomTab/CustomTabBase'; diff --git a/ui/tsconfig.lib.json b/ui/tsconfig.lib.json new file mode 100644 index 000000000..4e16def13 --- /dev/null +++ b/ui/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "emitDeclarationOnly": true, + "declaration": true, + "declarationDir": "./dist/lib" + }, + "include": [ + "src/publicApi.ts" + ] +} From fac69feb1bef6202bbe382a0b01c9aa33ee0bf7d Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:51:29 +0100 Subject: [PATCH 4/4] add more types Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> --- ui/package.json | 4 ++-- ui/src/components/CustomTab/CustomTab.tsx | 5 +---- ui/src/components/CustomTab/CustomTab.types.ts | 4 ++++ ui/src/components/CustomTab/CustomTabBase.ts | 8 +++++--- 4 files changed, 12 insertions(+), 9 deletions(-) create mode 100644 ui/src/components/CustomTab/CustomTab.types.ts diff --git a/ui/package.json b/ui/package.json index 3f35f528c..13f4ec83d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,12 +1,12 @@ { "name": "@splunk/add-on-ucc-framework", - "description": "Splunk Add-on SDK formerly UCC is a build and code generation framework", + "description": "UCC is a build and code generation framework for building Splunk Add-ons (TAs)", "repository": { "type": "git", "url": "git+https://github.com/splunk/addonfactory-ucc-generator.git", "directory": "ui" }, - "version": "5.55.0", + "version": "5.56.0", "license": "Apache-2.0", "author": "Splunk Inc.", "homepage": "https://splunk.github.io/addonfactory-ucc-generator", diff --git a/ui/src/components/CustomTab/CustomTab.tsx b/ui/src/components/CustomTab/CustomTab.tsx index 89b4e77a3..6a4bd0aa5 100644 --- a/ui/src/components/CustomTab/CustomTab.tsx +++ b/ui/src/components/CustomTab/CustomTab.tsx @@ -1,12 +1,9 @@ import React, { useEffect, useRef, useState } from 'react'; import { _ } from '@splunk/ui-utils/i18n'; -import { z } from 'zod'; import { getUnifiedConfigs } from '../../util/util'; import { getBuildDirPath } from '../../util/script'; -import { TabSchema } from '../../types/globalConfig/pages'; import { CustomTabConstructor } from './CustomTabBase'; - -type Tab = z.infer; +import { Tab } from './CustomTab.types'; interface CustomTabProps { tab: Tab; diff --git a/ui/src/components/CustomTab/CustomTab.types.ts b/ui/src/components/CustomTab/CustomTab.types.ts new file mode 100644 index 000000000..ebbd62e95 --- /dev/null +++ b/ui/src/components/CustomTab/CustomTab.types.ts @@ -0,0 +1,4 @@ +import { z } from 'zod'; +import { TabSchema } from '../../types/globalConfig/pages'; + +export type Tab = z.infer; diff --git a/ui/src/components/CustomTab/CustomTabBase.ts b/ui/src/components/CustomTab/CustomTabBase.ts index 6026fd373..ffd038a42 100644 --- a/ui/src/components/CustomTab/CustomTabBase.ts +++ b/ui/src/components/CustomTab/CustomTabBase.ts @@ -1,3 +1,5 @@ +import { Tab } from './CustomTab.types'; + export type CustomTabInstance = InstanceType; @@ -6,11 +8,11 @@ export type CustomTabConstructor CustomTabInstance; export abstract class CustomTabBase { - protected tab: object; + protected tab: Tab; - protected el: HTMLElement; + protected el: HTMLDivElement; - constructor(tab: object, el: HTMLElement) { + constructor(tab: Tab, el: HTMLDivElement) { this.tab = tab; this.el = el; }