@abtnode/ux 1.16.16 → 1.16.17-beta-7ec31a60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,643 @@
1
+ import { useState, useEffect, lazy, useRef } from 'react';
2
+ import { Link, useNavigate, useParams } from 'react-router-dom';
3
+ import styled from '@emotion/styled';
4
+ import useSetState from 'react-use/lib/useSetState';
5
+ import pick from 'lodash/pick';
6
+ import joinUrl from 'url-join';
7
+ import semver from 'semver';
8
+ import Avatar from '@mui/material/Avatar';
9
+ import TextField from '@mui/material/TextField';
10
+ import Typography from '@mui/material/Typography';
11
+ import Breadcrumbs from '@mui/material/Breadcrumbs';
12
+ import Box from '@mui/material/Box';
13
+ import IconButton from '@mui/material/IconButton';
14
+ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
15
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
16
+ import Button from '@arcblock/ux/lib/Button';
17
+ import Toast from '@arcblock/ux/lib/Toast';
18
+ import Tabs from '@arcblock/ux/lib/Tabs';
19
+ import Empty from '@arcblock/ux/lib/Empty';
20
+ import { PROJECT } from '@blocklet/constant';
21
+ import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
22
+ import BlockletBundleAvatar from '../bundle-avatar';
23
+ import { useNodeContext } from '../../contexts/node';
24
+ import { useBlockletContext } from '../../contexts/blocklet';
25
+ import EmptySpinner from '../../empty-spinner';
26
+ import Resource from './resource';
27
+
28
+ // eslint-disable-next-line import/no-unresolved
29
+ import { jsx as _jsx } from "react/jsx-runtime";
30
+ import { jsxs as _jsxs } from "react/jsx-runtime";
31
+ import { Fragment as _Fragment } from "react/jsx-runtime";
32
+ const UploaderComponent = /*#__PURE__*/lazy(() => import('@blocklet/uploader/react').then(res => ({
33
+ default: res.Uploader
34
+ })));
35
+ const addComponentTabs = ({
36
+ tabs,
37
+ blocklet,
38
+ ancestors = []
39
+ }) => {
40
+ const key = blocklet.meta.did;
41
+ tabs.push({
42
+ label: /*#__PURE__*/_jsxs(Box, {
43
+ ml: -4,
44
+ display: "flex",
45
+ alignItems: "center",
46
+ justifyContent: "flex-start",
47
+ children: [/*#__PURE__*/_jsx(BlockletBundleAvatar, {
48
+ size: 24,
49
+ blocklet: blocklet,
50
+ ancestors: ancestors
51
+ }), /*#__PURE__*/_jsx(Box, {
52
+ ml: "16px",
53
+ className: "text",
54
+ children: /*#__PURE__*/_jsx(Box, {
55
+ children: blocklet.meta.title
56
+ })
57
+ })]
58
+ }, key),
59
+ value: key
60
+ });
61
+ };
62
+ const pickParams = release => pick(release, ['blockletVersion', 'blockletTitle', 'blockletDescription', 'blockletLogo', 'blockletIntroduction', 'blockletScreenshots', 'note']);
63
+ export default function CreateRelease({
64
+ ...rest
65
+ }) {
66
+ const navigate = useNavigate();
67
+ const {
68
+ projectId,
69
+ releaseId: inputReleaseId
70
+ } = useParams();
71
+ const {
72
+ t
73
+ } = useLocaleContext();
74
+ const {
75
+ blocklet
76
+ } = useBlockletContext();
77
+ const [params, setParams] = useSetState(null);
78
+ const [loading, setLoading] = useState(false);
79
+ const [release, setRelease] = useState(null);
80
+ const {
81
+ api
82
+ } = useNodeContext();
83
+ const uploaderLogoRef = useRef(null);
84
+ const uploaderScreenshotRef = useRef(null);
85
+ const releaseId = inputReleaseId === 'create' ? '' : inputReleaseId;
86
+ const mode = inputReleaseId === 'create' ? 'create' : 'edit';
87
+ const tabs = [];
88
+ const resourceComponents = (blocklet?.children || []).filter(x => x.meta.capabilities.resourceExportPage);
89
+ resourceComponents.forEach(item => {
90
+ addComponentTabs({
91
+ tabs,
92
+ blocklet: item,
93
+ t,
94
+ ancestors: [blocklet]
95
+ });
96
+ });
97
+ const [tab, setTab] = useState(tabs[0]?.value);
98
+ const isPublished = release?.status === 'published';
99
+ const readOnly = isPublished;
100
+ const getProject = () => {
101
+ api.getProject({
102
+ input: {
103
+ did: blocklet.meta.did,
104
+ projectId
105
+ }
106
+ }).then(res => {
107
+ setLoading(false);
108
+ const data = res.project || {};
109
+ if (!data.blockletVersion) {
110
+ data.blockletVersion = '1.0.0';
111
+ } else if (semver.valid(data.blockletVersion)) {
112
+ data.blockletVersion = semver.inc(data.blockletVersion, 'patch');
113
+ }
114
+ setParams(pickParams(data));
115
+ }).catch(err => {
116
+ setLoading(false);
117
+ Toast.error(err.message);
118
+ });
119
+ };
120
+ const getRelease = () => {
121
+ api.getRelease({
122
+ input: {
123
+ did: blocklet.meta.did,
124
+ projectId,
125
+ releaseId
126
+ }
127
+ }).then(res => {
128
+ setLoading(false);
129
+ setParams(pickParams(res?.release));
130
+ setRelease(res?.release);
131
+ }).catch(err => {
132
+ setLoading(false);
133
+ Toast.error(err.message);
134
+ });
135
+ };
136
+ const getData = () => {
137
+ if (mode === 'edit') {
138
+ if (!releaseId) {
139
+ Toast.error('Empty release id');
140
+ return;
141
+ }
142
+ getRelease();
143
+ }
144
+ if (mode === 'create') {
145
+ getProject();
146
+ }
147
+ };
148
+ useEffect(() => {
149
+ getData();
150
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
151
+
152
+ const onRelease = status => {
153
+ if (!params.blockletTitle) {
154
+ Toast.error(t('blocklet.publish.errorTip.noTitle'));
155
+ return;
156
+ }
157
+ if (!params.blockletVersion) {
158
+ Toast.error(t('blocklet.publish.errorTip.noVersion'));
159
+ return;
160
+ }
161
+ if (status === PROJECT.RELEASE_STATUS.published) {
162
+ if (!params.blockletDescription) {
163
+ Toast.error(t('blocklet.publish.errorTip.noDescription'));
164
+ return;
165
+ }
166
+ if (!params.note) {
167
+ Toast.error(t('blocklet.publish.errorTip.noNote'));
168
+ return;
169
+ }
170
+ }
171
+ const _params = {
172
+ ...params
173
+ };
174
+ _params.blockletVersion = semver.valid(_params.blockletVersion);
175
+ if (!_params.blockletVersion) {
176
+ Toast.error('Invalid Blocklet Version');
177
+ return;
178
+ }
179
+ _params.blockletTitle = (_params.blockletTitle || '').trim();
180
+ _params.blockletDescription = (_params.blockletDescription || '').trim();
181
+ _params.blockletIntroduction = (_params.blockletIntroduction || '').trim();
182
+ _params.note = (_params.note || '').trim();
183
+ api.createRelease({
184
+ input: {
185
+ ..._params,
186
+ did: blocklet.meta.did,
187
+ projectId,
188
+ releaseId,
189
+ status
190
+ }
191
+ }).then(() => {
192
+ if (status === 'draft') {
193
+ Toast.success('Save draft success');
194
+ if (mode === 'create') {
195
+ navigate(`../${projectId}`, {
196
+ replace: true
197
+ });
198
+ }
199
+ } else {
200
+ Toast.success('Create Release success');
201
+ navigate(`../${projectId}`, {
202
+ replace: true
203
+ });
204
+ }
205
+ }).catch(err => {
206
+ Toast.error(err.message);
207
+ });
208
+ };
209
+ if (!params && loading) {
210
+ return /*#__PURE__*/_jsx(EmptySpinner, {});
211
+ }
212
+ if (!params) {
213
+ return null;
214
+ }
215
+ const uploadLogoPrefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/logo/upload`;
216
+ const uploadScreenshotPrefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/screenshot/upload`;
217
+ const logoUrl = params?.blockletLogo ? `${uploadLogoPrefix}/${params.blockletLogo}` : `${WELLKNOWN_SERVICE_PATH_PREFIX}/static/images/logo.png`;
218
+ const screenshotUrls = (params?.blockletScreenshots || []).filter(Boolean).map(x => `${uploadScreenshotPrefix}/${x}`);
219
+ const item = resourceComponents.find(x => x.meta.did === tab);
220
+ const resourceContent = item ? /*#__PURE__*/_jsx(Box, {
221
+ children: /*#__PURE__*/_jsx(Resource, {
222
+ app: blocklet,
223
+ component: item,
224
+ projectId: projectId,
225
+ release: {
226
+ ...release,
227
+ id: releaseId
228
+ }
229
+ })
230
+ }) : /*#__PURE__*/_jsx(Box, {
231
+ display: "flex",
232
+ mt: -3,
233
+ children: /*#__PURE__*/_jsx(Empty, {
234
+ children: t('common.empty')
235
+ })
236
+ });
237
+ const onTabChange = x => {
238
+ setTab(x);
239
+ };
240
+ return /*#__PURE__*/_jsxs(Main, {
241
+ ...rest,
242
+ children: [/*#__PURE__*/_jsxs(Box, {
243
+ className: "sticky-header",
244
+ children: [/*#__PURE__*/_jsxs(Breadcrumbs, {
245
+ className: "breadcrumbs",
246
+ "aria-label": "breadcrumb",
247
+ children: [/*#__PURE__*/_jsx(Link, {
248
+ to: "../",
249
+ children: t('common.publish')
250
+ }), /*#__PURE__*/_jsx(Link, {
251
+ to: `../${projectId}`,
252
+ children: params?.blockletTitle || 'Blocklet'
253
+ }), /*#__PURE__*/_jsx(Typography, {
254
+ color: "text.primary",
255
+ children: mode === 'create' ? t('common.create') : params?.blockletVersion || t('common.edit')
256
+ })]
257
+ }), /*#__PURE__*/_jsxs(Box, {
258
+ display: "flex",
259
+ children: [!isPublished && /*#__PURE__*/_jsxs(_Fragment, {
260
+ children: [/*#__PURE__*/_jsx(Button, {
261
+ variant: "outlined",
262
+ disabled: loading,
263
+ onClick: () => onRelease(PROJECT.RELEASE_STATUS.draft),
264
+ style: {
265
+ marginRight: 12
266
+ },
267
+ children: t('blocklet.publish.saveDraft')
268
+ }), /*#__PURE__*/_jsx(Button, {
269
+ variant: "contained",
270
+ disabled: loading,
271
+ onClick: () => onRelease(PROJECT.RELEASE_STATUS.published),
272
+ children: t('common.release')
273
+ })]
274
+ }), isPublished && /*#__PURE__*/_jsx(Button, {
275
+ variant: "contained",
276
+ children: /*#__PURE__*/_jsx("a", {
277
+ href: joinUrl(`${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/${releaseId}/download/${(release.files || [])[0]}`),
278
+ children: t('common.download')
279
+ })
280
+ })]
281
+ })]
282
+ }), /*#__PURE__*/_jsxs(Box, {
283
+ pt: 3,
284
+ children: [/*#__PURE__*/_jsxs(Box, {
285
+ display: "flex",
286
+ className: "section",
287
+ children: [/*#__PURE__*/_jsx(Typography, {
288
+ variant: "h3",
289
+ className: "left",
290
+ children: t('blocklet.publish.productTitle')
291
+ }), /*#__PURE__*/_jsxs(Box, {
292
+ sx: {
293
+ flex: 1
294
+ },
295
+ children: [/*#__PURE__*/_jsx(TextField, {
296
+ label: `Blocklet ${t('common.title')}`,
297
+ placeholder: `Blocklet ${t('common.title')}`,
298
+ inputProps: {
299
+ 'data-cy': 'blocklet-title',
300
+ readOnly
301
+ },
302
+ autoComplete: "off",
303
+ variant: "outlined",
304
+ fullWidth: true,
305
+ value: params.blockletTitle || '',
306
+ onChange: e => {
307
+ setParams({
308
+ blockletTitle: e.target.value
309
+ });
310
+ }
311
+ }), /*#__PURE__*/_jsx(TextField, {
312
+ label: `Blocklet ${t('common.description')}`,
313
+ placeholder: `Blocklet ${t('common.description')}`,
314
+ inputProps: {
315
+ 'data-cy': 'blocklet-description',
316
+ readOnly
317
+ },
318
+ autoComplete: "off",
319
+ variant: "outlined",
320
+ fullWidth: true,
321
+ value: params.blockletDescription || '',
322
+ onChange: e => {
323
+ setParams({
324
+ blockletDescription: e.target.value
325
+ });
326
+ },
327
+ sx: {
328
+ mt: 3
329
+ }
330
+ }), /*#__PURE__*/_jsx(TextField, {
331
+ label: `Blocklet ${t('common.introduction')}`,
332
+ placeholder: `Blocklet ${t('common.introduction')}`,
333
+ inputProps: {
334
+ 'data-cy': 'export-blocklet-introduction',
335
+ readOnly
336
+ },
337
+ autoComplete: "off",
338
+ variant: "outlined",
339
+ fullWidth: true,
340
+ multiline: true,
341
+ rows: 4,
342
+ value: params.blockletIntroduction || '',
343
+ onChange: e => {
344
+ setParams({
345
+ blockletIntroduction: e.target.value
346
+ });
347
+ },
348
+ sx: {
349
+ mt: 3
350
+ }
351
+ })]
352
+ })]
353
+ }), /*#__PURE__*/_jsxs(Box, {
354
+ display: "flex",
355
+ mt: 3,
356
+ className: "section",
357
+ children: [/*#__PURE__*/_jsx(Typography, {
358
+ variant: "h3",
359
+ className: "left",
360
+ children: t('blocklet.publish.versionTitle')
361
+ }), /*#__PURE__*/_jsxs(Box, {
362
+ sx: {
363
+ flex: 1
364
+ },
365
+ children: [/*#__PURE__*/_jsx(TextField, {
366
+ label: `Blocklet ${t('common.version')}`,
367
+ placeholder: `Blocklet ${t('common.version')}`,
368
+ inputProps: {
369
+ 'data-cy': 'blocklet-version',
370
+ readOnly
371
+ },
372
+ autoComplete: "off",
373
+ variant: "outlined",
374
+ fullWidth: true,
375
+ value: params.blockletVersion,
376
+ onChange: e => {
377
+ setParams({
378
+ blockletVersion: e.target.value
379
+ });
380
+ }
381
+ }), /*#__PURE__*/_jsx(TextField, {
382
+ label: t('blocklet.publish.releaseNote'),
383
+ autoComplete: "off",
384
+ variant: "outlined",
385
+ inputProps: {
386
+ 'data-cy': 'release-note',
387
+ readOnly
388
+ },
389
+ fullWidth: true,
390
+ multiline: true,
391
+ rows: 4,
392
+ value: params.note,
393
+ onChange: e => {
394
+ setParams({
395
+ note: e.target.value
396
+ });
397
+ },
398
+ sx: {
399
+ mt: 3
400
+ }
401
+ })]
402
+ })]
403
+ }), /*#__PURE__*/_jsxs(Box, {
404
+ display: "flex",
405
+ mt: 3,
406
+ className: "section full-width",
407
+ children: [/*#__PURE__*/_jsx(Typography, {
408
+ variant: "h3",
409
+ className: "left",
410
+ children: t('blocklet.publish.imgTitle')
411
+ }), /*#__PURE__*/_jsxs(Box, {
412
+ sx: {
413
+ flex: 1
414
+ },
415
+ children: [/*#__PURE__*/_jsxs(Box, {
416
+ display: "flex",
417
+ children: [/*#__PURE__*/_jsx(Typography, {
418
+ variant: "subtitle1",
419
+ sx: {
420
+ mr: 2
421
+ },
422
+ children: t('common.logo')
423
+ }), /*#__PURE__*/_jsx(Box, {
424
+ sx: {
425
+ flex: 1,
426
+ cursor: readOnly ? 'default' : 'pointer'
427
+ },
428
+ children: /*#__PURE__*/_jsx(Avatar, {
429
+ variant: "square",
430
+ sx: {
431
+ width: 80,
432
+ height: 80
433
+ },
434
+ alt: "Blocklet Logo",
435
+ src: logoUrl,
436
+ onClick: () => !readOnly && uploaderLogoRef.current.open()
437
+ })
438
+ })]
439
+ }), /*#__PURE__*/_jsxs(Box, {
440
+ display: "flex",
441
+ mt: 3,
442
+ children: [/*#__PURE__*/_jsx(Typography, {
443
+ variant: "subtitle1",
444
+ sx: {
445
+ mr: 2
446
+ },
447
+ children: t('common.screenshot')
448
+ }), /*#__PURE__*/_jsxs(Box, {
449
+ display: "flex",
450
+ alignItems: "center",
451
+ sx: {
452
+ flex: 1,
453
+ flexWrap: 'wrap'
454
+ },
455
+ children: [screenshotUrls.map((x, index) => /*#__PURE__*/_jsxs(Box, {
456
+ className: "screenshot",
457
+ children: [/*#__PURE__*/_jsx("img", {
458
+ alt: "screenshot",
459
+ src: x
460
+ }), !readOnly && /*#__PURE__*/_jsx(IconButton, {
461
+ className: "action",
462
+ onClick: () => {
463
+ const arr = [...params.blockletScreenshots];
464
+ arr.splice(index, 1);
465
+ setParams({
466
+ blockletScreenshots: arr
467
+ });
468
+ },
469
+ children: /*#__PURE__*/_jsx(DeleteOutlineIcon, {})
470
+ })]
471
+ })), screenshotUrls.length < 5 && /*#__PURE__*/_jsx(Box, {
472
+ sx: {
473
+ width: 200,
474
+ height: 140,
475
+ background: '#eee',
476
+ cursor: readOnly ? 'default' : 'pointer',
477
+ color: '#999',
478
+ mb: 2
479
+ },
480
+ display: "flex",
481
+ justifyContent: "center",
482
+ alignItems: "center",
483
+ fontSize: 40,
484
+ onClick: () => !readOnly && uploaderScreenshotRef.current.open(),
485
+ children: "+"
486
+ })]
487
+ })]
488
+ })]
489
+ }), /*#__PURE__*/_jsx(UploaderComponent, {
490
+ id: "\u200Buploader-logo",
491
+ ref: uploaderLogoRef,
492
+ popup: true,
493
+ onUploadFinish: result => {
494
+ setParams({
495
+ blockletLogo: result.data.filename
496
+ });
497
+ },
498
+ plugins: ['ImageEditor', 'Url', 'Webcam'],
499
+ apiPathProps: {
500
+ uploader: uploadLogoPrefix,
501
+ disableMediaKitPrefix: true
502
+ }
503
+ }, "uploader-screenshot"), /*#__PURE__*/_jsx(UploaderComponent, {
504
+ id: "\u200Buploader-screenshot",
505
+ ref: uploaderScreenshotRef,
506
+ popup: true,
507
+ onUploadFinish: result => {
508
+ const blockletScreenshots = params.blockletScreenshots || [];
509
+ blockletScreenshots.push(result.data?.filename);
510
+ setParams({
511
+ blockletScreenshots
512
+ });
513
+ },
514
+ plugins: ['ImageEditor', 'Url', 'Webcam'],
515
+ apiPathProps: {
516
+ uploader: uploadScreenshotPrefix,
517
+ disableMediaKitPrefix: true
518
+ }
519
+ }, "uploader-screenshot")]
520
+ }), /*#__PURE__*/_jsxs(Box, {
521
+ display: "flex",
522
+ mt: 3,
523
+ className: "section full-width",
524
+ children: [/*#__PURE__*/_jsxs(Box, {
525
+ className: "left",
526
+ children: [/*#__PURE__*/_jsx(Typography, {
527
+ variant: "h3",
528
+ children: t('blocklet.publish.resourceTitle')
529
+ }), /*#__PURE__*/_jsx(Tabs, {
530
+ tabs: tabs,
531
+ current: tab,
532
+ orientation: "vertical",
533
+ onChange: onTabChange,
534
+ sx: {
535
+ width: '100%'
536
+ }
537
+ })]
538
+ }), /*#__PURE__*/_jsx(Box, {
539
+ sx: {
540
+ flex: 1
541
+ },
542
+ children: /*#__PURE__*/_jsx(Box, {
543
+ children: resourceContent
544
+ })
545
+ })]
546
+ })]
547
+ })]
548
+ });
549
+ }
550
+ CreateRelease.propTypes = {};
551
+ CreateRelease.defaultProps = {};
552
+ const Main = styled.div`
553
+ .sticky-header {
554
+ margin-top: -12px;
555
+ padding: 12px 0;
556
+ position: sticky;
557
+ top: 0;
558
+ z-index: 99;
559
+ display: flex;
560
+ align-items: center;
561
+ justify-content: space-between;
562
+ background-color: #fff;
563
+ padding-bottom: 12px;
564
+ border-bottom: ${({
565
+ theme
566
+ }) => `1px solid ${theme.palette.divider}`};
567
+ }
568
+ .screenshot {
569
+ margin-bottom: 16px;
570
+ max-width: 200px;
571
+ max-height: 140px;
572
+ width: 200px;
573
+ height: 140px;
574
+ overflow: hidden;
575
+ display: flex;
576
+ align-items: center;
577
+ justify-content: center;
578
+ background-color: #eee;
579
+ margin-right: 16px;
580
+ position: relative;
581
+ .action {
582
+ visibility: hidden;
583
+ position: absolute;
584
+ top: 0px;
585
+ right: 0px;
586
+ background-color: rgba(0, 0, 0, 0.2);
587
+ color: rgba(255, 255, 255, 0.8);
588
+ }
589
+ &:hover .action {
590
+ visibility: visible;
591
+ }
592
+ }
593
+ .screenshot img {
594
+ width: 100%; /* 图像宽度填充容器 */
595
+ height: auto; /* 图像高度自适应 */
596
+ }
597
+ .section {
598
+ max-width: 800px;
599
+ &.full-width {
600
+ max-width: 100%;
601
+ }
602
+ .MuiTypography-h3 {
603
+ font-size: 1.1rem;
604
+ font-weight: 700;
605
+ }
606
+ .left {
607
+ flex-shrink: 0;
608
+ width: 140px;
609
+ }
610
+ .MuiTabs-root {
611
+ margin-top: 8px;
612
+ transform: translateX(-16px);
613
+ .MuiButtonBase-root .text {
614
+ color: ${({
615
+ theme
616
+ }) => theme.palette.text.primary};
617
+ }
618
+ .MuiButtonBase-root.Mui-selected .text {
619
+ color: ${({
620
+ theme
621
+ }) => theme.palette.primary.main};
622
+ }
623
+ }
624
+ .MuiTabs-indicator {
625
+ display: none;
626
+ }
627
+ .MuiTypography-subtitle1 {
628
+ width: 120px;
629
+ font-weight: 700;
630
+ font-size: 1rem;
631
+ ${({
632
+ theme
633
+ }) => theme.breakpoints.down('sm')} {
634
+ width: 80px;
635
+ }
636
+ }
637
+ }
638
+ .MuiButtonBase-root {
639
+ a {
640
+ color: inherit;
641
+ }
642
+ }
643
+ `;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { Routes, Route } from 'react-router-dom';
3
+ import styled from '@emotion/styled';
4
+ import Box from '@mui/material/Box';
5
+ import ProjectList from './project-list';
6
+ import CreateProject from './create-project';
7
+ import ReleasesList from './release-list';
8
+ import CreateRelease from './create-release';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ export default function BlockletPublish() {
12
+ return /*#__PURE__*/_jsx(Main, {
13
+ children: /*#__PURE__*/_jsxs(Routes, {
14
+ children: [/*#__PURE__*/_jsx(Route, {
15
+ path: "/",
16
+ element: /*#__PURE__*/_jsx(ProjectList, {})
17
+ }), /*#__PURE__*/_jsx(Route, {
18
+ path: "/create",
19
+ element: /*#__PURE__*/_jsx(CreateProject, {})
20
+ }), /*#__PURE__*/_jsx(Route, {
21
+ path: "/:projectId",
22
+ element: /*#__PURE__*/_jsx(ReleasesList, {})
23
+ }), /*#__PURE__*/_jsx(Route, {
24
+ path: "/:projectId/:releaseId",
25
+ element: /*#__PURE__*/_jsx(CreateRelease, {})
26
+ })]
27
+ })
28
+ });
29
+ }
30
+ BlockletPublish.propTypes = {};
31
+ const Main = styled(Box)`
32
+ a {
33
+ color: ${({
34
+ theme
35
+ }) => theme.palette.primary.main};
36
+ }
37
+ `;