@integration-app/react 0.1.26 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +83 -0
- package/dist/index.d.ts +302 -0
- package/dist/index.js +426 -0
- package/dist/index.js.map +1 -0
- package/dist/index.module.d.ts +302 -0
- package/dist/index.module.mjs +393 -0
- package/dist/index.module.mjs.map +1 -0
- package/dist/index.umd.d.ts +302 -0
- package/dist/index.umd.js +428 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +50 -27
- package/rollup.dts.config.mjs +21 -0
- package/src/app-events/useAppEventSubscription.ts +20 -0
- package/src/app-events/useAppEventSubscriptions.ts +18 -0
- package/src/app-events/useAppEventType.ts +15 -0
- package/src/app-events/useAppEventTypes.ts +13 -0
- package/src/app-events/useAppEvents.ts +13 -0
- package/src/contexts/integration-app-context.tsx +55 -0
- package/src/data-form/index.tsx +3 -0
- package/src/data-sources/useDataSource.ts +12 -0
- package/src/data-sources/useDataSourceEvents.ts +16 -0
- package/src/data-sources/useDataSourceInstance.ts +48 -0
- package/src/data-sources/useDataSourceInstanceCollection.ts +19 -0
- package/src/data-sources/useDataSourceInstanceLocations.ts +30 -0
- package/src/data-sources/useDataSourceInstances.ts +16 -0
- package/src/data-sources/useDataSources.ts +13 -0
- package/src/field-mappings/useFieldMapping.ts +14 -0
- package/src/field-mappings/useFieldMappingInstance.ts +31 -0
- package/src/field-mappings/useFieldMappingInstances.ts +18 -0
- package/src/field-mappings/useFieldMappings.ts +13 -0
- package/src/flows/useFlow.ts +12 -0
- package/src/flows/useFlowInstance.ts +16 -0
- package/src/flows/useFlowInstances.ts +13 -0
- package/src/flows/useFlowRun.ts +12 -0
- package/src/flows/useFlowRuns.ts +11 -0
- package/src/flows/useFlowTemplate.ts +0 -0
- package/src/flows/useFlowTemplates.ts +0 -0
- package/src/flows/useFlows.ts +11 -0
- package/src/hooks/useElement.tsx +187 -0
- package/src/hooks/useElements.tsx +101 -0
- package/src/hooks/useGetter.tsx +38 -0
- package/src/index.tsx +40 -0
- package/src/integrations/useConnection.ts +12 -0
- package/src/integrations/useConnections.ts +13 -0
- package/src/integrations/useConnectorSpec.ts +25 -0
- package/src/integrations/useIntegration.ts +14 -0
- package/src/integrations/useIntegrations.ts +13 -0
- package/tsconfig.json +40 -0
- package/app-events/useAppEventSubscription.d.ts +0 -14
- package/app-events/useAppEventSubscription.js +0 -10
- package/app-events/useAppEventSubscription.js.map +0 -1
- package/app-events/useAppEventSubscriptions.d.ts +0 -8
- package/app-events/useAppEventSubscriptions.js +0 -12
- package/app-events/useAppEventSubscriptions.js.map +0 -1
- package/app-events/useAppEventType.d.ts +0 -13
- package/app-events/useAppEventType.js +0 -10
- package/app-events/useAppEventType.js.map +0 -1
- package/app-events/useAppEventTypes.d.ts +0 -8
- package/app-events/useAppEventTypes.js +0 -12
- package/app-events/useAppEventTypes.js.map +0 -1
- package/app-events/useAppEvents.d.ts +0 -8
- package/app-events/useAppEvents.js +0 -12
- package/app-events/useAppEvents.js.map +0 -1
- package/contexts/integration-app-context.d.ts +0 -11
- package/contexts/integration-app-context.js +0 -22
- package/contexts/integration-app-context.js.map +0 -1
- package/data-form/index.d.ts +0 -1
- package/data-form/index.js +0 -8
- package/data-form/index.js.map +0 -1
- package/data-sources/useDataSource.d.ts +0 -12
- package/data-sources/useDataSource.js +0 -10
- package/data-sources/useDataSource.js.map +0 -1
- package/data-sources/useDataSourceEvents.d.ts +0 -8
- package/data-sources/useDataSourceEvents.js +0 -12
- package/data-sources/useDataSourceEvents.js.map +0 -1
- package/data-sources/useDataSourceInstance.d.ts +0 -28
- package/data-sources/useDataSourceInstance.js +0 -28
- package/data-sources/useDataSourceInstance.js.map +0 -1
- package/data-sources/useDataSourceInstanceCollection.d.ts +0 -7
- package/data-sources/useDataSourceInstanceCollection.js +0 -16
- package/data-sources/useDataSourceInstanceCollection.js.map +0 -1
- package/data-sources/useDataSourceInstanceLocations.d.ts +0 -10
- package/data-sources/useDataSourceInstanceLocations.js +0 -21
- package/data-sources/useDataSourceInstanceLocations.js.map +0 -1
- package/data-sources/useDataSources.d.ts +0 -8
- package/data-sources/useDataSources.js +0 -12
- package/data-sources/useDataSources.js.map +0 -1
- package/field-mappings/useFieldMapping.d.ts +0 -12
- package/field-mappings/useFieldMapping.js +0 -10
- package/field-mappings/useFieldMapping.js.map +0 -1
- package/field-mappings/useFieldMappingInstance.d.ts +0 -17
- package/field-mappings/useFieldMappingInstance.js +0 -17
- package/field-mappings/useFieldMappingInstance.js.map +0 -1
- package/field-mappings/useFieldMappingInstances.d.ts +0 -8
- package/field-mappings/useFieldMappingInstances.js +0 -12
- package/field-mappings/useFieldMappingInstances.js.map +0 -1
- package/field-mappings/useFieldMappings.d.ts +0 -8
- package/field-mappings/useFieldMappings.js +0 -12
- package/field-mappings/useFieldMappings.js.map +0 -1
- package/flows/useFlow.d.ts +0 -12
- package/flows/useFlow.js +0 -10
- package/flows/useFlow.js.map +0 -1
- package/flows/useFlowInstance.d.ts +0 -14
- package/flows/useFlowInstance.js +0 -10
- package/flows/useFlowInstance.js.map +0 -1
- package/flows/useFlowInstances.d.ts +0 -8
- package/flows/useFlowInstances.js +0 -12
- package/flows/useFlowInstances.js.map +0 -1
- package/flows/useFlowRun.d.ts +0 -12
- package/flows/useFlowRun.js +0 -10
- package/flows/useFlowRun.js.map +0 -1
- package/flows/useFlowRuns.d.ts +0 -8
- package/flows/useFlowRuns.js +0 -10
- package/flows/useFlowRuns.js.map +0 -1
- package/flows/useFlows.d.ts +0 -8
- package/flows/useFlows.js +0 -10
- package/flows/useFlows.js.map +0 -1
- package/hooks/useElement.d.ts +0 -25
- package/hooks/useElement.js +0 -71
- package/hooks/useElement.js.map +0 -1
- package/hooks/useElements.d.ts +0 -15
- package/hooks/useElements.js +0 -59
- package/hooks/useElements.js.map +0 -1
- package/hooks/useGetter.d.ts +0 -6
- package/hooks/useGetter.js +0 -32
- package/hooks/useGetter.js.map +0 -1
- package/index.d.ts +0 -28
- package/index.js +0 -61
- package/index.js.map +0 -1
- package/integrations/useConnection.d.ts +0 -12
- package/integrations/useConnection.js +0 -10
- package/integrations/useConnection.js.map +0 -1
- package/integrations/useConnectionSpec.d.ts +0 -5
- package/integrations/useConnectionSpec.js +0 -25
- package/integrations/useConnectionSpec.js.map +0 -1
- package/integrations/useConnections.d.ts +0 -8
- package/integrations/useConnections.js +0 -12
- package/integrations/useConnections.js.map +0 -1
- package/integrations/useIntegration.d.ts +0 -12
- package/integrations/useIntegration.js +0 -10
- package/integrations/useIntegration.js.map +0 -1
- package/integrations/useIntegrations.d.ts +0 -8
- package/integrations/useIntegrations.js +0 -12
- package/integrations/useIntegrations.js.map +0 -1
@@ -0,0 +1,55 @@
|
|
1
|
+
import { IntegrationAppClient } from '@integration-app/sdk'
|
2
|
+
import { createContext, ReactNode, useContext, useMemo } from 'react'
|
3
|
+
|
4
|
+
const IntegrationAppContext = createContext<IntegrationAppClient>(null)
|
5
|
+
|
6
|
+
IntegrationAppContext.displayName = 'IntegrationAppClientContext'
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @interface
|
10
|
+
*/
|
11
|
+
interface IntegrationAppProviderProps {
|
12
|
+
token?: string
|
13
|
+
fetchToken?: () => Promise<string>
|
14
|
+
credentials?: any
|
15
|
+
fetchCredentials?: () => Promise<any>
|
16
|
+
apiUri?: string
|
17
|
+
uiUri?: string
|
18
|
+
children: ReactNode
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Provides an IntegrationAppClient instance to the React tree.
|
23
|
+
*/
|
24
|
+
export const IntegrationAppProvider = ({
|
25
|
+
token,
|
26
|
+
fetchToken,
|
27
|
+
credentials,
|
28
|
+
fetchCredentials,
|
29
|
+
apiUri = null,
|
30
|
+
uiUri = null,
|
31
|
+
children,
|
32
|
+
}: IntegrationAppProviderProps) => {
|
33
|
+
const client = useMemo(
|
34
|
+
() =>
|
35
|
+
new IntegrationAppClient({
|
36
|
+
token,
|
37
|
+
fetchToken,
|
38
|
+
credentials,
|
39
|
+
fetchCredentials,
|
40
|
+
apiUri,
|
41
|
+
uiUri,
|
42
|
+
}),
|
43
|
+
[token, JSON.stringify(credentials), apiUri, uiUri],
|
44
|
+
)
|
45
|
+
|
46
|
+
return (
|
47
|
+
<IntegrationAppContext.Provider value={client}>
|
48
|
+
{children}
|
49
|
+
</IntegrationAppContext.Provider>
|
50
|
+
)
|
51
|
+
}
|
52
|
+
|
53
|
+
export function useIntegrationApp(): IntegrationAppClient {
|
54
|
+
return useContext(IntegrationAppContext)
|
55
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { DataSource, DataSourceAccessor } from '@integration-app/sdk'
|
2
|
+
import { useElement } from '../hooks/useElement'
|
3
|
+
|
4
|
+
export function useDataSource(idOrKey: string) {
|
5
|
+
const { data: dataSource, ...rest } = useElement<
|
6
|
+
DataSource,
|
7
|
+
string,
|
8
|
+
DataSourceAccessor
|
9
|
+
>(idOrKey, (integrationApp) => integrationApp.dataSource.bind(integrationApp))
|
10
|
+
|
11
|
+
return { dataSource, ...rest }
|
12
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import {
|
2
|
+
DataSourceEvent,
|
3
|
+
FindDataSourceEventsQuery,
|
4
|
+
} from '@integration-app/sdk'
|
5
|
+
import { useElements } from '../hooks/useElements'
|
6
|
+
|
7
|
+
export function useDataSourceEvents(query?: FindDataSourceEventsQuery) {
|
8
|
+
const { ...rest } = useElements<DataSourceEvent, FindDataSourceEventsQuery>(
|
9
|
+
query,
|
10
|
+
(integrationApp) => integrationApp.dataSourceEvents,
|
11
|
+
)
|
12
|
+
|
13
|
+
return {
|
14
|
+
...rest,
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import {
|
2
|
+
DataCollectionCreateRequest,
|
3
|
+
DataCollectionFindRequest,
|
4
|
+
DataCollectionUpdateRequest,
|
5
|
+
DataSourceInstanceAccessor,
|
6
|
+
DataSourceInstanceSelector,
|
7
|
+
OpenDataSourceConfigurationOptions,
|
8
|
+
DataSourceInstance,
|
9
|
+
} from '@integration-app/sdk'
|
10
|
+
import { useElement } from '../hooks/useElement'
|
11
|
+
|
12
|
+
export function useDataSourceInstance(
|
13
|
+
selector: DataSourceInstanceSelector | { id: string },
|
14
|
+
) {
|
15
|
+
const { data: dataSourceInstance, ...rest } = useElement<
|
16
|
+
DataSourceInstance,
|
17
|
+
DataSourceInstanceSelector,
|
18
|
+
DataSourceInstanceAccessor
|
19
|
+
>(selector, (integrationApp) =>
|
20
|
+
integrationApp.dataSourceInstance.bind(integrationApp),
|
21
|
+
)
|
22
|
+
|
23
|
+
const accessor = rest.accessor
|
24
|
+
|
25
|
+
return {
|
26
|
+
dataSourceInstance,
|
27
|
+
setup: () => accessor.setup(),
|
28
|
+
subscribe: (eventType) => accessor.subscribe(eventType),
|
29
|
+
resubscribe: (eventType) => accessor.resubscribe(eventType),
|
30
|
+
unsubscribe: (eventType) => accessor.unsubscribe(eventType),
|
31
|
+
pullUpdates: () => accessor.pullUpdates(),
|
32
|
+
fullSync: () => accessor.fullSync(),
|
33
|
+
reset: () => accessor.reset(),
|
34
|
+
openConfiguration: (options?: OpenDataSourceConfigurationOptions) =>
|
35
|
+
accessor.openConfiguration(options),
|
36
|
+
findRecords: (request?: DataCollectionFindRequest) =>
|
37
|
+
accessor.findRecords(request),
|
38
|
+
findRecordById: (id: string) => accessor.findRecordById(id),
|
39
|
+
createRecord: (request?: DataCollectionCreateRequest) =>
|
40
|
+
accessor.createRecord(request),
|
41
|
+
updateRecord: (request?: DataCollectionUpdateRequest) =>
|
42
|
+
accessor.updateRecord(request),
|
43
|
+
deleteRecord: (id?: string) => accessor.deleteRecord(id),
|
44
|
+
unifiedFieldsToNative: (unifiedFields: any) =>
|
45
|
+
accessor.unifiedFieldsToNative(unifiedFields),
|
46
|
+
...rest,
|
47
|
+
}
|
48
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { DataCollectionSpec, DataSourceInstance } from '@integration-app/sdk'
|
2
|
+
import { useIntegrationApp } from '../contexts/integration-app-context'
|
3
|
+
import useGetter from '../hooks/useGetter'
|
4
|
+
|
5
|
+
export function useDataSourceInstanceCollection(
|
6
|
+
dataSourceInstance: DataSourceInstance,
|
7
|
+
) {
|
8
|
+
const integrationApp = useIntegrationApp()
|
9
|
+
const { data: collection, ...rest } = useGetter<DataCollectionSpec>(
|
10
|
+
dataSourceInstance?.id,
|
11
|
+
() =>
|
12
|
+
integrationApp.dataSourceInstance(dataSourceInstance.id).getCollection(),
|
13
|
+
)
|
14
|
+
|
15
|
+
return {
|
16
|
+
collection,
|
17
|
+
...rest,
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import {
|
2
|
+
DataDirectoryListResponse,
|
3
|
+
DataSourceInstance,
|
4
|
+
} from '@integration-app/sdk'
|
5
|
+
import { useIntegrationApp } from '../contexts/integration-app-context'
|
6
|
+
import useGetter from '../hooks/useGetter'
|
7
|
+
|
8
|
+
export function useDataSourceInstanceLocations(
|
9
|
+
dataSourceInstance: DataSourceInstance,
|
10
|
+
args?: {
|
11
|
+
path?: string
|
12
|
+
cursor?: string
|
13
|
+
},
|
14
|
+
) {
|
15
|
+
const integrationApp = useIntegrationApp()
|
16
|
+
const { data, ...rest } = useGetter<DataDirectoryListResponse>(
|
17
|
+
dataSourceInstance
|
18
|
+
? `${dataSourceInstance.id}/${JSON.stringify(args)}`
|
19
|
+
: undefined,
|
20
|
+
() =>
|
21
|
+
integrationApp
|
22
|
+
.dataSourceInstance(dataSourceInstance.id)
|
23
|
+
.getLocations(args),
|
24
|
+
)
|
25
|
+
|
26
|
+
return {
|
27
|
+
locations: data?.locations ?? [],
|
28
|
+
...rest,
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import {
|
2
|
+
FindDataSourceInstancesQuery,
|
3
|
+
DataSourceInstance,
|
4
|
+
} from '@integration-app/sdk'
|
5
|
+
import { useElements } from '../hooks/useElements'
|
6
|
+
|
7
|
+
export function useDataSourceInstances(query?: FindDataSourceInstancesQuery) {
|
8
|
+
const { ...rest } = useElements<
|
9
|
+
DataSourceInstance,
|
10
|
+
FindDataSourceInstancesQuery
|
11
|
+
>(query, (integrationApp) => integrationApp.dataSourceInstances)
|
12
|
+
|
13
|
+
return {
|
14
|
+
...rest,
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { DataSource, FindDataSourcesQuery } from '@integration-app/sdk'
|
2
|
+
import { useElements } from '../hooks/useElements'
|
3
|
+
|
4
|
+
export function useDataSources(query?: FindDataSourcesQuery) {
|
5
|
+
const { ...rest } = useElements<DataSource, FindDataSourcesQuery>(
|
6
|
+
query,
|
7
|
+
(integrationApp) => integrationApp.dataSources,
|
8
|
+
)
|
9
|
+
|
10
|
+
return {
|
11
|
+
...rest,
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { FieldMapping, FieldMappingAccessor } from '@integration-app/sdk'
|
2
|
+
import { useElement } from '../hooks/useElement'
|
3
|
+
|
4
|
+
export function useFieldMapping(idOrKey: string) {
|
5
|
+
const { data: fieldMapping, ...rest } = useElement<
|
6
|
+
FieldMapping,
|
7
|
+
string,
|
8
|
+
FieldMappingAccessor
|
9
|
+
>(idOrKey, (integrationApp) =>
|
10
|
+
integrationApp.fieldMapping.bind(integrationApp),
|
11
|
+
)
|
12
|
+
|
13
|
+
return { fieldMapping, ...rest }
|
14
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import {
|
2
|
+
FieldMappingInstanceAccessor,
|
3
|
+
FieldMappingInstanceSelector,
|
4
|
+
FieldMappingInstance,
|
5
|
+
OpenFieldMappingInstanceConfigurationOptions,
|
6
|
+
} from '@integration-app/sdk'
|
7
|
+
import { useElement } from '../hooks/useElement'
|
8
|
+
|
9
|
+
export function useFieldMappingInstance(
|
10
|
+
selector: FieldMappingInstanceSelector | { id: string },
|
11
|
+
) {
|
12
|
+
const { data: fieldMappingInstance, ...rest } = useElement<
|
13
|
+
FieldMappingInstance,
|
14
|
+
FieldMappingInstanceSelector,
|
15
|
+
FieldMappingInstanceAccessor
|
16
|
+
>(selector, (integrationApp) =>
|
17
|
+
integrationApp.fieldMappingInstance.bind(integrationApp),
|
18
|
+
)
|
19
|
+
|
20
|
+
const accessor = rest.accessor
|
21
|
+
|
22
|
+
return {
|
23
|
+
fieldMappingInstance,
|
24
|
+
setup: () => accessor.setup(),
|
25
|
+
reset: () => accessor.reset(),
|
26
|
+
openConfiguration: (
|
27
|
+
options?: OpenFieldMappingInstanceConfigurationOptions,
|
28
|
+
) => accessor.openConfiguration(options),
|
29
|
+
...rest,
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import {
|
2
|
+
FindFieldMappingInstancesQuery,
|
3
|
+
FieldMappingInstance,
|
4
|
+
} from '@integration-app/sdk'
|
5
|
+
import { useElements } from '../hooks/useElements'
|
6
|
+
|
7
|
+
export function useFieldMappingInstances(
|
8
|
+
query?: FindFieldMappingInstancesQuery,
|
9
|
+
) {
|
10
|
+
const { ...rest } = useElements<
|
11
|
+
FieldMappingInstance,
|
12
|
+
FindFieldMappingInstancesQuery
|
13
|
+
>(query, (integrationApp) => integrationApp.fieldMappingInstances)
|
14
|
+
|
15
|
+
return {
|
16
|
+
...rest,
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { FieldMapping, FindFieldMappingsQuery } from '@integration-app/sdk'
|
2
|
+
import { useElements } from '../hooks/useElements'
|
3
|
+
|
4
|
+
export function useFieldMappings(query?: FindFieldMappingsQuery) {
|
5
|
+
const { ...rest } = useElements<FieldMapping, FindFieldMappingsQuery>(
|
6
|
+
query,
|
7
|
+
(integrationApp) => integrationApp.fieldMappings,
|
8
|
+
)
|
9
|
+
|
10
|
+
return {
|
11
|
+
...rest,
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { Flow, FlowAccessor, FlowSelector } from '@integration-app/sdk'
|
2
|
+
import { useElement } from '../hooks/useElement'
|
3
|
+
|
4
|
+
export function useFlow(idOrSelector: string | FlowSelector) {
|
5
|
+
const { data: flow, ...rest } = useElement<
|
6
|
+
Flow,
|
7
|
+
string | FlowSelector,
|
8
|
+
FlowAccessor
|
9
|
+
>(idOrSelector, (integrationApp) => integrationApp.flow.bind(integrationApp))
|
10
|
+
|
11
|
+
return { flow, ...rest }
|
12
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import {
|
2
|
+
FlowInstance,
|
3
|
+
FlowInstanceAccessor,
|
4
|
+
FlowInstanceSelector,
|
5
|
+
} from '@integration-app/sdk'
|
6
|
+
import { useElement } from '../hooks/useElement'
|
7
|
+
|
8
|
+
export function useFlowInstance(props: FlowInstanceSelector | { id: string }) {
|
9
|
+
const { data: flowInstance, ...rest } = useElement<
|
10
|
+
FlowInstance,
|
11
|
+
FlowInstanceSelector,
|
12
|
+
FlowInstanceAccessor
|
13
|
+
>(props, (integrationApp) => integrationApp.flowInstance.bind(integrationApp))
|
14
|
+
|
15
|
+
return { flowInstance, ...rest }
|
16
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { FindFlowInstancesQuery, FlowInstance } from '@integration-app/sdk'
|
2
|
+
import { useElements } from '../hooks/useElements'
|
3
|
+
|
4
|
+
export function useFlowInstances(query?: FindFlowInstancesQuery) {
|
5
|
+
const { ...rest } = useElements<FlowInstance, FindFlowInstancesQuery>(
|
6
|
+
query,
|
7
|
+
(integrationApp) => integrationApp.flowInstances,
|
8
|
+
)
|
9
|
+
|
10
|
+
return {
|
11
|
+
...rest,
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { FlowRun, FlowRunAccessor } from '@integration-app/sdk'
|
2
|
+
import { useElement } from '../hooks/useElement'
|
3
|
+
|
4
|
+
export function useFlowRun(id: string) {
|
5
|
+
const { data: flowRun, ...rest } = useElement<
|
6
|
+
FlowRun,
|
7
|
+
string,
|
8
|
+
FlowRunAccessor
|
9
|
+
>(id, (integrationApp) => integrationApp.flowRun.bind(integrationApp))
|
10
|
+
|
11
|
+
return { flowRun, ...rest }
|
12
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { FindFlowRunsRequest, FlowRun } from '@integration-app/sdk'
|
2
|
+
import { useElements } from '../hooks/useElements'
|
3
|
+
|
4
|
+
export function useFlowRuns(query?: FindFlowRunsRequest) {
|
5
|
+
const { ...rest } = useElements<FlowRun, FindFlowRunsRequest>(
|
6
|
+
query,
|
7
|
+
(integrationApp) => integrationApp.flowRuns,
|
8
|
+
)
|
9
|
+
|
10
|
+
return { ...rest }
|
11
|
+
}
|
File without changes
|
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { useElements } from '../hooks/useElements'
|
2
|
+
import { FindFlowsRequest, Flow } from '@integration-app/sdk'
|
3
|
+
|
4
|
+
export function useFlows(query?: FindFlowsRequest) {
|
5
|
+
const { ...rest } = useElements<Flow, FindFlowsRequest>(
|
6
|
+
query,
|
7
|
+
(integrationApp) => integrationApp.flows,
|
8
|
+
)
|
9
|
+
|
10
|
+
return { ...rest }
|
11
|
+
}
|
@@ -0,0 +1,187 @@
|
|
1
|
+
import {
|
2
|
+
IntegrationAppClient,
|
3
|
+
ElementAccessor,
|
4
|
+
ElementInstanceAccessor,
|
5
|
+
} from '@integration-app/sdk'
|
6
|
+
import { useEffect, useState } from 'react'
|
7
|
+
import { useIntegrationApp } from 'contexts/integration-app-context'
|
8
|
+
|
9
|
+
interface ElementHookResult<
|
10
|
+
ElementInterface,
|
11
|
+
ElementAccessor,
|
12
|
+
CreateRequest,
|
13
|
+
UpdateRequest,
|
14
|
+
> {
|
15
|
+
data: ElementInterface | undefined
|
16
|
+
loading: boolean
|
17
|
+
error?: Error
|
18
|
+
create: (data: CreateRequest) => Promise<ElementInterface>
|
19
|
+
patch: (data: UpdateRequest) => Promise<ElementInterface>
|
20
|
+
put: (data: CreateRequest) => Promise<ElementInterface>
|
21
|
+
archive: () => Promise<void>
|
22
|
+
refresh: () => void
|
23
|
+
accessor: ElementAccessor
|
24
|
+
}
|
25
|
+
|
26
|
+
type ElementAccessorGetter<SelectorInterface, ElementAccessor> = (
|
27
|
+
params: SelectorInterface | string,
|
28
|
+
) => ElementAccessor
|
29
|
+
|
30
|
+
export type ElementAccessorGenerator<SelectorInterface, ElementAccessor> = (
|
31
|
+
integrationApp: IntegrationAppClient,
|
32
|
+
) => ElementAccessorGetter<SelectorInterface, ElementAccessor>
|
33
|
+
|
34
|
+
interface BaseElementAccessor<ElementInterface, CreateRequest, UpdateRequest> {
|
35
|
+
get(): Promise<ElementInterface>
|
36
|
+
create?: (data: CreateRequest) => Promise<ElementInterface>
|
37
|
+
patch?(data: UpdateRequest): Promise<ElementInterface>
|
38
|
+
put?(data: CreateRequest): Promise<ElementInterface>
|
39
|
+
archive?(): Promise<void>
|
40
|
+
}
|
41
|
+
|
42
|
+
type ExtractElementGenerics<T, Interface> = T extends ElementAccessor<
|
43
|
+
infer _InterfaceType,
|
44
|
+
infer CreateRequestType,
|
45
|
+
infer UpdateRequestType
|
46
|
+
>
|
47
|
+
? { CreateRequest: CreateRequestType; UpdateRequest: UpdateRequestType }
|
48
|
+
: T extends ElementInstanceAccessor<
|
49
|
+
infer _ElementInstanceType,
|
50
|
+
infer _SelectorType,
|
51
|
+
infer CreateRequestType,
|
52
|
+
infer UpdateRequestType
|
53
|
+
>
|
54
|
+
? { CreateRequest: CreateRequestType; UpdateRequest: UpdateRequestType }
|
55
|
+
: { CreateRequest: Partial<Interface>; UpdateRequest: Partial<Interface> }
|
56
|
+
|
57
|
+
export function useElement<
|
58
|
+
ElementInterface,
|
59
|
+
SelectorInterface,
|
60
|
+
ElementAccessor extends BaseElementAccessor<
|
61
|
+
ElementInterface,
|
62
|
+
CreateRequest,
|
63
|
+
UpdateRequest
|
64
|
+
>,
|
65
|
+
CreateRequest extends Partial<ElementInterface> = ExtractElementGenerics<
|
66
|
+
ElementAccessor,
|
67
|
+
ElementInterface
|
68
|
+
>['CreateRequest'],
|
69
|
+
UpdateRequest extends Partial<ElementInterface> = ExtractElementGenerics<
|
70
|
+
ElementAccessor,
|
71
|
+
ElementInterface
|
72
|
+
>['UpdateRequest'],
|
73
|
+
>(
|
74
|
+
props: SelectorInterface | { id: string },
|
75
|
+
accessorGenerator: ElementAccessorGenerator<
|
76
|
+
SelectorInterface,
|
77
|
+
ElementAccessor
|
78
|
+
>,
|
79
|
+
): ElementHookResult<
|
80
|
+
ElementInterface,
|
81
|
+
ElementAccessor,
|
82
|
+
CreateRequest,
|
83
|
+
UpdateRequest
|
84
|
+
> {
|
85
|
+
const integrationApp = useIntegrationApp()
|
86
|
+
const [data, setData] = useState<ElementInterface>()
|
87
|
+
const [loading, setLoading] = useState<boolean>(true)
|
88
|
+
const [error, setError] = useState<Error>(null)
|
89
|
+
const [refreshCounter, setRefreshCounter] = useState(0)
|
90
|
+
|
91
|
+
function updateDataWith(newData) {
|
92
|
+
if (data !== undefined) {
|
93
|
+
setData({
|
94
|
+
...data,
|
95
|
+
...newData,
|
96
|
+
})
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
function replaceDataWith(newData) {
|
101
|
+
setData(newData)
|
102
|
+
}
|
103
|
+
|
104
|
+
const selector = (props as any)?.id
|
105
|
+
? (props as { id: string }).id
|
106
|
+
: (props as SelectorInterface)
|
107
|
+
|
108
|
+
const accessor = integrationApp
|
109
|
+
? accessorGenerator(integrationApp)(selector)
|
110
|
+
: null
|
111
|
+
|
112
|
+
useEffect(() => {
|
113
|
+
setLoading(true)
|
114
|
+
setError(null)
|
115
|
+
if (integrationApp && selector) {
|
116
|
+
accessor
|
117
|
+
.get()
|
118
|
+
.then(setData)
|
119
|
+
.catch(setError)
|
120
|
+
.finally(() => setLoading(false))
|
121
|
+
} else {
|
122
|
+
setError(
|
123
|
+
new Error(
|
124
|
+
'IntegrationApp not found. Was this component wrapped in <IntegrationAppProvider>?',
|
125
|
+
),
|
126
|
+
)
|
127
|
+
}
|
128
|
+
}, [
|
129
|
+
integrationApp,
|
130
|
+
JSON.stringify(selector),
|
131
|
+
JSON.stringify(props),
|
132
|
+
refreshCounter,
|
133
|
+
])
|
134
|
+
|
135
|
+
async function create(createData: CreateRequest) {
|
136
|
+
// Because `createData` do not contain all critical fields
|
137
|
+
// we do not update state with `createData` to avoid problem
|
138
|
+
// with missing critical fields like `id`
|
139
|
+
|
140
|
+
const returnedData = await accessor.create(createData)
|
141
|
+
replaceDataWith(returnedData)
|
142
|
+
return returnedData
|
143
|
+
}
|
144
|
+
|
145
|
+
function refresh() {
|
146
|
+
setRefreshCounter(refreshCounter + 1)
|
147
|
+
}
|
148
|
+
|
149
|
+
async function patch(patch: UpdateRequest) {
|
150
|
+
if (typeof patch === 'object') {
|
151
|
+
updateDataWith(patch ?? {})
|
152
|
+
|
153
|
+
// TODO: PL-3550
|
154
|
+
// PATCH could response with modified fields that do not exist in `patch`
|
155
|
+
// but this data could be outdated because of other methods calls
|
156
|
+
return accessor.patch(patch)
|
157
|
+
} else {
|
158
|
+
return data
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
async function put(putData: CreateRequest) {
|
163
|
+
updateDataWith(putData)
|
164
|
+
|
165
|
+
// TODO: PL-3550
|
166
|
+
// PUT could response with modified fields that do not exist in `patch`
|
167
|
+
// but this data could be outdated because of other methods calls
|
168
|
+
return await accessor.put(putData)
|
169
|
+
}
|
170
|
+
|
171
|
+
async function archive() {
|
172
|
+
setData(null)
|
173
|
+
return accessor.archive()
|
174
|
+
}
|
175
|
+
|
176
|
+
return {
|
177
|
+
data,
|
178
|
+
create,
|
179
|
+
patch,
|
180
|
+
put,
|
181
|
+
archive,
|
182
|
+
refresh,
|
183
|
+
loading,
|
184
|
+
error,
|
185
|
+
accessor,
|
186
|
+
}
|
187
|
+
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
import { useIntegrationApp } from '../contexts/integration-app-context'
|
2
|
+
import { useEffect, useRef, useState } from 'react'
|
3
|
+
import { IntegrationAppClient } from '@integration-app/sdk'
|
4
|
+
import { PaginationQuery, PaginationResponse } from '@integration-app/sdk'
|
5
|
+
|
6
|
+
export interface ElementsHookResult<Element> {
|
7
|
+
items: Element[]
|
8
|
+
loading: boolean
|
9
|
+
error?: Error
|
10
|
+
refresh(): Promise<void>
|
11
|
+
loadMore(): Promise<void>
|
12
|
+
}
|
13
|
+
|
14
|
+
interface ElementsAccessor<Element, FindQuery> {
|
15
|
+
find(query: FindQuery): Promise<PaginationResponse<Element>>
|
16
|
+
}
|
17
|
+
|
18
|
+
type InstanceAccessorGenerator<Element, FindQuery> = (
|
19
|
+
integrationApp: IntegrationAppClient,
|
20
|
+
) => ElementsAccessor<Element, FindQuery>
|
21
|
+
|
22
|
+
export function useElements<Element, FindQuery extends PaginationQuery>(
|
23
|
+
initialQuery: FindQuery,
|
24
|
+
accessorGenerator: InstanceAccessorGenerator<Element, FindQuery>,
|
25
|
+
): ElementsHookResult<Element> {
|
26
|
+
const integrationApp = useIntegrationApp()
|
27
|
+
|
28
|
+
const refreshId = useRef<number>(0)
|
29
|
+
const [items, setItems] = useState<Element[]>([])
|
30
|
+
const [nextCursor, setNextCursor] = useState<any>(undefined)
|
31
|
+
const [loading, setLoading] = useState<boolean>(false)
|
32
|
+
const [error, setError] = useState<Error>(null)
|
33
|
+
|
34
|
+
async function loadMore() {
|
35
|
+
const startingRefreshId = refreshId.current
|
36
|
+
const isFirstPage = !nextCursor
|
37
|
+
|
38
|
+
function setStateIfCurrentRefresh(stateSetter, valueGetter: (arg) => any) {
|
39
|
+
// If the refreshId has changed since the beginning of this function,
|
40
|
+
// it means refresh() was called while we were loading more results.
|
41
|
+
// Don't change the state in that case - the latest refresh will take care of that.
|
42
|
+
stateSetter((value) =>
|
43
|
+
startingRefreshId === refreshId.current ? valueGetter(value) : value,
|
44
|
+
)
|
45
|
+
}
|
46
|
+
|
47
|
+
setStateIfCurrentRefresh(setError, () => null)
|
48
|
+
setStateIfCurrentRefresh(setLoading, () => true)
|
49
|
+
|
50
|
+
const queryParams = {
|
51
|
+
...initialQuery,
|
52
|
+
}
|
53
|
+
|
54
|
+
if (nextCursor) queryParams.cursor = nextCursor
|
55
|
+
|
56
|
+
try {
|
57
|
+
const data = await accessorGenerator(integrationApp).find(queryParams)
|
58
|
+
|
59
|
+
setStateIfCurrentRefresh(setNextCursor, () => data.cursor)
|
60
|
+
setStateIfCurrentRefresh(setItems, (items) =>
|
61
|
+
isFirstPage ? data.items : [...items, ...data.items],
|
62
|
+
)
|
63
|
+
} catch (e) {
|
64
|
+
setStateIfCurrentRefresh(setError, () => e)
|
65
|
+
} finally {
|
66
|
+
setStateIfCurrentRefresh(setLoading, () => false)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
// refresh on initialQuery change
|
71
|
+
useEffect(() => {
|
72
|
+
if (!integrationApp) {
|
73
|
+
setError(
|
74
|
+
new Error(
|
75
|
+
'IntegrationApp not found. Was this component wrapped in <IntegrationAppProvider>?',
|
76
|
+
),
|
77
|
+
)
|
78
|
+
|
79
|
+
return
|
80
|
+
}
|
81
|
+
|
82
|
+
refresh()
|
83
|
+
}, [integrationApp, JSON.stringify(initialQuery)])
|
84
|
+
|
85
|
+
async function refresh() {
|
86
|
+
refreshId.current += 1
|
87
|
+
setNextCursor(undefined)
|
88
|
+
await loadMore()
|
89
|
+
}
|
90
|
+
|
91
|
+
return {
|
92
|
+
items,
|
93
|
+
|
94
|
+
refresh,
|
95
|
+
loadMore,
|
96
|
+
|
97
|
+
loading,
|
98
|
+
|
99
|
+
error,
|
100
|
+
}
|
101
|
+
}
|