Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

356-github-sync-plugin-losing-access-tokens-sometimes #1373

Closed
Closed
Changes from 8 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
Original file line number Diff line number Diff line change
@@ -41,7 +41,6 @@ export function pullTokensFactory(
StorageProviderType.JSONBIN,
StorageProviderType.URL,
].includes(storageType.provider);

if (isRemoteStorage) {
const matchingSet = params.localApiProviders?.find((provider) => (
isSameCredentials(provider, storageType)
58 changes: 58 additions & 0 deletions src/app/components/BorderTokenDownShiftInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { ResolveTokenValuesResult } from '@/plugin/tokenHelpers';
import DownshiftInput from './DownshiftInput';
import { getLabelForProperty } from '@/utils/getLabelForProperty';

const mapTypeToPlaceHolder = {
color: 'Border color',
width: 'Border width',
style: 'solid | dashed',
};

export default function BorderTokenDownShiftInput({
name,
value,
type,
resolvedTokens,
handleChange,
setInputValue,
handleToggleInputHelper,
}: {
name: string,
value: string;
type: string;
resolvedTokens: ResolveTokenValuesResult[];
handleChange: React.ChangeEventHandler;
setInputValue: (newInputValue: string, property: string) => void;
handleToggleInputHelper?: () => void;
}) {
const onChange = React.useCallback((e: React.ChangeEvent<HTMLInputElement>) => handleChange(e), [handleChange]);
const handleBorderDownShiftInputChange = React.useCallback((newInputValue: string) => setInputValue(newInputValue, name), [name, setInputValue]);
const getIconComponent = React.useMemo(() => getLabelForProperty(name), [name]);
return (
<DownshiftInput
name={name}
value={value}
type={type}
label={getIconComponent}
inlineLabel
resolvedTokens={resolvedTokens}
handleChange={onChange}
setInputValue={handleBorderDownShiftInputChange}
placeholder={mapTypeToPlaceHolder[name as keyof typeof mapTypeToPlaceHolder]}
prefix={
name === 'color' && (
<button
type="button"
className="block w-4 h-4 rounded-sm cursor-pointer shadow-border shadow-gray-300 focus:shadow-focus focus:shadow-primary-400"
style={{ background: value ?? '#000000', fontSize: 0 }}
onClick={handleToggleInputHelper}
>
{value}
</button>
)
}
suffix
/>
);
}
64 changes: 64 additions & 0 deletions src/app/components/BorderTokenForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';
import { useUIDSeed } from 'react-uid';
import get from 'just-safe-get';
import { EditTokenObject } from '@/types/tokens';
import Heading from './Heading';
import { TokenTypes } from '@/constants/TokenTypes';
import { ResolveTokenValuesResult } from '@/plugin/tokenHelpers';
import Stack from './Stack';
import BorderTokenDownShiftInput from './BorderTokenDownShiftInput';
import ColorPicker from './ColorPicker';

const propertyTypes = {
color: TokenTypes.COLOR,
width: TokenTypes.BORDER_WIDTH,
style: 'strokeStyle',
};

export default function BorderTokenForm({
internalEditToken,
resolvedTokens,
handleBorderValueChange,
handleBorderValueDownShiftInputChange,
}: {
internalEditToken: Extract<EditTokenObject, { type: TokenTypes.BORDER }>;
resolvedTokens: ResolveTokenValuesResult[];
handleBorderValueChange: React.ChangeEventHandler;
handleBorderValueDownShiftInputChange: (newInputValue: string, property: string) => void;
}) {
const seed = useUIDSeed();
const [inputHelperOpen, setInputHelperOpen] = React.useState<boolean>(false);

const handleToggleInputHelper = React.useCallback(() => setInputHelperOpen(!inputHelperOpen), [inputHelperOpen]);
const onColorChange = React.useCallback((color: string) => {
handleBorderValueDownShiftInputChange(color, 'color');
}, [handleBorderValueChange]);

return (
<Stack direction="column" gap={2}>
<Stack direction="row" gap={2} justify="between" align="center">
<Heading>Value</Heading>
</Stack>
<Stack gap={2} direction="column">
{Object.entries(internalEditToken.schema.schemas.value.properties ?? {}).map(([key], keyIndex) => (
<>
<BorderTokenDownShiftInput
name={key}
key={`border-input-${seed(keyIndex)}`}
value={typeof internalEditToken.value === 'object' ? get(internalEditToken.value, key, '') : ''}
type={propertyTypes[key as keyof typeof propertyTypes]}
resolvedTokens={resolvedTokens}
handleChange={handleBorderValueChange}
setInputValue={handleBorderValueDownShiftInputChange}
handleToggleInputHelper={handleToggleInputHelper}
/>
{inputHelperOpen && key === 'color' && (
<ColorPicker value={typeof internalEditToken.value === 'object' && get(internalEditToken.value, key, '')} onChange={onColorChange} />
)}
</>
))}

</Stack>
</Stack>
);
}
36 changes: 36 additions & 0 deletions src/app/components/EditTokenForm.tsx
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ import { EditTokenFormStatus } from '@/constants/EditTokenFormStatus';
import { StyleOptions } from '@/constants/StyleOptions';
import Textarea from './Textarea';
import Heading from './Heading';
import BorderTokenForm from './BorderTokenForm';
import Box from './Box';

type Props = {
@@ -181,6 +182,31 @@ function EditTokenForm({ resolvedTokens }: Props) {
}
}, [internalEditToken]);

const handleBorderValueChange = React.useCallback<React.ChangeEventHandler<HTMLInputElement>>(
(e) => {
e.persist();
if (internalEditToken?.type === TokenTypes.BORDER && typeof internalEditToken?.value !== 'string') {
setInternalEditToken({
...internalEditToken,
value: {
...internalEditToken.value,
[e.target.name]: e.target.value,
},
});
}
},
[internalEditToken],
);

const handleBorderValueDownShiftInputChange = React.useCallback((newInputValue: string, property: string) => {
if (internalEditToken?.type === TokenTypes.BORDER && typeof internalEditToken?.value !== 'string') {
setInternalEditToken({
...internalEditToken,
value: { ...internalEditToken.value, [property]: newInputValue },
});
}
}, [internalEditToken]);

const handleDownShiftInputChange = React.useCallback((newInputValue: string) => {
setInternalEditToken({
...internalEditToken,
@@ -352,6 +378,16 @@ function EditTokenForm({ resolvedTokens }: Props) {
/>
);
}
case TokenTypes.BORDER: {
return (
<BorderTokenForm
internalEditToken={internalEditToken}
resolvedTokens={resolvedTokens}
handleBorderValueChange={handleBorderValueChange}
handleBorderValueDownShiftInputChange={handleBorderValueDownShiftInputChange}
/>
);
}
default: {
return (
<div>
18 changes: 17 additions & 1 deletion src/app/components/InspectorResolvedToken.tsx
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import { SingleToken } from '@/types/tokens';
import IconShadow from '@/icons/shadow.svg';
import IconComposition from '@/icons/composition.svg';
import { TokenTypes } from '@/constants/TokenTypes';
import { IconImage } from '@/icons';
import { IconBorder, IconImage } from '@/icons';

export default function InspectorResolvedToken({ token }: { token: SingleToken }) {
// TODO: Introduce shared component for token tooltips
@@ -107,6 +107,22 @@ export default function InspectorResolvedToken({ token }: { token: SingleToken }
);
}

case TokenTypes.BORDER: {
return (
<Box
css={{
background: '$bgSubtle',
fontSize: '$small',
padding: '$2 $3',
borderRadius: '$default',
width: '40px',
}}
>
<IconBorder />
</Box>
);
}

default: {
return (
<Box
20 changes: 12 additions & 8 deletions src/app/components/StorageItem.tsx
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ const StorageItem = ({ item, onEdit }: Props) => {
return shouldDelete;
}, [confirm]);

const isActive = React.useCallback(() => isSameCredentials(item, storageType), [item, storageType]);
const isActive = React.useCallback(() => isSameCredentials(item, storageType), [item, storageType, isSameCredentials]);

const handleDelete = React.useCallback(async () => {
if (await askUserIfDelete()) deleteProvider(item);
@@ -61,13 +61,17 @@ const StorageItem = ({ item, onEdit }: Props) => {
{' '}
{branch && ` (${branch})`}
</Box>
<button
type="button"
className="inline-flex text-left text-red-600 underline text-xxs"
onClick={handleDelete}
>
Delete local credentials
</button>
{
!isActive() && (
Copy link
Collaborator

@six7 six7 Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you revert this now that we know this didn't cause it? so the Delete button is visible when it's active even.

<button
type="button"
className="inline-flex text-left text-red-600 underline text-xxs"
onClick={handleDelete}
>
Delete local credentials
</button>
)
}
</Box>
<div className="flex items-center space-x-2 flex-nowrap">
{onEdit && (
17 changes: 17 additions & 0 deletions src/app/components/TokenTooltip/SingleBorderValueDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { TokenBorderValue } from '@/types/values';
import TooltipProperty from './TooltipProperty';
import Stack from '../Stack';

type Props = {
value: TokenBorderValue;
resolvedValue: TokenBorderValue;
};

export const SingleBorderValueDisplay: React.FC<Props> = ({ value, resolvedValue }) => (
<Stack direction="column" align="start" gap={1}>
<TooltipProperty label="Color" value={value.color} resolvedValue={resolvedValue?.color} />
<TooltipProperty label="Width" value={value.width} resolvedValue={resolvedValue?.width} />
<TooltipProperty label="Style" value={value.style} resolvedValue={resolvedValue?.style} />
</Stack>
);
16 changes: 15 additions & 1 deletion src/app/components/TokenTooltip/TokenTooltipContent.test.tsx
Original file line number Diff line number Diff line change
@@ -123,7 +123,6 @@ const tokens: SingleToken[] = [
},
description: 'regular typography token',
},

{
name: 'typography.headlines.default',
type: TokenTypes.TYPOGRAPHY,
@@ -217,6 +216,21 @@ const tokens: SingleToken[] = [
description: 'a broken reference',
failedToResolve: true,
},
{
name: 'border.regular',
type: TokenTypes.BORDER,
value: {
color: 'test-value-object-value',
width: '12px',
style: 'solid',
},
rawValue: {
color: 'test-value-object-value',
width: '12px',
style: 'solid',
},
description: 'border token',
},
];

const shadowTokens = [
18 changes: 15 additions & 3 deletions src/app/components/TokenTooltip/TokenTooltipContentValue.tsx
Original file line number Diff line number Diff line change
@@ -5,13 +5,16 @@ import useTokens from '../../store/useTokens';
import { SingleToken } from '@/types/tokens';
import { SingleShadowValueDisplay } from './SingleShadowValueDisplay';
import { TokensContext } from '@/context';
import { isSingleBoxShadowToken, isSingleTypographyToken, isSingleCompositionToken } from '@/utils/is';
import {
isSingleBoxShadowToken, isSingleTypographyToken, isSingleCompositionToken, isSingleBorderToken,
} from '@/utils/is';
import { SingleTypographyValueDisplay } from './SingleTypographyValueDisplay';
import { TokenBoxshadowValue, TokenTypographyValue } from '@/types/values';
import { TokenBorderValue, TokenBoxshadowValue, TokenTypographyValue } from '@/types/values';
import { SingleCompositionValueDisplay } from './SingleCompositionValueDisplay';
import TooltipProperty from './TooltipProperty';
import Stack from '../Stack';
import { CompositionTokenValue } from '@/types/CompositionTokenProperty';
import { SingleBorderValueDisplay } from './SingleBorderValueDisplay';

type Props = {
token: SingleToken;
@@ -86,14 +89,23 @@ export const TokenTooltipContentValue: React.FC<Props> = ({ token }) => {
/>
) : null}
<SingleShadowValueDisplay
// @TODO strengthen type checking here
// @TODO strengthen type checking here
value={token.value as TokenBoxshadowValue}
resolvedValue={resolvedValue as TokenBoxshadowValue}
/>
</div>
);
}

if (isSingleBorderToken(token)) {
return (
<SingleBorderValueDisplay
value={token.value as TokenBorderValue}
resolvedValue={resolvedValue as TokenBorderValue}
/>
);
}

if (typeof token.value !== 'string' && typeof token.value !== 'number') {
return <TooltipProperty value={JSON.stringify(token.value, null, 2)} />;
}
4 changes: 4 additions & 0 deletions src/app/components/createTokenObj.test.tsx
Original file line number Diff line number Diff line change
@@ -170,6 +170,10 @@ describe('createTokenObj', () => {
input: 'composition',
output: 'composition',
},
{
input: 'border',
output: 'border',
},
{
input: 'asset',
output: 'asset',
2 changes: 2 additions & 0 deletions src/app/components/createTokenObj.tsx
Original file line number Diff line number Diff line change
@@ -43,6 +43,8 @@ export function transformName(name: string): TokenTypes {
return TokenTypes.PARAGRAPH_SPACING;
case 'composition':
return TokenTypes.COMPOSITION;
case 'border':
return TokenTypes.BORDER;
case 'asset':
return TokenTypes.ASSET;
default:
2 changes: 1 addition & 1 deletion src/app/hooks/usePropertiesForType.test.ts
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ describe('usePropertiesForTokenType', () => {
},
{
label: 'Border',
name: Properties.border,
name: Properties.borderColor,
},
],
},
2 changes: 1 addition & 1 deletion src/app/hooks/usePropertiesForType.ts
Original file line number Diff line number Diff line change
@@ -115,7 +115,7 @@ export function usePropertiesForTokenType(type: TokenTypes, value?: SingleToken[
},
{
label: 'Border',
name: Properties.border,
name: Properties.borderColor,
},
);
break;
2 changes: 1 addition & 1 deletion src/app/hooks/useTypeForProperty.test.ts
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ describe('useTypeForProperty', () => {
output: 'fill',
},
{
input: 'border',
input: 'borderColor',
output: 'fill',
},
{
Loading