Skip to content

Commit

Permalink
✨ Sync frequencies
Browse files Browse the repository at this point in the history
  • Loading branch information
naelob committed Sep 9, 2024
1 parent 4acfbc5 commit 4e20c2a
Show file tree
Hide file tree
Showing 81 changed files with 590 additions and 244 deletions.
4 changes: 2 additions & 2 deletions apps/magic-link/src/hooks/useOAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type UseOAuthProps = {
}
};

const useOAuth = ({ providerName, vertical, returnUrl, projectId, linkedUserId,additionalParams, redirectIngressUri, onSuccess }: UseOAuthProps) => {
const useOAuth = ({ providerName, vertical, returnUrl, projectId, linkedUserId, additionalParams, redirectIngressUri, onSuccess }: UseOAuthProps) => {
const [isReady, setIsReady] = useState(false);
const intervalRef = useRef<number | ReturnType<typeof setInterval> | null>(null);
const authWindowRef = useRef<Window | null>(null);
Expand Down Expand Up @@ -51,7 +51,7 @@ const useOAuth = ({ providerName, vertical, returnUrl, projectId, linkedUserId,a
const openModal = async (onWindowClose: () => void) => {
const apiUrl = config.API_URL!;
const authUrl = await constructAuthUrl({
projectId, linkedUserId, providerName, returnUrl, apiUrl , vertical,additionalParams, redirectUriIngress: redirectIngressUri
projectId, linkedUserId, providerName, returnUrl, apiUrl , vertical, additionalParams, redirectUriIngress: redirectIngressUri
});

if (!authUrl) {
Expand Down
34 changes: 0 additions & 34 deletions apps/magic-link/src/lib/ProviderModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ const ProviderModal = () => {
});

const onWindowClose = () => {

setSelectedProvider({
provider: '',
category: ''
Expand Down Expand Up @@ -163,38 +162,6 @@ const ProviderModal = () => {
}
}, [startFlow, isReady]);

Check warning on line 163 in apps/magic-link/src/lib/ProviderModal.tsx

View workflow job for this annotation

GitHub Actions / Changeset

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array

Check warning on line 163 in apps/magic-link/src/lib/ProviderModal.tsx

View workflow job for this annotation

GitHub Actions / Build and Test (18.x)

React Hook useEffect has a missing dependency: 'open'. Either include it or remove the dependency array



const handleWalletClick = (walletName: string, category: string) => {
setSelectedProvider({provider: walletName.toLowerCase(), category: category.toLowerCase()});
const logoPath = CONNECTORS_METADATA[category.toLowerCase()][walletName.toLowerCase()].logoPath;
setCurrentProviderLogoURL(logoPath);
setCurrentProvider(walletName.toLowerCase())
setPreStartFlow(true);
};

const handleStartFlow = () => {
const providerMetadata = CONNECTORS_METADATA[selectedProvider.category][selectedProvider.provider];
if (providerMetadata.authStrategy.strategy === AuthStrategy.api_key || providerMetadata.authStrategy.strategy === AuthStrategy.basic) {
setOpenBasicAuthDialog(true);
} else if (providerMetadata?.options?.end_user_domain) {
setOpenDomainDialog(true);
} else {
// OAUTH2 WITHOUT EXTRA PARAMS
setLoading({ status: true, provider: selectedProvider?.provider! });
setStartFlow(true);
}
}

const handleCategoryClick = (category: string) => {
setPreStartFlow(false);
setSelectedProvider({
provider: '',
category: ''
});
setSelectedCategory(category);
};

const CloseSuccessDialog = (close : boolean) => {
if(!close)
{
Expand Down Expand Up @@ -228,7 +195,6 @@ const ProviderModal = () => {
onCloseBasicAuthDialog(false);
setLoading({status: true, provider: selectedProvider?.provider!});
setPreStartFlow(false);

// Creating Basic Auth Connection
createApiKeyConnection({
query : {
Expand Down
167 changes: 81 additions & 86 deletions apps/webapp/src/app/(Dashboard)/configuration/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import FieldMappingsTable from "@/components/Configuration/FieldMappings/FieldMa
import AddLinkedAccount from "@/components/Configuration/LinkedUsers/AddLinkedAccount";
import useLinkedUsers from "@/hooks/get/useLinkedUsers";
import useFieldMappings from "@/hooks/get/useFieldMappings";
import { useState } from "react";
import { useEffect, useState } from "react";
import AddWebhook from "@/components/Configuration/Webhooks/AddWebhook";
import { WebhooksPage } from "@/components/Configuration/Webhooks/WebhooksPage";
import useWebhooks from "@/hooks/get/useWebhooks";
Expand All @@ -33,27 +33,13 @@ import { LoadingSpinner } from "@/components/ui/loading-spinner";
import { CatalogWidget, verticals } from "@/components/Configuration/Catalog/CatalogWidget";
import { CopySnippet } from "@/components/Configuration/Catalog/CopySnippet";
import {Button as Button2} from "@/components/ui/button2"
import { SelectTrigger, SelectValue, SelectContent, SelectItem } from "@radix-ui/react-select";
import { Select } from "antd";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@/components/ui/select';
import usePullFrequencies from "@/hooks/get/useGetPullFrequencies";
import useUpdatePullFrequency from "@/hooks/create/useCreatePullFrequency";
import { toast } from "sonner";
import { useQueryClient } from "@tanstack/react-query";
import { Badge } from "@/components/ui/badge";

type PullFrequency = {
id_projects_pull_frequency: string;
crm: bigint | null;
ats: bigint | null;
hris: bigint | null;
accounting: bigint | null;
filestorage: bigint | null;
ecommerce: bigint | null;
ticketing: bigint | null;
created_at: Date;
modified_at: Date;
id_project: string;
};
import { Loader2 } from "lucide-react";

const frequencyOptions = [
{ label: '5 min', value: 300 },
Expand All @@ -76,7 +62,10 @@ export default function Page() {
const { createPullFrequencyPromise } = useUpdatePullFrequency();

const [open, setOpen] = useState(false);
const [localFrequencies, setLocalFrequencies] = useState<Record<string, number>>({});
const [localFrequencies, setLocalFrequencies] = useState<Record<string, string>>({});
const [loadingStates, setLoadingStates] = useState<Record<string, boolean>>({});


const queryClient = useQueryClient();

if(error){
Expand Down Expand Up @@ -120,54 +109,51 @@ export default function Page() {
data_type: mapping.data_type,
}))

const handleFrequencyChange = (vertical: string, value: number) => {
const VERTICALS = verticals.filter((vertical) => !["marketingautomation", "cybersecurity", "productivity"].includes(vertical));

useEffect(() => {
if (pullFrequencies) {
const initialFrequencies = VERTICALS.reduce((acc, vertical) => {
const value = pullFrequencies[vertical as keyof typeof pullFrequencies];
acc[vertical] = typeof value === 'string' ? value : '0';
return acc;
}, {} as Record<string, string>);
setLocalFrequencies(initialFrequencies);
}
}, [pullFrequencies]);

const handleFrequencyChange = (vertical: string, value: string) => {
setLocalFrequencies(prev => ({ ...prev, [vertical]: value }));
};

// In your component, add this function:
const getFrequencyValue = (pullFrequencies: PullFrequency[] | undefined, vertical: string): number => {
if (!pullFrequencies || pullFrequencies.length === 0) return 0;
const frequency = pullFrequencies[0][vertical as keyof PullFrequency];
return frequency ? Number(frequency) : 0;
};

const saveFrequencies = async () => {

const saveFrequency = async (vertical: string) => {
setLoadingStates(prev => ({ ...prev, [vertical]: true }));
try {
const updateData = verticals.reduce((acc, vertical) => {
const pullFrequencyValue = pullFrequencies && pullFrequencies[0]?.[vertical as keyof PullFrequency];
acc[vertical] = localFrequencies[vertical] ||
(typeof pullFrequencyValue === 'bigint' ? Number(pullFrequencyValue) :
(typeof pullFrequencyValue === 'number' ? pullFrequencyValue : 0));
return acc;
}, {} as Record<string, number>);
const updateData = { [vertical]: parseInt(localFrequencies[vertical] || '0', 10) };

toast.promise(
createPullFrequencyPromise(updateData),
await toast.promise(
createPullFrequencyPromise(updateData),
{
loading: 'Loading...',
success: (data: any) => {
queryClient.setQueryData<any[]>(['pull-frequencies'], (oldQueryData = []) => {
return [...oldQueryData, data];
});
return (
<div className="flex flex-row items-center">
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.49991 0.877045C3.84222 0.877045 0.877075 3.84219 0.877075 7.49988C0.877075 11.1575 3.84222 14.1227 7.49991 14.1227C11.1576 14.1227 14.1227 11.1575 14.1227 7.49988C14.1227 3.84219 11.1576 0.877045 7.49991 0.877045ZM1.82708 7.49988C1.82708 4.36686 4.36689 1.82704 7.49991 1.82704C10.6329 1.82704 13.1727 4.36686 13.1727 7.49988C13.1727 10.6329 10.6329 13.1727 7.49991 13.1727C4.36689 13.1727 1.82708 10.6329 1.82708 7.49988ZM10.1589 5.53774C10.3178 5.31191 10.2636 5.00001 10.0378 4.84109C9.81194 4.68217 9.50004 4.73642 9.34112 4.96225L6.51977 8.97154L5.35681 7.78706C5.16334 7.59002 4.84677 7.58711 4.64973 7.78058C4.45268 7.97404 4.44978 8.29061 4.64325 8.48765L6.22658 10.1003C6.33054 10.2062 6.47617 10.2604 6.62407 10.2483C6.77197 10.2363 6.90686 10.1591 6.99226 10.0377L10.1589 5.53774Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
<div className="ml-2">
Pull frequencies
<Badge variant="secondary" className="rounded-sm px-1 mx-2 font-normal">{`${data.linked_user_origin_id}`}</Badge>
have been updated
</div>
</div>
)
;
},
error: (err: any) => err.message || 'Error'
});
console.log("Frequencies updated successfully!");
loading: 'Updating...',
success: (data: any) => {
queryClient.setQueryData<any>(['pull-frequencies'], (oldData: any) => ({
...oldData,
[vertical]: localFrequencies[vertical],
}));
return `Frequency saved`;
},
error: (err: any) => err.message || 'Error updating frequency',
}
);
} catch (error) {
console.error("Error updating pull frequencies:", error);
console.error(`Error updating ${vertical} pull frequency:`, error);
} finally {
setLoadingStates(prev => ({ ...prev, [vertical]: false }));
}
};



return (
Expand Down Expand Up @@ -246,37 +232,46 @@ export default function Page() {
<TabsContent value="pull-frequency" className="space-y-4">
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-12">
<Card className="col-span-12">
<CardHeader>
<CardTitle>Pull Frequency Settings</CardTitle>
<CardDescription>Set the sync frequency for each vertical</CardDescription>
</CardHeader>
<CardContent>
{verticals.map(vertical => (
<div key={vertical} className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-1">
{vertical.toUpperCase()}
</label>
<Select
value={(localFrequencies[vertical] || getFrequencyValue(pullFrequencies, vertical))}
onChange={(value: number) => handleFrequencyChange(vertical, value)}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select frequency" />
</SelectTrigger>
<SelectContent>
{frequencyOptions.map(option => (
<SelectItem key={option.value} value={option.value.toString()}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<CardHeader>
<CardTitle>Pull Frequency Settings</CardTitle>
<CardDescription>Set the sync frequency for each vertical</CardDescription>
</CardHeader>
<CardContent>
{VERTICALS.map(vertical => (
<div key={vertical} className="mb-4">
<label className="block text-sm font-medium text-white mb-1">
{vertical.toUpperCase()}
</label>
<div className="flex items-center space-x-2">
<Select
value={localFrequencies[vertical] || '0'}
onValueChange={(value: string) => handleFrequencyChange(vertical, value)}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select frequency" />
</SelectTrigger>
<SelectContent>
{frequencyOptions.map(option => (
<SelectItem key={option.value} value={option.value.toString()}>
{option.label}
</SelectItem>
))}
<Separator className="my-4" />
<Button onClick={saveFrequencies} className="w-full">Save Frequencies</Button>
</CardContent>
</Card>
</SelectContent>
</Select>
<Button
onClick={() => saveFrequency(vertical)}
disabled={loadingStates[vertical]}
>
{loadingStates[vertical] ? (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
) : null}
{loadingStates[vertical] ? 'Saving...' : 'Save'}
</Button>
</div>
</div>
))}
</CardContent>
</Card>
</div>
</TabsContent>

Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/src/hooks/get/useGetPullFrequencies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Cookies from 'js-cookie';
const usePullFrequencies = () => {
return useQuery({
queryKey: ['pull-frequencies'],
queryFn: async (): Promise<PullFrequency[]> => {
queryFn: async (): Promise<PullFrequency> => {
const response = await fetch(`${config.API_URL}/sync/internal/pull-frequencies`,{
method: 'GET',
headers: {
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ services:
POSTHOG_HOST: ${POSTHOG_HOST}
POSTHOG_KEY: ${POSTHOG_KEY}
PH_TELEMETRY: ${PH_TELEMETRY}
SALESFORCE_CRM_CLOUD_CLIENT_ID: ${SALESFORCE_CRM_CLOUD_CLIENT_ID}
SALESFORCE_CRM_CLOUD_CLIENT_SECRET: ${SALESFORCE_CRM_CLOUD_CLIENT_SECRET}

restart: unless-stopped
ports:
Expand Down
4 changes: 3 additions & 1 deletion docker-compose.source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ services:
POSTHOG_HOST: "https://us.i.posthog.com"
POSTHOG_KEY: "phc_WhWJfNPOHAuWVdyTacGxrPa9JW54scnofA9KVEjFcFw"
PH_TELEMETRY: "TRUE"

SALESFORCE_CRM_CLOUD_CLIENT_ID: ${SALESFORCE_CRM_CLOUD_CLIENT_ID}
SALESFORCE_CRM_CLOUD_CLIENT_SECRET: ${SALESFORCE_CRM_CLOUD_CLIENT_SECRET}

restart: unless-stopped
ports:
- 3000:3000
Expand Down
3 changes: 3 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ services:
POSTHOG_HOST: "https://us.i.posthog.com"
POSTHOG_KEY: "phc_WhWJfNPOHAuWVdyTacGxrPa9JW54scnofA9KVEjFcFw"
PH_TELEMETRY: "TRUE"
SALESFORCE_CRM_CLOUD_CLIENT_ID: ${SALESFORCE_CRM_CLOUD_CLIENT_ID}
SALESFORCE_CRM_CLOUD_CLIENT_SECRET: ${SALESFORCE_CRM_CLOUD_CLIENT_SECRET}

restart: unless-stopped
ports:
- 3000:3000
Expand Down
20 changes: 10 additions & 10 deletions packages/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -1639,7 +1639,7 @@ model ecom_product_variants {
/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model events {
id_event String @id(map: "pk_jobs") @db.Uuid
id_connection String @db.Uuid
id_connection String? @db.Uuid
id_project String @db.Uuid
type String
status String
Expand All @@ -1648,8 +1648,8 @@ model events {
url String
provider String
timestamp DateTime @default(now()) @db.Timestamptz(6)
id_linked_user String @db.Uuid
linked_users linked_users @relation(fields: [id_linked_user], references: [id_linked_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_12")
id_linked_user String? @db.Uuid
linked_users linked_users? @relation(fields: [id_linked_user], references: [id_linked_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_12")
jobs_status_history jobs_status_history[]
webhook_delivery_attempts webhook_delivery_attempts[]
Expand Down Expand Up @@ -1965,19 +1965,19 @@ model linked_users {

/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model projects {
id_project String @id(map: "pk_projects") @db.Uuid
id_project String @id(map: "pk_projects") @db.Uuid
name String
sync_mode String
pull_frequency BigInt?
redirect_url String?
id_user String @db.Uuid
id_connector_set String @db.Uuid
id_user String @db.Uuid
id_connector_set String @db.Uuid
api_keys api_keys[]
connections connections[]
linked_users linked_users[]
users users @relation(fields: [id_user], references: [id_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_46_1")
connector_sets connector_sets @relation(fields: [id_connector_set], references: [id_connector_set], onDelete: NoAction, onUpdate: NoAction, map: "fk_project_connectorsetid")
projects_pull_frequency projects_pull_frequency[]
users users @relation(fields: [id_user], references: [id_user], onDelete: NoAction, onUpdate: NoAction, map: "fk_46_1")
connector_sets connector_sets @relation(fields: [id_connector_set], references: [id_connector_set], onDelete: NoAction, onUpdate: NoAction, map: "fk_project_connectorsetid")
projects_pull_frequency projects_pull_frequency?
@@index([id_connector_set], map: "fk_connectors_sets")
}
Expand Down Expand Up @@ -2141,6 +2141,6 @@ model projects_pull_frequency {
ticketing BigInt?
created_at DateTime @default(now()) @db.Timestamptz(6)
modified_at DateTime @default(now()) @db.Timestamptz(6)
id_project String @db.Uuid
id_project String @unique(map: "uq_projects_pull_frequency_project") @db.Uuid
projects projects @relation(fields: [id_project], references: [id_project], onDelete: NoAction, onUpdate: NoAction, map: "fk_projects_pull_frequency_project")
}
Loading

0 comments on commit 4e20c2a

Please sign in to comment.