Skip to content

Commit

Permalink
Merge pull request #3207 from tokens-studio/update-sdk-to-v2
Browse files Browse the repository at this point in the history
Update sdk to v2
  • Loading branch information
roppazvan authored Dec 18, 2024
2 parents 41f7e34 + 9a748e3 commit da1786c
Show file tree
Hide file tree
Showing 48 changed files with 1,700 additions and 2,196 deletions.
5 changes: 5 additions & 0 deletions .changeset/quick-years-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/figma-plugin": minor
---

Improved Tokens Studio Sync provider creation and updated Tokens Studio SDK to the latest version
14 changes: 6 additions & 8 deletions packages/tokens-studio-for-figma/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,7 @@ export default {
// coverageProvider: "babel",

// A list of reporter names that Jest uses when writing coverage reports
coverageReporters: [
'json',
'text',
'lcov',
'clover',
],
coverageReporters: ['json', 'text', 'lcov', 'clover'],

// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
Expand Down Expand Up @@ -81,7 +76,7 @@ export default {
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/tests/__mocks__/fileMock.js',
'<rootDir>/tests/__mocks__/fileMock.js',
'\\.(css)$': '<rootDir>/tests/__mocks__/styleMock.js',
'^@/(.*)$': '<rootDir>/src/$1',
'^@/types/(.*)$': '<rootDir>/src/types/$1',
Expand Down Expand Up @@ -185,7 +180,10 @@ export default {
// "^.+\\.js$": "babel-jest",
// },
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
transformIgnorePatterns: ['/node_modules/(?!(@figma-plugin|react-dnd|@react-dnd|react-colorful|dnd-core|react-dnd-html5-backend|culori|dot-prop)/)', '\\.pnp\\.[^\\/]+$'],
transformIgnorePatterns: [
'/node_modules/(?!(@figma-plugin|react-dnd|@react-dnd|react-colorful|dnd-core|react-dnd-html5-backend|culori|dot-prop|@tokens-studio/sdk|@apollo/client)/)',
'\\.pnp\\.[^\\/]+$',
],

// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
Expand Down
5 changes: 3 additions & 2 deletions packages/tokens-studio-for-figma/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"build-storybook": "build-storybook"
},
"dependencies": {
"@apollo/client": "^3.12.2",
"@figma-plugin/helpers": "^0.15.2",
"@gitbeaker/rest": "^39.21.2",
"@monaco-editor/react": "^4.5.1",
Expand All @@ -61,7 +62,7 @@
"@supabase/supabase-js": "^2.0.5",
"@supernovaio/supernova-sdk": "^1.9.3",
"@tokens-studio/graph-engine": "^0.17.5",
"@tokens-studio/sdk": "^1.2.1",
"@tokens-studio/sdk": "^2.0.0-alpha.0",
"@tokens-studio/tokens": "0.2.5",
"@tokens-studio/types": "0.5.1",
"@tokens-studio/ui": "0.9.0",
Expand All @@ -81,8 +82,8 @@
"color2k": "^2.0.1",
"colorjs.io": "^0.4.3",
"copy-to-clipboard": "^3.3.3",
"dnd-core": "^12.0.1",
"deepmerge-ts": "^5.1.0",
"dnd-core": "^12.0.1",
"dot-object": "^2.1.3",
"downshift": "^6.1.7",
"eventemitter3": "^4.0.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const ManageThemesModal: React.FC<React.PropsWithChildren<React.PropsWith
const treeItems = themeListToTree(themes);
const { t } = useTranslation(['tokens']);

const themeEditorDefaultValues = useMemo(() => {
const themeEditorDefaultValues: Partial<ThemeObject> = useMemo(() => {
const themeObject = themes.find(({ id }) => id === themeEditorOpen);
if (themeObject) {
return {
Expand Down Expand Up @@ -94,7 +94,7 @@ export const ManageThemesModal: React.FC<React.PropsWithChildren<React.PropsWith
setThemeEditorOpen(false);
}
}
}, [confirm, dispatch.tokenState, themeEditorOpen]);
}, [confirm, dispatch.tokenState, t, themeEditorOpen]);

const handleCancelEdit = useCallback(() => {
setThemeEditorOpen(false);
Expand All @@ -112,9 +112,13 @@ export const ManageThemesModal: React.FC<React.PropsWithChildren<React.PropsWith
name: values.name,
selectedTokenSets: values.tokenSets,
...(values?.group ? { group: values.group } : {}),
meta: {
oldName: themeEditorDefaultValues?.name,
oldGroup: themeEditorDefaultValues?.group,
},
});
setThemeEditorOpen(false);
}, [themeEditorOpen, dispatch]);
}, [themeEditorOpen, dispatch.tokenState, themeEditorDefaultValues]);

const handleReorder = React.useCallback((reorderedItems: TreeItem[]) => {
let currentGroup = '';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import React from 'react';
import React, { useEffect } from 'react';
import zod from 'zod';
import {
Box, Button, FormField, Heading, IconButton, Label, Link, Stack, Text, TextInput,
Box,
Button,
FormField,
Heading,
IconButton,
Label,
Link,
Select,
Stack,
Text,
TextInput,
} from '@tokens-studio/ui';
import { EyeClosedIcon, EyeOpenIcon } from '@radix-ui/react-icons';
import { useTranslation } from 'react-i18next';
import { create, Organization } from '@tokens-studio/sdk';
import { StorageProviderType } from '@/constants/StorageProviderType';
import { StorageTypeFormValues } from '@/types/StorageType';
import { generateId } from '@/utils/generateId';
import { ChangeEventHandler } from './types';
import { ErrorMessage } from '../ErrorMessage';
import TokensStudioWord from '@/icons/tokensstudio-word.svg';
import { styled } from '@/stitches.config';
import { GET_ORGS_QUERY } from '@/storage/tokensStudio/graphql';

const StyledTokensStudioWord = styled(TokensStudioWord, {
width: '200px',
Expand All @@ -32,6 +44,8 @@ export default function TokensStudioForm({
onChange, onSubmit, onCancel, values, hasErrored, errorMessage,
}: Props) {
const { t } = useTranslation(['storage']);
const [fetchOrgsError, setFetchOrgsError] = React.useState<string | null>(null);
const [orgData, setOrgData] = React.useState<Organization[]>([]);
const syncGuideUrl = 'tokens-studio';
const [isMasked, setIsMasked] = React.useState(true);
const [showTeaser, setShowTeaser] = React.useState(true);
Expand All @@ -50,6 +64,7 @@ export default function TokensStudioForm({
id: zod.string(),
secret: zod.string(),
internalId: zod.string().optional(),
orgId: zod.string(),
});
const validationResult = zodSchema.safeParse(values);
if (validationResult.success) {
Expand All @@ -73,13 +88,79 @@ export default function TokensStudioForm({
setShowTeaser(false);
}, []);

const fetchOrgData = React.useCallback(async () => {
try {
const client = create({
host: process.env.TOKENS_STUDIO_API_HOST || 'localhost:4200',
secure: process.env.NODE_ENV !== 'development',
auth: `Bearer ${values.secret}`,
});
const result = await client.query({
query: GET_ORGS_QUERY,
});
if (result.data?.organizations) {
setOrgData(result.data.organizations.data as Organization[]);
}
} catch (error) {
setFetchOrgsError('Error fetching organization data. Please check your Studio API key.');
}
}, [values.secret]);

useEffect(() => {
if (values.secret) {
fetchOrgData();
}
}, [values.secret, fetchOrgData]);

const orgOptions = React.useMemo(
() => orgData?.map((org) => ({
label: org.name,
value: org.id,
})),
[orgData],
);

const onOrgChange = React.useCallback(
(value: string) => {
onChange({ target: { name: 'orgId', value } });
},
[onChange],
);

const projectOptions = React.useMemo(() => {
if (!orgData) return [];
const selectedOrgData = orgData.find((org) => org.id === values.orgId);
if (!selectedOrgData) return [];
return selectedOrgData.projects.data.map((project) => ({
label: project.name,
value: project.id,
}));
}, [orgData, values.orgId]);

const selectedOrg = orgOptions?.find((org) => org.value === values.orgId);

const selectedProject = projectOptions?.find((project) => project.value === values.id);

const onProjectChange = React.useCallback(
(value: string) => {
onChange({ target: { name: 'id', value } });
},
[onChange],
);

return showTeaser ? (
<Stack direction="column" align="start" gap={5}>
<StyledTokensStudioWord />
<Stack direction="column" gap={3}>
<Heading size="large">A dedicated design tokens management platform</Heading>
<Box>We are working a dedicated design tokens management platform built on our powerful node-based graph engine including plug and play token transformation - suitable for enterprises! Still in early access, sign up for the waitlist!</Box>
<Link href="https://tokens.studio/studio" target="_blank" rel="noreferrer">Learn more</Link>
<Box>
We are working a dedicated design tokens management platform built on our powerful node-based graph engine
including plug and play token transformation - suitable for enterprises! Still in early access, sign up for
the waitlist!
</Box>
<Link href="https://tokens.studio/studio" target="_blank" rel="noreferrer">
Learn more
</Link>
</Stack>
<Button onClick={handleDismissTeaser}>Already got access?</Button>
</Stack>
Expand Down Expand Up @@ -119,6 +200,7 @@ export default function TokensStudioForm({
onChange={onChange}
name="secret"
id="secret"
onBlur={fetchOrgData}
required
type={isMasked ? 'password' : 'text'}
trailingAction={(
Expand All @@ -130,11 +212,43 @@ export default function TokensStudioForm({
/>
)}
/>
{fetchOrgsError && <Text muted>{fetchOrgsError}</Text>}
</FormField>
<FormField>
<Label htmlFor="id">{t('providers.tokensstudio.id')}</Label>
<TextInput value={values.id || ''} onChange={onChange} type="text" name="id" id="id" required />
</FormField>
{orgOptions?.length > 0 && (
<Stack direction="column" gap={2}>
<Label htmlFor="org">{t('providers.tokensstudio.selectOrgLabel')}</Label>
<div>
<Select value={values.orgId ?? ''} onValueChange={onOrgChange} name="org">
<Select.Trigger value={selectedOrg?.label || 'Choose an organization'} />
<Select.Content>
{orgOptions?.map((option) => (
<Select.Item key={option.value} value={option.value}>
{option.label}
</Select.Item>
))}
</Select.Content>
</Select>
</div>
</Stack>
)}

{projectOptions?.length > 0 && (
<Stack direction="column" gap={2}>
<Label htmlFor="org">{t('providers.tokensstudio.selectProjectLabel')}</Label>
<div>
<Select value={values.id ?? ''} onValueChange={onProjectChange} name="id">
<Select.Trigger value={selectedProject?.label || 'Choose a project'} />
<Select.Content>
{projectOptions?.map((option) => (
<Select.Item key={option.value} value={option.value}>
{option.label}
</Select.Item>
))}
</Select.Content>
</Select>
</div>
</Stack>
)}
<Stack direction="row" justify="end" gap={4}>
<Button variant="secondary" onClick={onCancel}>
{t('cancel')}
Expand Down
Loading

0 comments on commit da1786c

Please sign in to comment.