-
-
+
+
+
+
+
+
+ {{ nativeRepos.length }}
+ {{ nativeRepos.length !== 1 ? "remote URLs" : "remote URL" }}
+
+
+
+
+ Git Remote URLs
+
+
+
+
+
/
+
+
+
-
- {{ repositories.length }}
- {{ repositories.length !== 1 ? "remote URLs" : "remote URL" }}
+ {{ pluralize('repository', groupedMirroredRepos[gmKey].length, true) }} (via {{ getIntegrationName(gmKey) }})
- Git Remote URLs
+ Repositories
-
+
+ /
+
-
+
+
diff --git a/frontend/src/config/integrations/git/config.ts b/frontend/src/config/integrations/git/config.ts
index 9e4de87ca4..8c1004b5fb 100644
--- a/frontend/src/config/integrations/git/config.ts
+++ b/frontend/src/config/integrations/git/config.ts
@@ -10,7 +10,7 @@ const git: IntegrationConfig = {
key: 'git',
name: 'Git',
image,
- description: 'Connect Git to sync commit activities from your repos.',
+ description: 'Sync commit activities from Git repositories.',
connectComponent: GitConnect,
dropdownComponent: GitDropdown,
connectedParamsComponent: GitParams,
diff --git a/frontend/src/config/integrations/github-nango/components/connect/github-connect.vue b/frontend/src/config/integrations/github-nango/components/connect/github-connect.vue
deleted file mode 100644
index fbf455d262..0000000000
--- a/frontend/src/config/integrations/github-nango/components/connect/github-connect.vue
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Connect
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend/src/config/integrations/github-nango/components/github-connect.vue b/frontend/src/config/integrations/github-nango/components/github-connect.vue
deleted file mode 100644
index cf0ed4d7d7..0000000000
--- a/frontend/src/config/integrations/github-nango/components/github-connect.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
- Connect
-
-
-
-
-
-
-
-
-
diff --git a/frontend/src/config/integrations/github-nango/components/github-mapped-repos.vue b/frontend/src/config/integrations/github-nango/components/github-mapped-repos.vue
deleted file mode 100644
index f8d1dbfe24..0000000000
--- a/frontend/src/config/integrations/github-nango/components/github-mapped-repos.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
- Syncing GitHub data from {{ mappedReposWithOtherProject.project }} project
- for {{ pluralize('repository', mappedReposWithOtherProject.repositories.length, true) }}.
-
-
-
-
- Mapped GitHub repositories
-
-
-
-
-
-
-
-
-
diff --git a/frontend/src/config/integrations/github-nango/components/github-params.vue b/frontend/src/config/integrations/github-nango/components/github-params.vue
index 278198f817..e0281b05dd 100644
--- a/frontend/src/config/integrations/github-nango/components/github-params.vue
+++ b/frontend/src/config/integrations/github-nango/components/github-params.vue
@@ -1,76 +1,31 @@
-
-
-
-
-
-
- {{ pluralize('repository', Object.keys(mappings).length, true) }}
-
-
-
- {{ mappedRepositories.length }} out of
- {{ allRepositoriesNames.length }} repositories connected
-
-
-
-
- {{ isInProgress ? 'Connected GitHub repositories' : 'GitHub repositories' }}
-
-
-
-
+
+
+
+
+ {{ mappedRepositories.length }} out of
+ {{ allRepositoriesNames.length }} repositories connected
+
+
+
+ Connected GitHub repositories
+
+
-
-
diff --git a/frontend/src/config/integrations/github/components/github-connect.vue b/frontend/src/config/integrations/github/components/github-connect.vue
index 7dac4be9c2..13c5f6dcf1 100644
--- a/frontend/src/config/integrations/github/components/github-connect.vue
+++ b/frontend/src/config/integrations/github/components/github-connect.vue
@@ -1,38 +1,113 @@
-
-
-
-
-
-
-
- Connect
-
-
-
+
+
+
+
+ Connect
+
+
+
+
+
+
+
+
+ GitHub - New integration
+
+
+ Sync repositories from multiple GitHub organizations. Doesn’t require organization admin permissions.
+
+
+
+
+
+
+
+
+
+ GitHub - Old integration
+
+
+ Sync repositories from a GitHub organization. Requires organization admin permissions.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/config/integrations/github/components/github-mappings-display.vue b/frontend/src/config/integrations/github/components/github-mappings-display.vue
new file mode 100644
index 0000000000..431d182ad7
--- /dev/null
+++ b/frontend/src/config/integrations/github/components/github-mappings-display.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+ {{ pluralize("repository", Object.keys(mappings).length, true) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ pluralize("repository", Object.keys(mappings).length, true) }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/config/integrations/github/components/github-params.vue b/frontend/src/config/integrations/github/components/github-params.vue
index 275c1af234..942c81718f 100644
--- a/frontend/src/config/integrations/github/components/github-params.vue
+++ b/frontend/src/config/integrations/github/components/github-params.vue
@@ -1,59 +1,18 @@
-
-
-
-
-
-
- {{ pluralize("repository", Object.keys(mappings).length, true) }}
-
-
-
-
-
- GitHub repositories
-
-
-
-
+
diff --git a/frontend/src/config/integrations/github/components/settings/github-settings-drawer.vue b/frontend/src/config/integrations/github/components/settings/github-settings-drawer.vue
index ab46827e4d..19ca04d0e9 100644
--- a/frontend/src/config/integrations/github/components/settings/github-settings-drawer.vue
+++ b/frontend/src/config/integrations/github/components/settings/github-settings-drawer.vue
@@ -6,6 +6,8 @@
pre-title="Integration"
:show-footer="true"
has-border
+ close-on-click-modal="true"
+ :close-function="canClose"
@close="isDrawerVisible = false"
>
@@ -15,14 +17,26 @@
alt="GitHub logo"
/>
+
+
+
+
+
+
+
+
+ Connected repositories are also synced through Git, which automatically mirrors your
+ GitHub settings for adding, updating, and deleting repositories.
+
+
-
+
Connected organization
@@ -57,7 +71,7 @@
Bulk selection
-
+
Select the subproject you want to map with each connected
repository.
@@ -85,9 +99,10 @@
v-model="search"
clearable
placeholder="Search repositories..."
+ class="is-rounded"
>
-
+
@@ -97,14 +112,14 @@
SUB-PROJECT
@@ -117,7 +132,7 @@
class="py-1.5 flex items-center"
>
-
+
/{{ repo.name }}
@@ -134,7 +149,7 @@
-
+
No repositories found
@@ -169,25 +184,16 @@
-
-
- Cancel
-
-
- Connect
-
-
+
+
+
+
diff --git a/frontend/src/modules/admin/modules/integration/components/drawer-description.vue b/frontend/src/modules/admin/modules/integration/components/drawer-description.vue
new file mode 100644
index 0000000000..a378137946
--- /dev/null
+++ b/frontend/src/modules/admin/modules/integration/components/drawer-description.vue
@@ -0,0 +1,31 @@
+
+
+ {{ integration.description }}
+
+
+ Learn more
+
+
+
+
+
diff --git a/frontend/src/modules/admin/modules/integration/components/drawer-footer-buttons.vue b/frontend/src/modules/admin/modules/integration/components/drawer-footer-buttons.vue
new file mode 100644
index 0000000000..6abda6d623
--- /dev/null
+++ b/frontend/src/modules/admin/modules/integration/components/drawer-footer-buttons.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+ Disconnect
+
+
+
+
+ Disconnect
+
+
+
+
+
+ Cancel
+
+
+
+ Revert changes
+
+
+
+
+ {{ isEditMode ? 'Update' : 'Connect' }}
+
+
+
+
+ {{ isEditMode ? 'Update' : 'Connect' }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/modules/admin/modules/integration/components/integration-confirmation-modal.vue b/frontend/src/modules/admin/modules/integration/components/integration-confirmation-modal.vue
new file mode 100644
index 0000000000..bbce588051
--- /dev/null
+++ b/frontend/src/modules/admin/modules/integration/components/integration-confirmation-modal.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
Are you sure you want to disconnect this integration?
+
+ Once disconnected, data will no longer sync from this source.
+ You can reconnect anytime to resume syncing, but this action can’t be undone.
+
+
+
+ Type DISCONNECT to confirm
+
+
+
+
+
+
+ Cancel
+
+
+ Disconnect integration
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/modules/admin/modules/integration/components/integration-list-item.vue b/frontend/src/modules/admin/modules/integration/components/integration-list-item.vue
index ba0b8f0e4c..e2f1e941e5 100644
--- a/frontend/src/modules/admin/modules/integration/components/integration-list-item.vue
+++ b/frontend/src/modules/admin/modules/integration/components/integration-list-item.vue
@@ -1,9 +1,9 @@
-
+
-
- {{ props.config.name }}
+
+ {{ props.config.name.replace(' (v2)', '') }}
+
-
+
{{ props.config.description }}
@@ -27,7 +28,7 @@
-
+
-
+
-
-
-
- {{ props.config.name }} integration failed to connect due to an API error.
-
+
+
+
+
+ {{ props.config.name }} integration failed to connect due to an API error.
+
-
+
+
+
+
+ •
+ Last data check completed {{ lastDataCheckCompleted }}
+
+
-
- •
- Last data check completed {{ lastDataCheckCompleted }}
-
-
-
+
-
-
- Disconnect integration
-
+
+
+
+ Disconnect integration
+
+
-
-
-
-
-
-
-
-
-
Are you sure you want to disconnect this integration?
-
- Once disconnected, data will no longer sync from this source.
- You can reconnect anytime to resume syncing, but this action can’t be undone.
-
-
-
- Type DISCONNECT to confirm
-
-
-
-
-
-
- Cancel
-
-
- Disconnect integration
-
-
-
-
+
+
+
diff --git a/frontend/src/ui-kit/lfx/tabs/tabs.scss b/frontend/src/ui-kit/lfx/tabs/tabs.scss
new file mode 100644
index 0000000000..dee1b7ed67
--- /dev/null
+++ b/frontend/src/ui-kit/lfx/tabs/tabs.scss
@@ -0,0 +1,32 @@
+.lfx-c-tabs {
+ @apply flex relative whitespace-nowrap w-fit transition bg-gray-100 rounded-full gap-1 p-1;
+
+ &--small {
+ .lfx-c-tab {
+ --lf-tab-font-size: var(--lf-tabs-small-font-size);
+ --lf-tab-line-height: var(--lf-tabs-small-line-height);
+ --lf-tab-padding: var(--lf-tabs-small-padding);
+ }
+ }
+
+ &--medium {
+ .lfx-c-tab {
+ --lf-tab-font-size: var(--lf-tabs-medium-font-size);
+ --lf-tab-line-height: var(--lf-tabs-medium-line-height);
+ --lf-tab-padding: var(--lf-tabs-medium-padding);
+ }
+ }
+}
+
+.lfx-c-tab {
+ @apply flex items-center justify-center text-center cursor-pointer transition-all select-none;
+ @apply rounded-full px-3 py-1 text-gray-600 font-normal leading-5 text-sm;
+
+ &:hover {
+ background: var(--lf-tab-hover-background);
+ }
+
+ &.is-active {
+ @apply bg-white text-gray-900 font-medium;
+ }
+}
diff --git a/frontend/src/ui-kit/lfx/tabs/tabs.vue b/frontend/src/ui-kit/lfx/tabs/tabs.vue
new file mode 100644
index 0000000000..9f61cca9ca
--- /dev/null
+++ b/frontend/src/ui-kit/lfx/tabs/tabs.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/ui-kit/lfx/tabs/types/TabsSize.ts b/frontend/src/ui-kit/lfx/tabs/types/TabsSize.ts
new file mode 100644
index 0000000000..fd90a69e52
--- /dev/null
+++ b/frontend/src/ui-kit/lfx/tabs/types/TabsSize.ts
@@ -0,0 +1,6 @@
+export const tabsSize = [
+ 'small',
+ 'medium',
+] as const;
+
+export type TabsSize = typeof tabsSize[number];
diff --git a/frontend/src/ui-kit/switch/switch.scss b/frontend/src/ui-kit/switch/switch.scss
index bd5a180eda..c28046d43a 100644
--- a/frontend/src/ui-kit/switch/switch.scss
+++ b/frontend/src/ui-kit/switch/switch.scss
@@ -40,7 +40,7 @@
// Disabled
&:disabled {
--lf-switch-handle: var(--lf-switch-disabled-unchecked-handle);
- --lf-switch-background: var(--lf-switch-unchecked-background);
+ --lf-switch-background: var(--lf-switch-disabled-background);
@apply cursor-not-allowed opacity-60;
&:checked {
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 4787e63d16..dac7f04623 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -120,6 +120,18 @@ module.exports = {
100: 'var(--lf-color-secondary-100)',
50: 'var(--lf-color-secondary-50)',
},
+ brand: {
+ 900: 'var(--lf-color-brand-900)',
+ 800: 'var(--lf-color-brand-800)',
+ 700: 'var(--lf-color-brand-700)',
+ 600: 'var(--lf-color-brand-600)',
+ 500: 'var(--lf-color-brand-500)',
+ 400: 'var(--lf-color-brand-400)',
+ 300: 'var(--lf-color-brand-300)',
+ 200: 'var(--lf-color-brand-200)',
+ 100: 'var(--lf-color-brand-100)',
+ 50: 'var(--lf-color-brand-50)',
+ },
gray: {
900: 'var(--lf-color-gray-900)',
800: 'var(--lf-color-gray-800)',
@@ -133,6 +145,18 @@ module.exports = {
100: 'var(--lf-color-gray-100)',
50: 'var(--lf-color-gray-50)',
},
+ neutral: {
+ 900: 'var(--lf-color-neutral-900)',
+ 800: 'var(--lf-color-neutral-800)',
+ 700: 'var(--lf-color-neutral-700)',
+ 600: 'var(--lf-color-neutral-600)',
+ 500: 'var(--lf-color-neutral-500)',
+ 400: 'var(--lf-color-neutral-400)',
+ 300: 'var(--lf-color-neutral-300)',
+ 200: 'var(--lf-color-neutral-200)',
+ 100: 'var(--lf-color-neutral-100)',
+ 50: 'var(--lf-color-neutral-50)',
+ },
red: {
900: 'var(--lf-color-red-900)',
800: 'var(--lf-color-red-800)',
@@ -193,7 +217,7 @@ module.exports = {
lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
'2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
- xs: '0 1px 2px -1px rgba(0, 0, 0, 0.10), 0 1px 3px 0 rgba(0, 0, 0, 0.10)',
+ xs: '0 1px 2px 0 rgba(0, 0, 0, 0.02)',
},
fontSize: {
'4xs': ['0.5rem'],
diff --git a/services/libs/data-access-layer/src/segments/index.ts b/services/libs/data-access-layer/src/segments/index.ts
index 9174044baa..0d1ce81acc 100644
--- a/services/libs/data-access-layer/src/segments/index.ts
+++ b/services/libs/data-access-layer/src/segments/index.ts
@@ -351,6 +351,39 @@ export async function getMappedWithSegmentName(
return result?.segment_name ?? null
}
+export async function getMappedAllWithSegmentName(
+ qx: QueryExecutor,
+ segmentId: string,
+ platforms: PlatformType[],
+): Promise<{ segmentName: string; url: string }[]> {
+ if (platforms.length === 0) {
+ return []
+ }
+
+ const results = await qx.select(
+ `
+ SELECT DISTINCT s.name as segment_name, r.url
+ FROM public.repositories r
+ LEFT JOIN integrations i ON r."sourceIntegrationId" = i.id
+ LEFT JOIN segments s ON i."segmentId" = s.id
+ WHERE r."segmentId" = $(segmentId)
+ AND r."deletedAt" IS NULL
+ AND (
+ i.id IS NULL
+ OR (i.platform = ANY($(platforms)::text[]) AND i."segmentId" <> $(segmentId))
+ )
+ `,
+ { segmentId, platforms },
+ )
+
+ return results
+ .filter((r: { segment_name: string; url: string }) => r.segment_name)
+ .map((r: { segment_name: string; url: string }) => ({
+ segmentName: r.segment_name,
+ url: r.url,
+ }))
+}
+
export interface ISegment {
id: string
name: string