Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions web/sdk/client/views/service-accounts/components/add-token-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
type ServiceUserToken
} from '@raystack/proton/frontier';
import { useFrontier } from '~/client/contexts/FrontierContext';
import type { Slot } from '~/shared/types';
import styles from '../service-account-details-view.module.css';

const tokenSchema = yup
Expand All @@ -26,9 +27,18 @@ type FormData = yup.InferType<typeof tokenSchema>;
export interface AddTokenFormProps {
serviceUserId: string;
onAddToken: (token: ServiceUserToken) => void;
generateKeyButton?: Slot<{
Comment thread
rohanchkrabrty marked this conversation as resolved.
onClick: () => void;
loading: boolean;
disabled: boolean;
}>;
}

export function AddTokenForm({ serviceUserId, onAddToken }: AddTokenFormProps) {
export function AddTokenForm({
serviceUserId,
onAddToken,
generateKeyButton
}: AddTokenFormProps) {
const { activeOrganization } = useFrontier();
const orgId = activeOrganization?.id || '';

Expand Down Expand Up @@ -78,24 +88,28 @@ export function AddTokenForm({ serviceUserId, onAddToken }: AddTokenFormProps) {
error={errors.title && String(errors.title?.message)}
className={styles.addTokenInput}
>
<Input
{...register('title')}
size="large"
placeholder="Label Name"
/>
<Input {...register('title')} size="large" placeholder="Label Name" />
</Field>
<Button
variant="solid"
color="accent"
size="normal"
type="submit"
loading={isSubmitting}
disabled={isSubmitting}
loaderText="Generating..."
data-test-id="frontier-sdk-service-account-generate-key-btn"
>
Generate new key
</Button>
{generateKeyButton ? (
generateKeyButton({
onClick: handleSubmit(onSubmit),
loading: isSubmitting,
disabled: isSubmitting
})
) : (
<Button
variant="solid"
color="accent"
size="normal"
type="submit"
loading={isSubmitting}
disabled={isSubmitting}
loaderText="Generating..."
data-test-id="frontier-sdk-service-account-generate-key-btn"
>
Generate new key
</Button>
)}
</Flex>
</form>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { PERMISSIONS, shouldShowComponent } from '~/utils';
import { useServiceUserTokens } from './hooks/useServiceUserTokens';
import { ViewContainer } from '~/client/components/view-container';
import { ViewHeader } from '~/client/components/view-header';
import { AddTokenForm } from './components/add-token-form';
import { AddTokenForm, type AddTokenFormProps } from './components/add-token-form';
import {
RevokeTokenDialog,
type RevokeTokenPayload
Expand All @@ -53,13 +53,17 @@ export interface ServiceAccountDetailsViewProps {
serviceAccountsLabel?: string;
onNavigateToServiceAccounts?: () => void;
onDeleteSuccess?: () => void;
slots?: {
generateKeyButton?: AddTokenFormProps['generateKeyButton'];
};
}

export function ServiceAccountDetailsView({
serviceAccountId,
serviceAccountsLabel = 'Service accounts',
onNavigateToServiceAccounts,
onDeleteSuccess
onDeleteSuccess,
slots
}: ServiceAccountDetailsViewProps) {
const { activeOrganization: organization } = useFrontier();
const t = useTerminology();
Expand Down Expand Up @@ -166,6 +170,7 @@ export function ServiceAccountDetailsView({
<AddTokenForm
serviceUserId={serviceAccountId}
onAddToken={addToken}
generateKeyButton={slots?.generateKeyButton}
/>
</>
)}
Expand Down
42 changes: 30 additions & 12 deletions web/sdk/client/views/service-accounts/service-accounts-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
} from '@raystack/apsara';
import deleteIcon from '~/client/assets/delete.svg';
import keyIcon from '~/client/assets/key.svg';
import exclamationTriangleIcon from '~/client/assets/exclamation-triangle.svg';
import { useQuery } from '@connectrpc/connect-query';
import { create } from '@bufbuild/protobuf';
import {
Expand All @@ -31,6 +30,7 @@ import { PERMISSIONS, shouldShowComponent } from '~/utils';
import { DEFAULT_DATE_FORMAT } from '~/client/utils/constants';
import { ViewContainer } from '~/client/components/view-container';
import { ViewHeader } from '~/client/components/view-header';
import type { Slot } from '~/shared/types';
import {
getColumns,
type ServiceAccountMenuPayload
Expand All @@ -50,10 +50,14 @@ const manageAccessDialogHandle = Dialog.createHandle<string>();

export interface ServiceAccountsViewProps {
onServiceAccountClick?: (id: string) => void;
slots?: {
addAccountButton?: Slot<{ onClick: () => void; disabled: boolean }>;
};
}

export function ServiceAccountsView({
onServiceAccountClick
onServiceAccountClick,
slots
}: ServiceAccountsViewProps) {
const {
activeOrganization: organization,
Expand Down Expand Up @@ -126,6 +130,8 @@ export function ServiceAccountsView({
[dateFormat, canUpdateWorkspace]
);

const handleAddServiceAccount = () => addDialogHandle.open(null);

const handleCreated = (serviceUserId: string) => {
onServiceAccountClick?.(serviceUserId);
};
Expand Down Expand Up @@ -167,15 +173,22 @@ export function ServiceAccountsView({
heading="No Service Account Found"
subHeading={`Create a new account to use the APIs of ${t.appName()} platform`}
primaryAction={
<Button
variant="solid"
color="accent"
size="small"
onClick={() => addDialogHandle.open(null)}
data-test-id="frontier-sdk-new-service-account-btn"
>
Add service account
</Button>
slots?.addAccountButton ? (
slots.addAccountButton({
onClick: handleAddServiceAccount,
disabled: false
})
) : (
<Button
variant="solid"
color="accent"
size="small"
onClick={handleAddServiceAccount}
data-test-id="frontier-sdk-new-service-account-btn"
>
Add service account
</Button>
)
}
/>
) : (
Expand Down Expand Up @@ -207,6 +220,11 @@ export function ServiceAccountsView({
</Flex>
{isLoading ? (
<Skeleton height="34px" width="160px" />
) : slots?.addAccountButton ? (
slots.addAccountButton({
onClick: handleAddServiceAccount,
disabled: !canUpdateWorkspace
})
) : (
<Tooltip>
<Tooltip.Trigger
Expand All @@ -216,7 +234,7 @@ export function ServiceAccountsView({
<Button
variant="solid"
color="accent"
onClick={() => addDialogHandle.open(null)}
onClick={handleAddServiceAccount}
disabled={!canUpdateWorkspace}
data-test-id="frontier-sdk-add-service-account-btn"
>
Expand Down
12 changes: 12 additions & 0 deletions web/sdk/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import React from 'react';
import { BasePlan } from '../src/types';
import { ThemeProviderProps } from '@raystack/apsara';

/**
* A render-prop slot: receives a context object (shape defined per view/slot)
* and returns the node to render. Lets a consumer override an internal element
* of a view while keeping the customisation on their side.
*
* @example
* interface ViewSlots {
* addButton?: Slot<{ onClick: () => void; disabled: boolean }>;
* }
*/
export type Slot<TContext> = (context: TContext) => React.ReactNode;

export interface FrontierClientBillingOptions {
supportEmail?: string;
successUrl?: string;
Expand Down
Loading