Информация об изменениях

Сообщение Re[5]: Насколько ии повлиял на сферу? от 27.09.2025 10:07

Изменено 27.09.2025 10:16 bnk

Re[5]: Насколько ии повлиял на сферу?
Здравствуйте, Артём, Вы писали:

Аё>Зачем 500 строк кода форме на 5 кнопок? Ты увеиен, что это вот 500 строк AI slop — это хорошо и поддерживаемо?


Ну на форме там 300, меньше вряд ли получится. 500 это в коммите всего. Вот, полный текст для формы. Как по мне так норм, я бы сам примерно так же написал. Он же по образу и подобию того что есть в проекте работает

  здесь
import React from 'react';
import {
  Dialog,
  DialogType,
  IDialogContentProps,
  DialogFooter,
  PrimaryButton,
  DefaultButton,
  Stack,
  Text,
  Icon,
  Spinner,
  SpinnerSize,
  MessageBar,
  MessageBarType,
  Separator
} from '@fluentui/react';
import { AuthService } from 'services/AuthService';
import { TokenKind } from 'shared/TokenKind';
import { TextService } from 'services/TextService';
import strings from 'VistoWebPartStrings';
import { useTheme } from '@fluentui/react';
import { trackClient } from 'services/trackClient';

export interface IConsentDialogProps {
  onDismiss: () => void;
}

interface IConsentItem {
  key: string;
  name: string;
  description: string;
  tokenKind: TokenKind;
  domain?: string;
  isGranted: boolean;
  isChecking: boolean;
  error?: string;
}

export const ConsentDialog: React.FC<IConsentDialogProps> = (props) => {
  const theme = useTheme();
  const [consentItems, setConsentItems] = React.useState<IConsentItem[]>([
    {
      key: 'default',
      name: TextService.format(strings.ConsentDialog_Default),
      description: TextService.format(strings.ConsentDialog_DefaultDescription),
      tokenKind: TokenKind.dashboard,
      domain: 'graph.microsoft.com',
      isGranted: false,
      isChecking: false
    },
    {
      key: 'sharepoint',
      name: TextService.format(strings.ConsentDialog_SharePoint),
      description: TextService.format(strings.ConsentDialog_SharePointDescription),
      tokenKind: TokenKind.sharepoint,
      isGranted: false,
      isChecking: false
    },
    {
      key: 'devops',
      name: TextService.format(strings.ConsentDialog_DevOps),
      description: TextService.format(strings.ConsentDialog_DevOpsDescription),
      tokenKind: TokenKind.devops,
      domain: 'dev.azure.com',
      isGranted: false,
      isChecking: false
    },
    {
      key: 'planner',
      name: TextService.format(strings.ConsentDialog_Planner),
      description: TextService.format(strings.ConsentDialog_PlannerDescription),
      tokenKind: TokenKind.planner,
      domain: 'graph.microsoft.com',
      isGranted: false,
      isChecking: false
    },
    {
      key: 'excel',
      name: TextService.format(strings.ConsentDialog_Excel),
      description: TextService.format(strings.ConsentDialog_ExcelDescription),
      tokenKind: TokenKind.excel,
      domain: 'graph.microsoft.com',
      isGranted: false,
      isChecking: false
    }
  ]);

  const [isInitializing, setIsInitializing] = React.useState(true);

  const formatErrorMessage = (error: any, item: IConsentItem): string => {
    const errorMessage = error?.message || error?.toString() || 'Unknown error';
    
    // Special handling for DevOps AADSTS650052 error
    if (item.key === 'devops' && errorMessage.includes('AADSTS650052')) {
      return "DevOps may not be available for your organization or user account. This is a common reason for this error.";
    }
    
    return errorMessage;
  };

  const checkConsentStatus = async (item: IConsentItem): Promise<boolean> => {
    try {
      // Try to get a token - if it succeeds, consent is granted
      const domain = item.domain || 'graph.microsoft.com';
      await AuthService.getAuthToken(item.tokenKind, domain);
      return true;
    } catch (error) {
      // If we get a consent error, consent is not granted
      trackClient.warn(`Consent check failed for ${TokenKind[item.tokenKind]}`, error);
      return false;
    }
  };

  const updateConsentItem = (key: string, updates: Partial<IConsentItem>) => {
    setConsentItems(prev => prev.map(item =>
      item.key === key ? { ...item, ...updates } : item
    ));
  };

  const checkAllConsents = async () => {
    setIsInitializing(true);

    const checkPromises = consentItems.map(async (item) => {
      updateConsentItem(item.key, { isChecking: true, error: undefined });

      try {
        const isGranted = await checkConsentStatus(item);
        updateConsentItem(item.key, {
          isGranted,
          isChecking: false,
          error: undefined
        });
      } catch (error) {
        updateConsentItem(item.key, {
          isGranted: false,
          isChecking: false,
          error: formatErrorMessage(error, item)
        });
      }
    });

    await Promise.all(checkPromises);
    setIsInitializing(false);
  };

  React.useEffect(() => {
    checkAllConsents();
  }, []);

  const requestConsent = async (item: IConsentItem) => {
    if (!AuthService.getConsent) {
      trackClient.error('getConsent provider not available');
      return;
    }

    updateConsentItem(item.key, { isChecking: true, error: undefined });

    try {
      const domain = item.domain || 'graph.microsoft.com';
      await AuthService.getConsent(item.tokenKind, async () => {
        // Test callback to verify consent was granted
        await AuthService.getAuthToken(item.tokenKind, domain);
      }, domain);

      // If we get here, consent was granted
      updateConsentItem(item.key, {
        isGranted: true,
        isChecking: false,
        error: undefined
      });
    } catch (error) {
      updateConsentItem(item.key, {
        isGranted: false,
        isChecking: false,
        error: formatErrorMessage(error, item)
      });
    }
  };

  const getStatusIcon = (item: IConsentItem) => {
    if (item.isChecking) {
      return <Spinner size={SpinnerSize.small} />;
    }

    if (item.isGranted) {
      return <Icon iconName="CheckMark" style={{ color: theme.palette.green }} />;
    }

    return <Icon iconName="ErrorBadge" style={{ color: theme.palette.red }} />;
  };

  const contentProps: IDialogContentProps = {
    type: DialogType.largeHeader,
    title: TextService.format(strings.ConsentDialog_Title),
    subText: TextService.format(strings.ConsentDialog_Description)
  };

  const grantedCount = consentItems.filter(item => item.isGranted).length;
  const totalCount = consentItems.length;

  return (
    <Dialog
      minWidth={400}
      maxWidth={600}
      isBlocking={false}
      dialogContentProps={contentProps}
      isOpen={true}
      onDismiss={props.onDismiss}
    >
      <Stack tokens={{ childrenGap: 'l1' }} styles={{ root: { paddingBottom: '32px' } }}>
        {isInitializing && (
          <MessageBar messageBarType={MessageBarType.info}>
            <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 's1' }}>
              <Spinner size={SpinnerSize.small} />
              <Text>{TextService.format(strings.ConsentDialog_CheckingAll)}</Text>
            </Stack>
          </MessageBar>
        )}

        {!isInitializing && (
          <MessageBar
            messageBarType={grantedCount === totalCount ? MessageBarType.success : MessageBarType.warning}
          >
            <Text>
              {TextService.format(strings.ConsentDialog_Status, {
                granted: grantedCount.toString(),
                total: totalCount.toString()
              })}
            </Text>
          </MessageBar>
        )}

        <Stack tokens={{ childrenGap: 's1' }}>
          {consentItems.map((item, index) => (
            <div key={item.key}>
              <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 'm' }}>
                <div style={{ width: 20, flexShrink: 0 }}>
                  {getStatusIcon(item)}
                </div>

                <Stack grow tokens={{ childrenGap: 'xs' }}>
                  <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 's2' }}>
                    <Text variant="medium" style={{ fontWeight: 600 }}>
                      {item.name}
                    </Text>
                    {(!item.isGranted && !item.isChecking) && (
                      <Text variant="small" style={{
                        color: theme.palette.orange,
                        backgroundColor: theme.palette.neutralLighter,
                        padding: '2px 6px',
                        borderRadius: '2px',
                        fontSize: '11px',
                        fontWeight: 600
                      }}>
                        {TextService.format(strings.ConsentDialog_NotGranted)}
                      </Text>
                    )}
                  </Stack>

                  <Text variant="small" style={{ color: theme.palette.neutralPrimary }}>
                    {item.description}
                  </Text>

                  {item.error && (
                    <Text variant="small" style={{
                      color: theme.palette.red,
                      wordBreak: 'break-word',
                      maxWidth: '100%'
                    }}>
                      {TextService.format(strings.ConsentDialog_Error)}: {item.error}
                    </Text>
                  )}
                </Stack>

                <Stack horizontal verticalAlign="center" style={{ minWidth: 140, justifyContent: 'flex-end' }}>
                  {item.isGranted ? (
                    <DefaultButton
                      disabled={true}
                      text={TextService.format(strings.ConsentDialog_Granted)}
                      iconProps={{ iconName: 'CheckMark' }}
                      styles={{
                        root: {
                          backgroundColor: theme.palette.neutralLighter,
                          borderColor: theme.palette.neutralLight,
                          color: theme.palette.neutralSecondary
                        },
                        icon: { color: theme.palette.green }
                      }}
                    />
                  ) : item.isChecking ? (
                    <DefaultButton
                      disabled={true}
                      text={TextService.format(strings.ConsentDialog_Checking)}
                      onRenderIcon={() => <Spinner size={SpinnerSize.xSmall} />}
                      styles={{
                        root: {
                          backgroundColor: theme.palette.neutralLighter,
                          borderColor: theme.palette.neutralLight,
                          color: theme.palette.neutralSecondary
                        }
                      }}
                    />
                  ) : (
                    <PrimaryButton
                      text={TextService.format(strings.ConsentDialog_GrantConsent)}
                      onClick={() => requestConsent(item)}
                    />
                  )}
                </Stack>
              </Stack>
              {index < consentItems.length - 1 && <Separator styles={{ root: { margin: '4px 0' } }} />}
            </div>
          ))}
        </Stack>
      </Stack>

      <DialogFooter styles={{ actions: { display: 'flex', flexGrow: 1 }, actionsRight: { flexGrow: 1, justifyContent: 'space-between' } }}>
        <DefaultButton
          text={TextService.format(strings.ConsentDialog_RefreshAll)}
          onClick={checkAllConsents}
          disabled={isInitializing}
          iconProps={{ iconName: 'Refresh' }}
        />
        <DefaultButton onClick={props.onDismiss} text={TextService.format(strings.ConsentDialog_Close)} />
      </DialogFooter>
    </Dialog>
  );
};
Re[5]: Насколько ии повлиял на сферу?
Здравствуйте, Артём, Вы писали:

Аё>Зачем 500 строк кода форме на 5 кнопок? Ты увеиен, что это вот 500 строк AI slop — это хорошо и поддерживаемо?


Ну на форме там 300, меньше вряд ли получится. 500 это в коммите всего. Вот, полный текст для формы.
Как по мне так норм, я бы сам примерно так же написал. Он же по образу и подобию того что есть в проекте работает

  здесь
import React from 'react';
import {
  Dialog,
  DialogType,
  IDialogContentProps,
  DialogFooter,
  PrimaryButton,
  DefaultButton,
  Stack,
  Text,
  Icon,
  Spinner,
  SpinnerSize,
  MessageBar,
  MessageBarType,
  Separator
} from '@fluentui/react';
import { AuthService } from 'services/AuthService';
import { TokenKind } from 'shared/TokenKind';
import { TextService } from 'services/TextService';
import strings from 'VistoWebPartStrings';
import { useTheme } from '@fluentui/react';
import { trackClient } from 'services/trackClient';

export interface IConsentDialogProps {
  onDismiss: () => void;
}

interface IConsentItem {
  key: string;
  name: string;
  description: string;
  tokenKind: TokenKind;
  domain?: string;
  isGranted: boolean;
  isChecking: boolean;
  error?: string;
}

export const ConsentDialog: React.FC<IConsentDialogProps> = (props) => {
  const theme = useTheme();
  const [consentItems, setConsentItems] = React.useState<IConsentItem[]>([
    {
      key: 'default',
      name: TextService.format(strings.ConsentDialog_Default),
      description: TextService.format(strings.ConsentDialog_DefaultDescription),
      tokenKind: TokenKind.dashboard,
      domain: 'graph.microsoft.com',
      isGranted: false,
      isChecking: false
    },
    {
      key: 'sharepoint',
      name: TextService.format(strings.ConsentDialog_SharePoint),
      description: TextService.format(strings.ConsentDialog_SharePointDescription),
      tokenKind: TokenKind.sharepoint,
      isGranted: false,
      isChecking: false
    },
    {
      key: 'devops',
      name: TextService.format(strings.ConsentDialog_DevOps),
      description: TextService.format(strings.ConsentDialog_DevOpsDescription),
      tokenKind: TokenKind.devops,
      domain: 'dev.azure.com',
      isGranted: false,
      isChecking: false
    },
    {
      key: 'planner',
      name: TextService.format(strings.ConsentDialog_Planner),
      description: TextService.format(strings.ConsentDialog_PlannerDescription),
      tokenKind: TokenKind.planner,
      domain: 'graph.microsoft.com',
      isGranted: false,
      isChecking: false
    },
    {
      key: 'excel',
      name: TextService.format(strings.ConsentDialog_Excel),
      description: TextService.format(strings.ConsentDialog_ExcelDescription),
      tokenKind: TokenKind.excel,
      domain: 'graph.microsoft.com',
      isGranted: false,
      isChecking: false
    }
  ]);

  const [isInitializing, setIsInitializing] = React.useState(true);

  const formatErrorMessage = (error: any, item: IConsentItem): string => {
    const errorMessage = error?.message || error?.toString() || 'Unknown error';
    
    // Special handling for DevOps AADSTS650052 error
    if (item.key === 'devops' && errorMessage.includes('AADSTS650052')) {
      return "DevOps may not be available for your organization or user account. This is a common reason for this error.";
    }
    
    return errorMessage;
  };

  const checkConsentStatus = async (item: IConsentItem): Promise<boolean> => {
    try {
      // Try to get a token - if it succeeds, consent is granted
      const domain = item.domain || 'graph.microsoft.com';
      await AuthService.getAuthToken(item.tokenKind, domain);
      return true;
    } catch (error) {
      // If we get a consent error, consent is not granted
      trackClient.warn(`Consent check failed for ${TokenKind[item.tokenKind]}`, error);
      return false;
    }
  };

  const updateConsentItem = (key: string, updates: Partial<IConsentItem>) => {
    setConsentItems(prev => prev.map(item =>
      item.key === key ? { ...item, ...updates } : item
    ));
  };

  const checkAllConsents = async () => {
    setIsInitializing(true);

    const checkPromises = consentItems.map(async (item) => {
      updateConsentItem(item.key, { isChecking: true, error: undefined });

      try {
        const isGranted = await checkConsentStatus(item);
        updateConsentItem(item.key, {
          isGranted,
          isChecking: false,
          error: undefined
        });
      } catch (error) {
        updateConsentItem(item.key, {
          isGranted: false,
          isChecking: false,
          error: formatErrorMessage(error, item)
        });
      }
    });

    await Promise.all(checkPromises);
    setIsInitializing(false);
  };

  React.useEffect(() => {
    checkAllConsents();
  }, []);

  const requestConsent = async (item: IConsentItem) => {
    if (!AuthService.getConsent) {
      trackClient.error('getConsent provider not available');
      return;
    }

    updateConsentItem(item.key, { isChecking: true, error: undefined });

    try {
      const domain = item.domain || 'graph.microsoft.com';
      await AuthService.getConsent(item.tokenKind, async () => {
        // Test callback to verify consent was granted
        await AuthService.getAuthToken(item.tokenKind, domain);
      }, domain);

      // If we get here, consent was granted
      updateConsentItem(item.key, {
        isGranted: true,
        isChecking: false,
        error: undefined
      });
    } catch (error) {
      updateConsentItem(item.key, {
        isGranted: false,
        isChecking: false,
        error: formatErrorMessage(error, item)
      });
    }
  };

  const getStatusIcon = (item: IConsentItem) => {
    if (item.isChecking) {
      return <Spinner size={SpinnerSize.small} />;
    }

    if (item.isGranted) {
      return <Icon iconName="CheckMark" style={{ color: theme.palette.green }} />;
    }

    return <Icon iconName="ErrorBadge" style={{ color: theme.palette.red }} />;
  };

  const contentProps: IDialogContentProps = {
    type: DialogType.largeHeader,
    title: TextService.format(strings.ConsentDialog_Title),
    subText: TextService.format(strings.ConsentDialog_Description)
  };

  const grantedCount = consentItems.filter(item => item.isGranted).length;
  const totalCount = consentItems.length;

  return (
    <Dialog
      minWidth={400}
      maxWidth={600}
      isBlocking={false}
      dialogContentProps={contentProps}
      isOpen={true}
      onDismiss={props.onDismiss}
    >
      <Stack tokens={{ childrenGap: 'l1' }} styles={{ root: { paddingBottom: '32px' } }}>
        {isInitializing && (
          <MessageBar messageBarType={MessageBarType.info}>
            <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 's1' }}>
              <Spinner size={SpinnerSize.small} />
              <Text>{TextService.format(strings.ConsentDialog_CheckingAll)}</Text>
            </Stack>
          </MessageBar>
        )}

        {!isInitializing && (
          <MessageBar
            messageBarType={grantedCount === totalCount ? MessageBarType.success : MessageBarType.warning}
          >
            <Text>
              {TextService.format(strings.ConsentDialog_Status, {
                granted: grantedCount.toString(),
                total: totalCount.toString()
              })}
            </Text>
          </MessageBar>
        )}

        <Stack tokens={{ childrenGap: 's1' }}>
          {consentItems.map((item, index) => (
            <div key={item.key}>
              <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 'm' }}>
                <div style={{ width: 20, flexShrink: 0 }}>
                  {getStatusIcon(item)}
                </div>

                <Stack grow tokens={{ childrenGap: 'xs' }}>
                  <Stack horizontal verticalAlign="center" tokens={{ childrenGap: 's2' }}>
                    <Text variant="medium" style={{ fontWeight: 600 }}>
                      {item.name}
                    </Text>
                    {(!item.isGranted && !item.isChecking) && (
                      <Text variant="small" style={{
                        color: theme.palette.orange,
                        backgroundColor: theme.palette.neutralLighter,
                        padding: '2px 6px',
                        borderRadius: '2px',
                        fontSize: '11px',
                        fontWeight: 600
                      }}>
                        {TextService.format(strings.ConsentDialog_NotGranted)}
                      </Text>
                    )}
                  </Stack>

                  <Text variant="small" style={{ color: theme.palette.neutralPrimary }}>
                    {item.description}
                  </Text>

                  {item.error && (
                    <Text variant="small" style={{
                      color: theme.palette.red,
                      wordBreak: 'break-word',
                      maxWidth: '100%'
                    }}>
                      {TextService.format(strings.ConsentDialog_Error)}: {item.error}
                    </Text>
                  )}
                </Stack>

                <Stack horizontal verticalAlign="center" style={{ minWidth: 140, justifyContent: 'flex-end' }}>
                  {item.isGranted ? (
                    <DefaultButton
                      disabled={true}
                      text={TextService.format(strings.ConsentDialog_Granted)}
                      iconProps={{ iconName: 'CheckMark' }}
                      styles={{
                        root: {
                          backgroundColor: theme.palette.neutralLighter,
                          borderColor: theme.palette.neutralLight,
                          color: theme.palette.neutralSecondary
                        },
                        icon: { color: theme.palette.green }
                      }}
                    />
                  ) : item.isChecking ? (
                    <DefaultButton
                      disabled={true}
                      text={TextService.format(strings.ConsentDialog_Checking)}
                      onRenderIcon={() => <Spinner size={SpinnerSize.xSmall} />}
                      styles={{
                        root: {
                          backgroundColor: theme.palette.neutralLighter,
                          borderColor: theme.palette.neutralLight,
                          color: theme.palette.neutralSecondary
                        }
                      }}
                    />
                  ) : (
                    <PrimaryButton
                      text={TextService.format(strings.ConsentDialog_GrantConsent)}
                      onClick={() => requestConsent(item)}
                    />
                  )}
                </Stack>
              </Stack>
              {index < consentItems.length - 1 && <Separator styles={{ root: { margin: '4px 0' } }} />}
            </div>
          ))}
        </Stack>
      </Stack>

      <DialogFooter styles={{ actions: { display: 'flex', flexGrow: 1 }, actionsRight: { flexGrow: 1, justifyContent: 'space-between' } }}>
        <DefaultButton
          text={TextService.format(strings.ConsentDialog_RefreshAll)}
          onClick={checkAllConsents}
          disabled={isInitializing}
          iconProps={{ iconName: 'Refresh' }}
        />
        <DefaultButton onClick={props.onDismiss} text={TextService.format(strings.ConsentDialog_Close)} />
      </DialogFooter>
    </Dialog>
  );
};