mcp-market.module.scss 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. @import "../styles/animation.scss";
  2. .mcp-market-page {
  3. height: 100%;
  4. display: flex;
  5. flex-direction: column;
  6. .loading-indicator {
  7. font-size: 12px;
  8. color: var(--primary);
  9. margin-left: 8px;
  10. font-weight: normal;
  11. opacity: 0.8;
  12. }
  13. .mcp-market-page-body {
  14. padding: 20px;
  15. overflow-y: auto;
  16. .loading-container,
  17. .empty-container {
  18. display: flex;
  19. justify-content: center;
  20. align-items: center;
  21. min-height: 200px;
  22. width: 100%;
  23. background-color: var(--white);
  24. border: var(--border-in-light);
  25. border-radius: 10px;
  26. animation: slide-in ease 0.3s;
  27. }
  28. .loading-text,
  29. .empty-text {
  30. font-size: 14px;
  31. color: var(--black);
  32. opacity: 0.5;
  33. text-align: center;
  34. }
  35. .mcp-market-filter {
  36. width: 100%;
  37. max-width: 100%;
  38. margin-bottom: 20px;
  39. animation: slide-in ease 0.3s;
  40. height: 40px;
  41. display: flex;
  42. .search-bar {
  43. flex-grow: 1;
  44. max-width: 100%;
  45. min-width: 0;
  46. }
  47. }
  48. .server-list {
  49. display: flex;
  50. flex-direction: column;
  51. gap: 1px;
  52. }
  53. .mcp-market-item {
  54. padding: 20px;
  55. border: var(--border-in-light);
  56. animation: slide-in ease 0.3s;
  57. background-color: var(--white);
  58. transition: all 0.3s ease;
  59. &.disabled {
  60. opacity: 0.7;
  61. pointer-events: none;
  62. }
  63. &:not(:last-child) {
  64. border-bottom: 0;
  65. }
  66. &:first-child {
  67. border-top-left-radius: 10px;
  68. border-top-right-radius: 10px;
  69. }
  70. &:last-child {
  71. border-bottom-left-radius: 10px;
  72. border-bottom-right-radius: 10px;
  73. }
  74. &.loading {
  75. position: relative;
  76. &::after {
  77. content: "";
  78. position: absolute;
  79. top: 0;
  80. left: 0;
  81. right: 0;
  82. bottom: 0;
  83. background: linear-gradient(
  84. 90deg,
  85. transparent,
  86. rgba(255, 255, 255, 0.2),
  87. transparent
  88. );
  89. background-size: 200% 100%;
  90. animation: loading-pulse 1.5s infinite;
  91. }
  92. }
  93. .operation-status {
  94. display: inline-flex;
  95. align-items: center;
  96. margin-left: 10px;
  97. padding: 2px 8px;
  98. border-radius: 4px;
  99. font-size: 12px;
  100. background-color: #16a34a;
  101. color: #fff;
  102. animation: pulse 1.5s infinite;
  103. &[data-status="stopping"] {
  104. background-color: #9ca3af;
  105. }
  106. &[data-status="starting"] {
  107. background-color: #4ade80;
  108. }
  109. &[data-status="error"] {
  110. background-color: #f87171;
  111. }
  112. }
  113. .mcp-market-header {
  114. display: flex;
  115. justify-content: space-between;
  116. align-items: flex-start;
  117. width: 100%;
  118. .mcp-market-title {
  119. flex-grow: 1;
  120. margin-right: 20px;
  121. max-width: calc(100% - 300px);
  122. }
  123. .mcp-market-name {
  124. font-size: 14px;
  125. font-weight: bold;
  126. display: flex;
  127. align-items: center;
  128. gap: 8px;
  129. margin-bottom: 8px;
  130. .server-status {
  131. display: inline-flex;
  132. align-items: center;
  133. margin-left: 10px;
  134. padding: 2px 8px;
  135. border-radius: 4px;
  136. font-size: 12px;
  137. background-color: #22c55e;
  138. color: #fff;
  139. &.error {
  140. background-color: #ef4444;
  141. }
  142. &.stopped {
  143. background-color: #6b7280;
  144. }
  145. &.initializing {
  146. background-color: #f59e0b;
  147. animation: pulse 1.5s infinite;
  148. }
  149. .error-message {
  150. margin-left: 4px;
  151. font-size: 12px;
  152. }
  153. }
  154. }
  155. .repo-link {
  156. color: var(--primary);
  157. font-size: 12px;
  158. display: inline-flex;
  159. align-items: center;
  160. gap: 4px;
  161. text-decoration: none;
  162. opacity: 0.8;
  163. transition: opacity 0.2s;
  164. &:hover {
  165. opacity: 1;
  166. }
  167. svg {
  168. width: 14px;
  169. height: 14px;
  170. }
  171. }
  172. .tags-container {
  173. display: flex;
  174. gap: 4px;
  175. flex-wrap: wrap;
  176. margin-bottom: 8px;
  177. }
  178. .tag {
  179. background: var(--gray);
  180. color: var(--black);
  181. padding: 2px 6px;
  182. border-radius: 4px;
  183. font-size: 10px;
  184. opacity: 0.8;
  185. }
  186. .mcp-market-info {
  187. color: var(--black);
  188. font-size: 12px;
  189. overflow: hidden;
  190. text-overflow: ellipsis;
  191. white-space: nowrap;
  192. }
  193. .mcp-market-actions {
  194. display: flex;
  195. gap: 12px;
  196. align-items: flex-start;
  197. flex-shrink: 0;
  198. min-width: 180px;
  199. justify-content: flex-end;
  200. }
  201. }
  202. }
  203. }
  204. .array-input {
  205. display: flex;
  206. flex-direction: column;
  207. gap: 12px;
  208. width: 100%;
  209. padding: 16px;
  210. border: 1px solid var(--gray-200);
  211. border-radius: 10px;
  212. background-color: var(--white);
  213. .array-input-item {
  214. display: flex;
  215. gap: 8px;
  216. align-items: center;
  217. width: 100%;
  218. padding: 0;
  219. input {
  220. width: 100%;
  221. padding: 8px 12px;
  222. background-color: var(--gray-50);
  223. border-radius: 6px;
  224. transition: all 0.3s ease;
  225. font-size: 13px;
  226. border: 1px solid var(--gray-200);
  227. &:hover {
  228. background-color: var(--gray-100);
  229. border-color: var(--gray-300);
  230. }
  231. &:focus {
  232. background-color: var(--white);
  233. border-color: var(--primary);
  234. outline: none;
  235. box-shadow: 0 0 0 2px var(--primary-10);
  236. }
  237. &::placeholder {
  238. color: var(--gray-300);
  239. }
  240. }
  241. }
  242. :global(.icon-button.add-path-button) {
  243. width: 100%;
  244. background-color: var(--primary);
  245. color: white;
  246. padding: 8px 12px;
  247. border-radius: 6px;
  248. transition: all 0.3s ease;
  249. margin-top: 8px;
  250. display: flex;
  251. align-items: center;
  252. justify-content: center;
  253. border: none;
  254. height: 36px;
  255. &:hover {
  256. background-color: var(--primary-dark);
  257. }
  258. svg {
  259. width: 16px;
  260. height: 16px;
  261. margin-right: 4px;
  262. filter: brightness(2);
  263. }
  264. }
  265. }
  266. .path-list {
  267. width: 100%;
  268. display: flex;
  269. flex-direction: column;
  270. gap: 10px;
  271. .path-item {
  272. display: flex;
  273. gap: 10px;
  274. width: 100%;
  275. input {
  276. flex: 1;
  277. width: 100%;
  278. max-width: 100%;
  279. padding: 10px;
  280. border: var(--border-in-light);
  281. border-radius: 10px;
  282. box-sizing: border-box;
  283. font-size: 14px;
  284. background-color: var(--white);
  285. color: var(--black);
  286. &:hover {
  287. border-color: var(--gray-300);
  288. }
  289. &:focus {
  290. border-color: var(--primary);
  291. outline: none;
  292. box-shadow: 0 0 0 2px var(--primary-10);
  293. }
  294. }
  295. .browse-button {
  296. padding: 8px;
  297. border: var(--border-in-light);
  298. border-radius: 10px;
  299. background-color: transparent;
  300. color: var(--black-50);
  301. &:hover {
  302. border-color: var(--primary);
  303. color: var(--primary);
  304. background-color: transparent;
  305. }
  306. svg {
  307. width: 16px;
  308. height: 16px;
  309. }
  310. }
  311. .delete-button {
  312. padding: 8px;
  313. border: var(--border-in-light);
  314. border-radius: 10px;
  315. background-color: transparent;
  316. color: var(--black-50);
  317. &:hover {
  318. border-color: var(--danger);
  319. color: var(--danger);
  320. background-color: transparent;
  321. }
  322. svg {
  323. width: 16px;
  324. height: 16px;
  325. }
  326. }
  327. .file-input {
  328. display: none;
  329. }
  330. }
  331. .add-button {
  332. align-self: flex-start;
  333. display: flex;
  334. align-items: center;
  335. gap: 5px;
  336. padding: 8px 12px;
  337. background-color: transparent;
  338. border: var(--border-in-light);
  339. border-radius: 10px;
  340. color: var(--black);
  341. font-size: 12px;
  342. margin-top: 5px;
  343. &:hover {
  344. border-color: var(--primary);
  345. color: var(--primary);
  346. background-color: transparent;
  347. }
  348. svg {
  349. width: 16px;
  350. height: 16px;
  351. }
  352. }
  353. }
  354. .config-section {
  355. width: 100%;
  356. .config-header {
  357. margin-bottom: 12px;
  358. .config-title {
  359. font-size: 14px;
  360. font-weight: 600;
  361. color: var(--black);
  362. text-transform: capitalize;
  363. }
  364. .config-description {
  365. font-size: 12px;
  366. color: var(--gray-500);
  367. margin-top: 4px;
  368. }
  369. }
  370. .array-input {
  371. display: flex;
  372. flex-direction: column;
  373. gap: 12px;
  374. width: 100%;
  375. padding: 16px;
  376. border: 1px solid var(--gray-200);
  377. border-radius: 10px;
  378. background-color: var(--white);
  379. .array-input-item {
  380. display: flex;
  381. gap: 8px;
  382. align-items: center;
  383. width: 100%;
  384. padding: 0;
  385. input {
  386. width: 100%;
  387. padding: 8px 12px;
  388. background-color: var(--gray-50);
  389. border-radius: 6px;
  390. transition: all 0.3s ease;
  391. font-size: 13px;
  392. border: 1px solid var(--gray-200);
  393. &:hover {
  394. background-color: var(--gray-100);
  395. border-color: var(--gray-300);
  396. }
  397. &:focus {
  398. background-color: var(--white);
  399. border-color: var(--primary);
  400. outline: none;
  401. box-shadow: 0 0 0 2px var(--primary-10);
  402. }
  403. &::placeholder {
  404. color: var(--gray-300);
  405. }
  406. }
  407. :global(.icon-button) {
  408. width: 32px;
  409. height: 32px;
  410. padding: 0;
  411. border-radius: 6px;
  412. background-color: transparent;
  413. border: 1px solid var(--gray-200);
  414. flex-shrink: 0;
  415. display: flex;
  416. align-items: center;
  417. justify-content: center;
  418. &:hover {
  419. background-color: var(--gray-100);
  420. border-color: var(--gray-300);
  421. }
  422. svg {
  423. width: 16px;
  424. height: 16px;
  425. opacity: 0.7;
  426. }
  427. }
  428. }
  429. :global(.icon-button.add-path-button) {
  430. width: 100%;
  431. background-color: var(--primary);
  432. color: white;
  433. padding: 8px 12px;
  434. border-radius: 6px;
  435. transition: all 0.3s ease;
  436. margin-top: 8px;
  437. display: flex;
  438. align-items: center;
  439. justify-content: center;
  440. border: none;
  441. height: 36px;
  442. &:hover {
  443. background-color: var(--primary-dark);
  444. }
  445. svg {
  446. width: 16px;
  447. height: 16px;
  448. margin-right: 4px;
  449. filter: brightness(2);
  450. }
  451. }
  452. }
  453. }
  454. .input-item {
  455. width: 100%;
  456. input {
  457. width: 100%;
  458. padding: 10px;
  459. border: var(--border-in-light);
  460. border-radius: 10px;
  461. box-sizing: border-box;
  462. font-size: 14px;
  463. background-color: var(--white);
  464. color: var(--black);
  465. &:hover {
  466. border-color: var(--gray-300);
  467. }
  468. &:focus {
  469. border-color: var(--primary);
  470. outline: none;
  471. box-shadow: 0 0 0 2px var(--primary-10);
  472. }
  473. &::placeholder {
  474. color: var(--gray-300) !important;
  475. opacity: 1;
  476. }
  477. }
  478. }
  479. .tools-list {
  480. display: flex;
  481. flex-direction: column;
  482. gap: 16px;
  483. width: 100%;
  484. padding: 20px;
  485. max-width: 100%;
  486. overflow-x: hidden;
  487. word-break: break-word;
  488. box-sizing: border-box;
  489. .tool-item {
  490. width: 100%;
  491. box-sizing: border-box;
  492. .tool-name {
  493. font-size: 14px;
  494. font-weight: 600;
  495. color: var(--black);
  496. margin-bottom: 8px;
  497. padding-left: 12px;
  498. border-left: 3px solid var(--primary);
  499. box-sizing: border-box;
  500. width: 100%;
  501. }
  502. .tool-description {
  503. font-size: 13px;
  504. color: var(--gray-500);
  505. line-height: 1.6;
  506. padding-left: 15px;
  507. box-sizing: border-box;
  508. width: 100%;
  509. }
  510. }
  511. }
  512. :global {
  513. .modal-content {
  514. margin-top: 20px;
  515. max-width: 100%;
  516. overflow-x: hidden;
  517. }
  518. .list {
  519. padding: 10px;
  520. margin-bottom: 10px;
  521. background-color: var(--white);
  522. }
  523. .list-item {
  524. border: none;
  525. background-color: transparent;
  526. border-radius: 10px;
  527. padding: 10px;
  528. margin-bottom: 10px;
  529. display: flex;
  530. flex-direction: column;
  531. gap: 10px;
  532. .list-header {
  533. margin-bottom: 0;
  534. .list-title {
  535. font-size: 14px;
  536. font-weight: bold;
  537. text-transform: capitalize;
  538. color: var(--black);
  539. }
  540. .list-sub-title {
  541. font-size: 12px;
  542. color: var(--gray-500);
  543. margin-top: 4px;
  544. }
  545. }
  546. }
  547. }
  548. }
  549. @keyframes loading-pulse {
  550. 0% {
  551. background-position: 200% 0;
  552. }
  553. 100% {
  554. background-position: -200% 0;
  555. }
  556. }
  557. @keyframes pulse {
  558. 0% {
  559. opacity: 0.6;
  560. }
  561. 50% {
  562. opacity: 1;
  563. }
  564. 100% {
  565. opacity: 0.6;
  566. }
  567. }