You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BitbucketCloudSearchForm.tsx 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { FlagMessage, InputSearch, LightPrimary, Link } from 'design-system';
  21. import * as React from 'react';
  22. import { FormattedMessage } from 'react-intl';
  23. import ListFooter from '../../../../components/controls/ListFooter';
  24. import { translate } from '../../../../helpers/l10n';
  25. import { getBaseUrl } from '../../../../helpers/system';
  26. import { queryToSearch } from '../../../../helpers/urls';
  27. import { BitbucketCloudRepository } from '../../../../types/alm-integration';
  28. import AlmRepoItem from '../components/AlmRepoItem';
  29. import { REPOSITORY_PAGE_SIZE } from '../constants';
  30. import { CreateProjectModes } from '../types';
  31. export interface BitbucketCloudSearchFormProps {
  32. isLastPage: boolean;
  33. loadingMore: boolean;
  34. onImport: (repositorySlug: string) => void;
  35. onLoadMore: () => void;
  36. onSearch: (searchQuery: string) => void;
  37. repositories?: BitbucketCloudRepository[];
  38. searching: boolean;
  39. searchQuery: string;
  40. }
  41. function getRepositoryUrl(workspace: string, slug: string) {
  42. return `https://bitbucket.org/${workspace}/${slug}`;
  43. }
  44. export default function BitbucketCloudSearchForm(props: BitbucketCloudSearchFormProps) {
  45. const { isLastPage, loadingMore, repositories = [], searching, searchQuery } = props;
  46. if (repositories.length === 0 && searchQuery.length === 0 && !searching) {
  47. return (
  48. <FlagMessage className="sw-mt-2" variant="warning">
  49. <span>
  50. <FormattedMessage
  51. defaultMessage={translate('onboarding.create_project.bitbucketcloud.no_projects')}
  52. id="onboarding.create_project.bitbucketcloud.no_projects"
  53. values={{
  54. link: (
  55. <Link
  56. to={{
  57. pathname: '/projects/create',
  58. search: queryToSearch({ mode: CreateProjectModes.BitbucketCloud, resetPat: 1 }),
  59. }}
  60. >
  61. {translate('onboarding.create_project.update_your_token')}
  62. </Link>
  63. ),
  64. }}
  65. />
  66. </span>
  67. </FlagMessage>
  68. );
  69. }
  70. return (
  71. <div>
  72. <div className="sw-flex sw-items-center sw-mb-6 sw-w-abs-400">
  73. <InputSearch
  74. loading={searching}
  75. minLength={3}
  76. onChange={props.onSearch}
  77. placeholder={translate('onboarding.create_project.search_prompt')}
  78. size="full"
  79. value={searchQuery}
  80. />
  81. </div>
  82. {repositories.length === 0 ? (
  83. <div className="sw-py-6 sw-px-2">
  84. <LightPrimary className="sw-body-sm">{translate('no_results')}</LightPrimary>
  85. </div>
  86. ) : (
  87. <ul className="sw-flex sw-flex-col sw-gap-3">
  88. {repositories.map((r) => (
  89. <AlmRepoItem
  90. key={r.uuid}
  91. almKey={r.slug}
  92. almUrl={getRepositoryUrl(r.workspace, r.slug)}
  93. almUrlText={translate('onboarding.create_project.bitbucketcloud.link')}
  94. almIconSrc={`${getBaseUrl()}/images/alm/bitbucket.svg`}
  95. sqProjectKey={r.sqProjectKey}
  96. onImport={props.onImport}
  97. primaryTextNode={<span title={r.name}>{r.name}</span>}
  98. secondaryTextNode={<span title={r.projectKey}>{r.projectKey}</span>}
  99. />
  100. ))}
  101. </ul>
  102. )}
  103. <ListFooter
  104. className="sw-mb-10"
  105. count={repositories.length}
  106. // we don't know the total, so only provide when we've reached the last page
  107. total={isLastPage ? repositories.length : undefined}
  108. pageSize={REPOSITORY_PAGE_SIZE}
  109. loadMore={props.onLoadMore}
  110. loading={loadingMore}
  111. />
  112. </div>
  113. );
  114. }