Add npm packages app settings list (#19324)
solves https://discord.com/channels/1130383047699738754/1488499318762635344
This commit is contained in:
@@ -1724,6 +1724,7 @@ enum FeatureFlagKey {
|
|||||||
IS_AI_ENABLED
|
IS_AI_ENABLED
|
||||||
IS_COMMAND_MENU_ITEM_ENABLED
|
IS_COMMAND_MENU_ITEM_ENABLED
|
||||||
IS_MARKETPLACE_ENABLED
|
IS_MARKETPLACE_ENABLED
|
||||||
|
IS_MARKETPLACE_SETTING_TAB_VISIBLE
|
||||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED
|
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED
|
||||||
IS_PUBLIC_DOMAIN_ENABLED
|
IS_PUBLIC_DOMAIN_ENABLED
|
||||||
IS_EMAILING_DOMAIN_ENABLED
|
IS_EMAILING_DOMAIN_ENABLED
|
||||||
|
|||||||
@@ -1424,7 +1424,7 @@ export interface PublicFeatureFlag {
|
|||||||
__typename: 'PublicFeatureFlag'
|
__typename: 'PublicFeatureFlag'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
|
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
|
||||||
|
|
||||||
export interface ClientConfigMaintenanceMode {
|
export interface ClientConfigMaintenanceMode {
|
||||||
startAt: Scalars['DateTime']
|
startAt: Scalars['DateTime']
|
||||||
@@ -9092,6 +9092,7 @@ export const enumFeatureFlagKey = {
|
|||||||
IS_AI_ENABLED: 'IS_AI_ENABLED' as const,
|
IS_AI_ENABLED: 'IS_AI_ENABLED' as const,
|
||||||
IS_COMMAND_MENU_ITEM_ENABLED: 'IS_COMMAND_MENU_ITEM_ENABLED' as const,
|
IS_COMMAND_MENU_ITEM_ENABLED: 'IS_COMMAND_MENU_ITEM_ENABLED' as const,
|
||||||
IS_MARKETPLACE_ENABLED: 'IS_MARKETPLACE_ENABLED' as const,
|
IS_MARKETPLACE_ENABLED: 'IS_MARKETPLACE_ENABLED' as const,
|
||||||
|
IS_MARKETPLACE_SETTING_TAB_VISIBLE: 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' as const,
|
||||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' as const,
|
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' as const,
|
||||||
IS_PUBLIC_DOMAIN_ENABLED: 'IS_PUBLIC_DOMAIN_ENABLED' as const,
|
IS_PUBLIC_DOMAIN_ENABLED: 'IS_PUBLIC_DOMAIN_ENABLED' as const,
|
||||||
IS_EMAILING_DOMAIN_ENABLED: 'IS_EMAILING_DOMAIN_ENABLED' as const,
|
IS_EMAILING_DOMAIN_ENABLED: 'IS_EMAILING_DOMAIN_ENABLED' as const,
|
||||||
|
|||||||
@@ -1729,6 +1729,7 @@ export enum FeatureFlagKey {
|
|||||||
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
|
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
|
||||||
IS_JUNCTION_RELATIONS_ENABLED = 'IS_JUNCTION_RELATIONS_ENABLED',
|
IS_JUNCTION_RELATIONS_ENABLED = 'IS_JUNCTION_RELATIONS_ENABLED',
|
||||||
IS_MARKETPLACE_ENABLED = 'IS_MARKETPLACE_ENABLED',
|
IS_MARKETPLACE_ENABLED = 'IS_MARKETPLACE_ENABLED',
|
||||||
|
IS_MARKETPLACE_SETTING_TAB_VISIBLE = 'IS_MARKETPLACE_SETTING_TAB_VISIBLE',
|
||||||
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
|
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
|
||||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED = 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED',
|
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED = 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED',
|
||||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED = 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED',
|
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED = 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { getSettingsPath } from 'twenty-shared/utils';
|
|||||||
import { IconApps, IconCode, IconDownload } from 'twenty-ui/display';
|
import { IconApps, IconCode, IconDownload } from 'twenty-ui/display';
|
||||||
import { useQuery } from '@apollo/client/react';
|
import { useQuery } from '@apollo/client/react';
|
||||||
import {
|
import {
|
||||||
type FeatureFlagKey,
|
FeatureFlagKey,
|
||||||
PermissionFlagType,
|
PermissionFlagType,
|
||||||
FindManyApplicationsDocument,
|
FindManyApplicationsDocument,
|
||||||
} from '~/generated-metadata/graphql';
|
} from '~/generated-metadata/graphql';
|
||||||
@@ -33,6 +33,10 @@ export const SettingsApplications = () => {
|
|||||||
'IS_MARKETPLACE_ENABLED' as FeatureFlagKey,
|
'IS_MARKETPLACE_ENABLED' as FeatureFlagKey,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isMarketplaceSettingTabVisible = useIsFeatureEnabled(
|
||||||
|
FeatureFlagKey.IS_MARKETPLACE_SETTING_TAB_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
const activeTabId = useAtomComponentStateValue(
|
const activeTabId = useAtomComponentStateValue(
|
||||||
activeTabIdComponentState,
|
activeTabIdComponentState,
|
||||||
APPLICATIONS_TAB_LIST_ID,
|
APPLICATIONS_TAB_LIST_ID,
|
||||||
@@ -65,7 +69,9 @@ export const SettingsApplications = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ id: 'marketplace', title: t`Marketplace`, Icon: IconDownload },
|
...(isMarketplaceSettingTabVisible
|
||||||
|
? [{ id: 'marketplace', title: t`Marketplace`, Icon: IconDownload }]
|
||||||
|
: []),
|
||||||
{ id: 'installed', title: t`Installed`, Icon: IconApps },
|
{ id: 'installed', title: t`Installed`, Icon: IconApps },
|
||||||
...(hasDeveloperAccess
|
...(hasDeveloperAccess
|
||||||
? [{ id: 'developer', title: t`Developer`, Icon: IconCode }]
|
? [{ id: 'developer', title: t`Developer`, Icon: IconCode }]
|
||||||
@@ -81,7 +87,11 @@ export const SettingsApplications = () => {
|
|||||||
case 'developer':
|
case 'developer':
|
||||||
return <SettingsApplicationsDeveloperTab />;
|
return <SettingsApplicationsDeveloperTab />;
|
||||||
default:
|
default:
|
||||||
return <SettingsApplicationsAvailableTab />;
|
return isMarketplaceSettingTabVisible ? (
|
||||||
|
<SettingsApplicationsAvailableTab />
|
||||||
|
) : (
|
||||||
|
<SettingsApplicationsInstalledTab />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,11 +107,7 @@ export const SettingsApplications = () => {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SettingsPageContainer>
|
<SettingsPageContainer>
|
||||||
<TabList
|
<TabList tabs={tabs} componentInstanceId={APPLICATIONS_TAB_LIST_ID} />
|
||||||
tabs={tabs}
|
|
||||||
componentInstanceId={APPLICATIONS_TAB_LIST_ID}
|
|
||||||
behaveAsLinks={false}
|
|
||||||
/>
|
|
||||||
{renderActiveTabContent()}
|
{renderActiveTabContent()}
|
||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
|
|||||||
+41
-40
@@ -22,8 +22,9 @@ const StyledTableContainer = styled.div`
|
|||||||
margin-top: ${themeCssVariables.spacing[3]};
|
margin-top: ${themeCssVariables.spacing[3]};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledTableHeaderRowContainer = styled.div`
|
const StyledTableRowsContainer = styled.div`
|
||||||
margin-bottom: ${themeCssVariables.spacing[2]};
|
border-bottom: 1px solid ${themeCssVariables.border.color.light};
|
||||||
|
padding: ${themeCssVariables.spacing[2]} 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledSearchInputContainer = styled.div`
|
const StyledSearchInputContainer = styled.div`
|
||||||
@@ -64,47 +65,47 @@ export const SettingsApplicationsTable = ({
|
|||||||
</StyledSearchInputContainer>
|
</StyledSearchInputContainer>
|
||||||
<StyledTableContainer>
|
<StyledTableContainer>
|
||||||
<Table>
|
<Table>
|
||||||
<StyledTableHeaderRowContainer>
|
<TableRow
|
||||||
<TableRow
|
gridTemplateColumns={APPLICATION_TABLE_ROW_GRID_TEMPLATE_COLUMNS}
|
||||||
gridTemplateColumns={APPLICATION_TABLE_ROW_GRID_TEMPLATE_COLUMNS}
|
>
|
||||||
>
|
<TableHeader> {t`Name`}</TableHeader>
|
||||||
<TableHeader> {t`Name`}</TableHeader>
|
<TableHeader> {t`Description`}</TableHeader>
|
||||||
<TableHeader> {t`Description`}</TableHeader>
|
<TableHeader> {''}</TableHeader>
|
||||||
<TableHeader> {''}</TableHeader>
|
<TableHeader />
|
||||||
<TableHeader />
|
</TableRow>
|
||||||
</TableRow>
|
<StyledTableRowsContainer>
|
||||||
</StyledTableHeaderRowContainer>
|
{filteredApplications.map((application) => {
|
||||||
{filteredApplications.map((application) => {
|
const isNpmApp =
|
||||||
const isNpmApp =
|
application.applicationRegistration?.sourceType ===
|
||||||
application.applicationRegistration?.sourceType ===
|
ApplicationRegistrationSourceType.NPM;
|
||||||
ApplicationRegistrationSourceType.NPM;
|
|
||||||
|
|
||||||
const latestVersion =
|
const latestVersion =
|
||||||
application.applicationRegistration?.latestAvailableVersion;
|
application.applicationRegistration?.latestAvailableVersion;
|
||||||
|
|
||||||
const hasUpdate =
|
const hasUpdate =
|
||||||
isNpmApp &&
|
isNpmApp &&
|
||||||
isDefined(latestVersion) &&
|
isDefined(latestVersion) &&
|
||||||
isDefined(application.version) &&
|
isDefined(application.version) &&
|
||||||
isNewerSemver(latestVersion, application.version);
|
isNewerSemver(latestVersion, application.version);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsApplicationTableRow
|
<SettingsApplicationTableRow
|
||||||
key={application.id}
|
key={application.id}
|
||||||
application={application}
|
application={application}
|
||||||
hasUpdate={hasUpdate}
|
hasUpdate={hasUpdate}
|
||||||
action={
|
action={
|
||||||
<IconChevronRight
|
<IconChevronRight
|
||||||
size={theme.icon.size.md}
|
size={theme.icon.size.md}
|
||||||
stroke={theme.icon.stroke.sm}
|
stroke={theme.icon.stroke.sm}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
link={getSettingsPath(SettingsPath.ApplicationDetail, {
|
link={getSettingsPath(SettingsPath.ApplicationDetail, {
|
||||||
applicationId: application.id,
|
applicationId: application.id,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
</StyledTableRowsContainer>
|
||||||
</Table>
|
</Table>
|
||||||
</StyledTableContainer>
|
</StyledTableContainer>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
+129
-5
@@ -1,34 +1,68 @@
|
|||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { SettingsListCard } from '@/settings/components/SettingsListCard';
|
import { SettingsListCard } from '@/settings/components/SettingsListCard';
|
||||||
|
import {
|
||||||
|
StyledActionTableCell,
|
||||||
|
StyledNameTableCell,
|
||||||
|
} from '@/settings/data-model/object-details/components/SettingsObjectItemTableRowStyledComponents';
|
||||||
import { getDocumentationUrl } from '@/support/utils/getDocumentationUrl';
|
import { getDocumentationUrl } from '@/support/utils/getDocumentationUrl';
|
||||||
|
import { Table } from '@/ui/layout/table/components/Table';
|
||||||
|
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||||
|
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||||
|
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||||
import { useQuery } from '@apollo/client/react';
|
import { useQuery } from '@apollo/client/react';
|
||||||
import { styled } from '@linaria/react';
|
import { styled } from '@linaria/react';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
|
import { useContext, useMemo, useState } from 'react';
|
||||||
import { SettingsPath } from 'twenty-shared/types';
|
import { SettingsPath } from 'twenty-shared/types';
|
||||||
import { getSettingsPath } from 'twenty-shared/utils';
|
import { getSettingsPath } from 'twenty-shared/utils';
|
||||||
import { Tag } from 'twenty-ui/components';
|
import { Tag } from 'twenty-ui/components';
|
||||||
import {
|
import {
|
||||||
|
Avatar,
|
||||||
CommandBlock,
|
CommandBlock,
|
||||||
H2Title,
|
H2Title,
|
||||||
IconApps,
|
IconApps,
|
||||||
|
IconChevronRight,
|
||||||
IconCopy,
|
IconCopy,
|
||||||
IconFileInfo,
|
IconFileInfo,
|
||||||
|
OverflowingTextWithTooltip,
|
||||||
} from 'twenty-ui/display';
|
} from 'twenty-ui/display';
|
||||||
import { Button } from 'twenty-ui/input';
|
import { Button, SearchInput } from 'twenty-ui/input';
|
||||||
import { Section } from 'twenty-ui/layout';
|
import { Section } from 'twenty-ui/layout';
|
||||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||||
|
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||||
import {
|
import {
|
||||||
type ApplicationRegistrationFragmentFragment,
|
type ApplicationRegistrationFragmentFragment,
|
||||||
ApplicationRegistrationSourceType,
|
ApplicationRegistrationSourceType,
|
||||||
|
FeatureFlagKey,
|
||||||
FindManyApplicationRegistrationsDocument,
|
FindManyApplicationRegistrationsDocument,
|
||||||
} from '~/generated-metadata/graphql';
|
} from '~/generated-metadata/graphql';
|
||||||
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
|
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
|
||||||
|
import { useMarketplaceApps } from '~/modules/marketplace/hooks/useMarketplaceApps';
|
||||||
|
|
||||||
const StyledButtonContainer = styled.div`
|
const StyledButtonContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
margin: ${themeCssVariables.spacing[2]} 0;
|
margin: ${themeCssVariables.spacing[2]} 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledSearchInputContainer = styled.div`
|
||||||
|
padding-bottom: ${themeCssVariables.spacing[2]};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledEmptyState = styled.div`
|
||||||
|
color: ${themeCssVariables.font.color.tertiary};
|
||||||
|
padding: ${themeCssVariables.spacing[8]};
|
||||||
|
text-align: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledTableRowsContainer = styled.div`
|
||||||
|
border-bottom: 1px solid ${themeCssVariables.border.color.light};
|
||||||
|
padding: ${themeCssVariables.spacing[2]} 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const NPM_PACKAGES_GRID_COLUMNS = '200px 1fr 36px';
|
||||||
|
|
||||||
const SOURCE_TYPE_BADGE_CONFIG: Record<
|
const SOURCE_TYPE_BADGE_CONFIG: Record<
|
||||||
ApplicationRegistrationSourceType,
|
ApplicationRegistrationSourceType,
|
||||||
{ label: string; color: 'gray' | 'blue' | 'green' }
|
{ label: string; color: 'gray' | 'blue' | 'green' }
|
||||||
@@ -53,12 +87,34 @@ const SOURCE_TYPE_BADGE_CONFIG: Record<
|
|||||||
|
|
||||||
export const SettingsApplicationsDeveloperTab = () => {
|
export const SettingsApplicationsDeveloperTab = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
|
const { theme } = useContext(ThemeContext);
|
||||||
const currentWorkspaceMember = useAtomStateValue(currentWorkspaceMemberState);
|
const currentWorkspaceMember = useAtomStateValue(currentWorkspaceMemberState);
|
||||||
|
|
||||||
const { copyToClipboard } = useCopyToClipboard();
|
const { copyToClipboard } = useCopyToClipboard();
|
||||||
|
|
||||||
const { data, loading } = useQuery(FindManyApplicationRegistrationsDocument);
|
const { data, loading } = useQuery(FindManyApplicationRegistrationsDocument);
|
||||||
|
|
||||||
|
const isMarketplaceSettingTabVisible = useIsFeatureEnabled(
|
||||||
|
FeatureFlagKey.IS_MARKETPLACE_SETTING_TAB_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
const [npmSearchTerm, setNpmSearchTerm] = useState('');
|
||||||
|
const { data: marketplaceApps } = useMarketplaceApps();
|
||||||
|
|
||||||
|
const filteredMarketplaceApps = useMemo(() => {
|
||||||
|
if (!npmSearchTerm) {
|
||||||
|
return marketplaceApps;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lowerSearch = npmSearchTerm.toLowerCase();
|
||||||
|
|
||||||
|
return marketplaceApps.filter(
|
||||||
|
(application) =>
|
||||||
|
application.name.toLowerCase().includes(lowerSearch) ||
|
||||||
|
application.description.toLowerCase().includes(lowerSearch),
|
||||||
|
);
|
||||||
|
}, [marketplaceApps, npmSearchTerm]);
|
||||||
|
|
||||||
const registrations: ApplicationRegistrationFragmentFragment[] =
|
const registrations: ApplicationRegistrationFragmentFragment[] =
|
||||||
data?.findManyApplicationRegistrations ?? [];
|
data?.findManyApplicationRegistrations ?? [];
|
||||||
|
|
||||||
@@ -123,8 +179,8 @@ export const SettingsApplicationsDeveloperTab = () => {
|
|||||||
<>
|
<>
|
||||||
<Section>
|
<Section>
|
||||||
<H2Title
|
<H2Title
|
||||||
title={t`Create & Develop`}
|
title={t`Create an application`}
|
||||||
description={t`Scaffold a new app, then use the CLI to develop, publish, and distribute`}
|
description={t`You can either create a private app or share it to others`}
|
||||||
/>
|
/>
|
||||||
<CommandBlock commands={createCommands} button={createCopyButton} />
|
<CommandBlock commands={createCommands} button={createCopyButton} />
|
||||||
<StyledButtonContainer>
|
<StyledButtonContainer>
|
||||||
@@ -146,7 +202,7 @@ export const SettingsApplicationsDeveloperTab = () => {
|
|||||||
|
|
||||||
<Section>
|
<Section>
|
||||||
<H2Title
|
<H2Title
|
||||||
title={t`Your Apps`}
|
title={t`Your apps`}
|
||||||
description={t`All applications registered on this workspace`}
|
description={t`All applications registered on this workspace`}
|
||||||
/>
|
/>
|
||||||
{registrations.length > 0 ? (
|
{registrations.length > 0 ? (
|
||||||
@@ -164,6 +220,74 @@ export const SettingsApplicationsDeveloperTab = () => {
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
{!isMarketplaceSettingTabVisible && (
|
||||||
|
<Section>
|
||||||
|
<H2Title
|
||||||
|
title={t`NPM packages`}
|
||||||
|
description={t`Apps made by other developers published on npm`}
|
||||||
|
/>
|
||||||
|
<StyledSearchInputContainer>
|
||||||
|
<SearchInput
|
||||||
|
placeholder={t`Search an application`}
|
||||||
|
value={npmSearchTerm}
|
||||||
|
onChange={setNpmSearchTerm}
|
||||||
|
/>
|
||||||
|
</StyledSearchInputContainer>
|
||||||
|
{filteredMarketplaceApps.length === 0 ? (
|
||||||
|
<StyledEmptyState>{t`No application found`}</StyledEmptyState>
|
||||||
|
) : (
|
||||||
|
<Table>
|
||||||
|
<TableRow gridAutoColumns={NPM_PACKAGES_GRID_COLUMNS}>
|
||||||
|
<TableHeader>{t`Name`}</TableHeader>
|
||||||
|
<TableHeader>{t`Description`}</TableHeader>
|
||||||
|
<TableHeader />
|
||||||
|
</TableRow>
|
||||||
|
<StyledTableRowsContainer>
|
||||||
|
{filteredMarketplaceApps.map((application) => (
|
||||||
|
<TableRow
|
||||||
|
key={application.id}
|
||||||
|
gridAutoColumns={NPM_PACKAGES_GRID_COLUMNS}
|
||||||
|
to={getSettingsPath(
|
||||||
|
SettingsPath.AvailableApplicationDetail,
|
||||||
|
{
|
||||||
|
availableApplicationId: application.id,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<StyledNameTableCell>
|
||||||
|
<Avatar
|
||||||
|
avatarUrl={application.logo || null}
|
||||||
|
placeholder={application.name}
|
||||||
|
placeholderColorSeed={application.name}
|
||||||
|
size="md"
|
||||||
|
type="squared"
|
||||||
|
/>
|
||||||
|
<OverflowingTextWithTooltip text={application.name} />
|
||||||
|
</StyledNameTableCell>
|
||||||
|
<TableCell
|
||||||
|
overflow="hidden"
|
||||||
|
textOverflow="ellipsis"
|
||||||
|
whiteSpace="nowrap"
|
||||||
|
>
|
||||||
|
<OverflowingTextWithTooltip
|
||||||
|
text={application.description}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<StyledActionTableCell>
|
||||||
|
<IconChevronRight
|
||||||
|
size={theme.icon.size.md}
|
||||||
|
stroke={theme.icon.stroke.sm}
|
||||||
|
color={theme.font.color.tertiary}
|
||||||
|
/>
|
||||||
|
</StyledActionTableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</StyledTableRowsContainer>
|
||||||
|
</Table>
|
||||||
|
)}
|
||||||
|
</Section>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+1
@@ -234,6 +234,7 @@ describe('WorkspaceEntityManager', () => {
|
|||||||
IS_JSON_FILTER_ENABLED: false,
|
IS_JSON_FILTER_ENABLED: false,
|
||||||
IS_AI_ENABLED: false,
|
IS_AI_ENABLED: false,
|
||||||
IS_MARKETPLACE_ENABLED: false,
|
IS_MARKETPLACE_ENABLED: false,
|
||||||
|
IS_MARKETPLACE_SETTING_TAB_VISIBLE: false,
|
||||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: false,
|
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: false,
|
||||||
IS_PUBLIC_DOMAIN_ENABLED: false,
|
IS_PUBLIC_DOMAIN_ENABLED: false,
|
||||||
IS_EMAILING_DOMAIN_ENABLED: false,
|
IS_EMAILING_DOMAIN_ENABLED: false,
|
||||||
|
|||||||
+5
@@ -50,6 +50,11 @@ export const seedFeatureFlags = async ({
|
|||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
value: true,
|
value: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: FeatureFlagKey.IS_MARKETPLACE_SETTING_TAB_VISIBLE,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: FeatureFlagKey.IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED,
|
key: FeatureFlagKey.IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED,
|
||||||
workspaceId: workspaceId,
|
workspaceId: workspaceId,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export enum FeatureFlagKey {
|
|||||||
IS_AI_ENABLED = 'IS_AI_ENABLED',
|
IS_AI_ENABLED = 'IS_AI_ENABLED',
|
||||||
IS_COMMAND_MENU_ITEM_ENABLED = 'IS_COMMAND_MENU_ITEM_ENABLED',
|
IS_COMMAND_MENU_ITEM_ENABLED = 'IS_COMMAND_MENU_ITEM_ENABLED',
|
||||||
IS_MARKETPLACE_ENABLED = 'IS_MARKETPLACE_ENABLED',
|
IS_MARKETPLACE_ENABLED = 'IS_MARKETPLACE_ENABLED',
|
||||||
|
IS_MARKETPLACE_SETTING_TAB_VISIBLE = 'IS_MARKETPLACE_SETTING_TAB_VISIBLE',
|
||||||
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED = 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED',
|
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED = 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED',
|
||||||
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
|
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
|
||||||
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
|
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { themeCssVariables } from '@ui/theme-constants';
|
|||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
border-radius: ${themeCssVariables.border.radius.sm};
|
border-radius: ${themeCssVariables.border.radius.sm};
|
||||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||||
background: ${themeCssVariables.background.transparent.secondary};
|
background: ${themeCssVariables.background.secondary};
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: ${themeCssVariables.spacing[3]};
|
padding: ${themeCssVariables.spacing[3]};
|
||||||
|
|||||||
Reference in New Issue
Block a user