@manojkmfsi/monodog 1.1.37 → 1.1.39
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.
- package/CHANGELOG.md +12 -0
- package/monodog-dashboard/dist/assets/index-C08ciT3A.js +20 -0
- package/monodog-dashboard/dist/assets/index-C08ciT3A.js.map +1 -0
- package/monodog-dashboard/dist/assets/index-Dc2vaUOq.css +1 -0
- package/monodog-dashboard/{index.html → dist/index.html} +2 -1
- package/monodog-dashboard/package.json +0 -3
- package/package.json +2 -2
- package/monodog-dashboard/THEME_SYSTEM.md +0 -309
- package/monodog-dashboard/__tests__/AuthCallbackPage.test.ts +0 -138
- package/monodog-dashboard/__tests__/ConfigInspector.test.ts +0 -33
- package/monodog-dashboard/__tests__/DependencyGraph.test.ts +0 -72
- package/monodog-dashboard/__tests__/HealthStatus.test.ts +0 -69
- package/monodog-dashboard/__tests__/LoginPage.test.ts +0 -79
- package/monodog-dashboard/__tests__/PackageDetail.test.ts +0 -22
- package/monodog-dashboard/__tests__/ReleaseManager.test.tsx +0 -510
- package/monodog-dashboard/__tests__/api-client.test.ts +0 -475
- package/monodog-dashboard/__tests__/components.test.ts +0 -117
- package/monodog-dashboard/__tests__/dashboard.utils.test.ts +0 -144
- package/monodog-dashboard/__tests__/dependency.utils.test.ts +0 -125
- package/monodog-dashboard/__tests__/monorepoService.unit.test.ts +0 -103
- package/monodog-dashboard/__tests__/packages.utils.test.ts +0 -37
- package/monodog-dashboard/__tests__/pages.test.ts +0 -103
- package/monodog-dashboard/package-lock.json +0 -4587
- package/monodog-dashboard/postcss.config.js +0 -6
- package/monodog-dashboard/src/components/App.tsx +0 -36
- package/monodog-dashboard/src/components/LoadingState.tsx +0 -18
- package/monodog-dashboard/src/components/PermissionGuard.tsx +0 -92
- package/monodog-dashboard/src/components/ProtectedRoute.tsx +0 -24
- package/monodog-dashboard/src/components/configuration/Configuration.tsx +0 -91
- package/monodog-dashboard/src/components/configuration/components/BrandingSettings.tsx +0 -128
- package/monodog-dashboard/src/components/configuration/components/ConfigurationHeader.tsx +0 -34
- package/monodog-dashboard/src/components/configuration/components/ConfigurationModal.tsx +0 -20
- package/monodog-dashboard/src/components/configuration/components/ConfigurationTabs.tsx +0 -30
- package/monodog-dashboard/src/components/configuration/components/FeatureToggles.tsx +0 -66
- package/monodog-dashboard/src/components/configuration/components/GeneralSettings.tsx +0 -77
- package/monodog-dashboard/src/components/configuration/components/MonorepoSettings.tsx +0 -179
- package/monodog-dashboard/src/components/configuration/components/index.ts +0 -8
- package/monodog-dashboard/src/components/configuration/types/config.types.ts +0 -52
- package/monodog-dashboard/src/components/configuration/utils/config.utils.tsx +0 -115
- package/monodog-dashboard/src/components/main-dashboard/Dashboard.tsx +0 -242
- package/monodog-dashboard/src/components/main-dashboard/Layout.tsx +0 -112
- package/monodog-dashboard/src/components/main-dashboard/components/Header.tsx +0 -47
- package/monodog-dashboard/src/components/main-dashboard/components/PackageDistribution.tsx +0 -35
- package/monodog-dashboard/src/components/main-dashboard/components/PackageSearchFilter.tsx +0 -47
- package/monodog-dashboard/src/components/main-dashboard/components/PackageTable.tsx +0 -87
- package/monodog-dashboard/src/components/main-dashboard/components/QuickActions.tsx +0 -60
- package/monodog-dashboard/src/components/main-dashboard/components/StatsCards.tsx +0 -73
- package/monodog-dashboard/src/components/main-dashboard/components/index.ts +0 -7
- package/monodog-dashboard/src/components/main-dashboard/types/dashboard.types.ts +0 -33
- package/monodog-dashboard/src/components/main-dashboard/utils/dashboard.utils.tsx +0 -70
- package/monodog-dashboard/src/components/modules/ci-integration/CIIntegration.tsx +0 -277
- package/monodog-dashboard/src/components/modules/ci-integration/components/BuildDetails.tsx +0 -228
- package/monodog-dashboard/src/components/modules/ci-integration/components/BuildList.tsx +0 -212
- package/monodog-dashboard/src/components/modules/ci-integration/components/BuildOverview.tsx +0 -158
- package/monodog-dashboard/src/components/modules/ci-integration/components/CIIntegrationHeader.tsx +0 -38
- package/monodog-dashboard/src/components/modules/ci-integration/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/ci-integration/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/ci-integration/components/PipelineStatus.tsx +0 -223
- package/monodog-dashboard/src/components/modules/ci-integration/components/index.ts +0 -8
- package/monodog-dashboard/src/components/modules/ci-integration/types/ci.types.ts +0 -97
- package/monodog-dashboard/src/components/modules/ci-integration/utils/ci.utils.tsx +0 -264
- package/monodog-dashboard/src/components/modules/config-inspector/ConfigInspector.tsx +0 -324
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigEditor.tsx +0 -93
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigInspectorHeader.tsx +0 -36
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigPreview.tsx +0 -89
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigSidebar.tsx +0 -141
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigToolbar.tsx +0 -184
- package/monodog-dashboard/src/components/modules/config-inspector/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/config-inspector/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/config-inspector/components/ValidationPanel.tsx +0 -155
- package/monodog-dashboard/src/components/modules/config-inspector/components/index.ts +0 -9
- package/monodog-dashboard/src/components/modules/config-inspector/types/config.types.ts +0 -100
- package/monodog-dashboard/src/components/modules/config-inspector/utils/config.utils.tsx +0 -704
- package/monodog-dashboard/src/components/modules/dependency-graph/DependencyGraph.tsx +0 -224
- package/monodog-dashboard/src/components/modules/dependency-graph/components/CircularDependencies.tsx +0 -177
- package/monodog-dashboard/src/components/modules/dependency-graph/components/DependencyDetails.tsx +0 -192
- package/monodog-dashboard/src/components/modules/dependency-graph/components/DependencyGraphHeader.tsx +0 -30
- package/monodog-dashboard/src/components/modules/dependency-graph/components/DependencyList.tsx +0 -177
- package/monodog-dashboard/src/components/modules/dependency-graph/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphLegend.tsx +0 -89
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphStats.tsx +0 -141
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphToolbar.tsx +0 -107
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphVisualization.tsx +0 -179
- package/monodog-dashboard/src/components/modules/dependency-graph/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/dependency-graph/components/index.ts +0 -11
- package/monodog-dashboard/src/components/modules/dependency-graph/types/dependency.types.ts +0 -105
- package/monodog-dashboard/src/components/modules/dependency-graph/utils/dependency.utils.tsx +0 -433
- package/monodog-dashboard/src/components/modules/health-status/HealthStatus.tsx +0 -739
- package/monodog-dashboard/src/components/modules/health-status/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/health-status/components/HealthActions.tsx +0 -122
- package/monodog-dashboard/src/components/modules/health-status/components/HealthAlerts.tsx +0 -151
- package/monodog-dashboard/src/components/modules/health-status/components/HealthMetrics.tsx +0 -132
- package/monodog-dashboard/src/components/modules/health-status/components/HealthStatusHeader.tsx +0 -30
- package/monodog-dashboard/src/components/modules/health-status/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/health-status/components/OverallHealthScore.tsx +0 -122
- package/monodog-dashboard/src/components/modules/health-status/components/PackageHealthList.tsx +0 -195
- package/monodog-dashboard/src/components/modules/health-status/types/health.types.ts +0 -80
- package/monodog-dashboard/src/components/modules/health-status/utils/health.utils.tsx +0 -220
- package/monodog-dashboard/src/components/modules/packages/PackageDetail.tsx +0 -255
- package/monodog-dashboard/src/components/modules/packages/PackagesOverview.tsx +0 -166
- package/monodog-dashboard/src/components/modules/packages/components/ConfigurationTab.tsx +0 -311
- package/monodog-dashboard/src/components/modules/packages/components/DependenciesTab.tsx +0 -154
- package/monodog-dashboard/src/components/modules/packages/components/ErrorState.tsx +0 -21
- package/monodog-dashboard/src/components/modules/packages/components/HealthMetricsTab.tsx +0 -275
- package/monodog-dashboard/src/components/modules/packages/components/LoadingState.tsx +0 -14
- package/monodog-dashboard/src/components/modules/packages/components/PackageDetailHeader.tsx +0 -167
- package/monodog-dashboard/src/components/modules/packages/components/PackageDetailTabs.tsx +0 -49
- package/monodog-dashboard/src/components/modules/packages/components/PackageStats.tsx +0 -70
- package/monodog-dashboard/src/components/modules/packages/components/PackagesTable.tsx +0 -163
- package/monodog-dashboard/src/components/modules/packages/components/RecentCommitsTab.tsx +0 -90
- package/monodog-dashboard/src/components/modules/packages/components/SearchAndFilter.tsx +0 -66
- package/monodog-dashboard/src/components/modules/packages/components/index.ts +0 -12
- package/monodog-dashboard/src/components/modules/packages/types/packages.types.ts +0 -101
- package/monodog-dashboard/src/components/modules/packages/utils/packages.utils.tsx +0 -178
- package/monodog-dashboard/src/components/pipeline/JobsList.tsx +0 -83
- package/monodog-dashboard/src/components/pipeline/LogViewer.tsx +0 -392
- package/monodog-dashboard/src/components/pipeline/PipelineManager.tsx +0 -562
- package/monodog-dashboard/src/components/pipeline/WorkflowRunsList.tsx +0 -272
- package/monodog-dashboard/src/components/pipeline/WorkflowTrigger.tsx +0 -182
- package/monodog-dashboard/src/components/pipeline/utils/pipeline.utils.tsx +0 -11
- package/monodog-dashboard/src/components/publish-control/PublishControl.tsx +0 -229
- package/monodog-dashboard/src/components/publish-control/components/ChangelogViewer.tsx +0 -103
- package/monodog-dashboard/src/components/publish-control/components/ErrorState.tsx +0 -23
- package/monodog-dashboard/src/components/publish-control/components/LoadingState.tsx +0 -10
- package/monodog-dashboard/src/components/publish-control/components/PackageReleaseTable.tsx +0 -140
- package/monodog-dashboard/src/components/publish-control/components/PublishHeader.tsx +0 -30
- package/monodog-dashboard/src/components/publish-control/components/QuickActionCards.tsx +0 -56
- package/monodog-dashboard/src/components/publish-control/components/ReleaseSchedule.tsx +0 -104
- package/monodog-dashboard/src/components/publish-control/components/index.ts +0 -8
- package/monodog-dashboard/src/components/publish-control/types/publish.types.ts +0 -39
- package/monodog-dashboard/src/components/publish-control/utils/publish.utils.ts +0 -59
- package/monodog-dashboard/src/components/release-manager/ReleaseManager.tsx +0 -342
- package/monodog-dashboard/src/components/release-manager/components/ChangesetPreview.tsx +0 -123
- package/monodog-dashboard/src/components/release-manager/components/ErrorState.tsx +0 -38
- package/monodog-dashboard/src/components/release-manager/components/LoadingState.tsx +0 -18
- package/monodog-dashboard/src/components/release-manager/components/PackageSelector.tsx +0 -137
- package/monodog-dashboard/src/components/release-manager/components/PublishConfirmation.tsx +0 -150
- package/monodog-dashboard/src/components/release-manager/components/ReleaseValidation.tsx +0 -138
- package/monodog-dashboard/src/components/release-manager/components/VersionBumpSelector.tsx +0 -142
- package/monodog-dashboard/src/components/release-manager/types/index.ts +0 -9
- package/monodog-dashboard/src/components/release-manager/types/release-manager.types.ts +0 -29
- package/monodog-dashboard/src/components/setup-guide/SetupGuide.tsx +0 -96
- package/monodog-dashboard/src/components/setup-guide/components/SetupHeader.tsx +0 -24
- package/monodog-dashboard/src/components/setup-guide/components/SetupModal.tsx +0 -24
- package/monodog-dashboard/src/components/setup-guide/components/SetupProgress.tsx +0 -29
- package/monodog-dashboard/src/components/setup-guide/components/StepContent.tsx +0 -272
- package/monodog-dashboard/src/components/setup-guide/components/StepNavigation.tsx +0 -62
- package/monodog-dashboard/src/components/setup-guide/components/index.ts +0 -6
- package/monodog-dashboard/src/components/setup-guide/types/setup.types.ts +0 -38
- package/monodog-dashboard/src/components/setup-guide/utils/setup.utils.ts +0 -79
- package/monodog-dashboard/src/constants/api-config.ts +0 -81
- package/monodog-dashboard/src/constants/index.ts +0 -9
- package/monodog-dashboard/src/constants/messages.ts +0 -40
- package/monodog-dashboard/src/icons/heroicons.ts +0 -65
- package/monodog-dashboard/src/icons/index.tsx +0 -1788
- package/monodog-dashboard/src/index.css +0 -175
- package/monodog-dashboard/src/main.tsx +0 -9
- package/monodog-dashboard/src/pages/AuthCallbackPage.tsx +0 -103
- package/monodog-dashboard/src/pages/CIPage.tsx +0 -6
- package/monodog-dashboard/src/pages/ConfigPage.tsx +0 -6
- package/monodog-dashboard/src/pages/DashboardPage.tsx +0 -6
- package/monodog-dashboard/src/pages/DependenciesPage.tsx +0 -6
- package/monodog-dashboard/src/pages/HealthPage.tsx +0 -6
- package/monodog-dashboard/src/pages/LoginPage.tsx +0 -77
- package/monodog-dashboard/src/pages/PackageDetailPage.tsx +0 -6
- package/monodog-dashboard/src/pages/PackagesPage.tsx +0 -6
- package/monodog-dashboard/src/pages/PipelinePage.tsx +0 -22
- package/monodog-dashboard/src/pages/PublishPage.tsx +0 -6
- package/monodog-dashboard/src/pages/ReleaseManagerPage.tsx +0 -9
- package/monodog-dashboard/src/pages/index.ts +0 -28
- package/monodog-dashboard/src/routes/AppRouter.tsx +0 -89
- package/monodog-dashboard/src/routes/AppRouterPages.tsx +0 -56
- package/monodog-dashboard/src/routes/index.ts +0 -10
- package/monodog-dashboard/src/routes/routes.config.ts +0 -94
- package/monodog-dashboard/src/services/api/api-client.ts +0 -189
- package/monodog-dashboard/src/services/api/index.ts +0 -30
- package/monodog-dashboard/src/services/api/types/api.types.ts +0 -63
- package/monodog-dashboard/src/services/auth-context.tsx +0 -344
- package/monodog-dashboard/src/services/monorepoService.ts +0 -733
- package/monodog-dashboard/src/services/permission-context.tsx +0 -193
- package/monodog-dashboard/src/theme/COMPONENT_UPDATES.md +0 -273
- package/monodog-dashboard/src/theme/INTEGRATION.md +0 -381
- package/monodog-dashboard/src/theme/README.md +0 -239
- package/monodog-dashboard/src/theme/examples.tsx +0 -386
- package/monodog-dashboard/src/theme/index.ts +0 -402
- package/monodog-dashboard/src/theme/migration-guide.md +0 -335
- package/monodog-dashboard/src/types/auth-context.types.ts +0 -51
- package/monodog-dashboard/src/types/component.types.ts +0 -96
- package/monodog-dashboard/src/types/icons.types.ts +0 -13
- package/monodog-dashboard/src/types/index.ts +0 -68
- package/monodog-dashboard/src/types/monorepo-service.types.ts +0 -53
- package/monodog-dashboard/src/types/permission-context.types.ts +0 -49
- package/monodog-dashboard/src/types/pipeline.types.ts +0 -89
- package/monodog-dashboard/src/types/routes.types.ts +0 -12
- package/monodog-dashboard/src/utils/cookies.ts +0 -47
- package/monodog-dashboard/tailwind.config.js +0 -68
- package/monodog-dashboard/tsconfig.app.json +0 -14
- package/monodog-dashboard/tsconfig.json +0 -17
- package/monodog-dashboard/tsconfig.node.json +0 -10
- package/monodog-dashboard/vite.config.ts +0 -9
package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigEditor.tsx
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { ConfigEditorProps } from '../types/config.types';
|
|
2
|
-
import { maskSecrets, detectLanguage } from '../utils/config.utils';
|
|
3
|
-
import { DocumentIcon } from '../../../../icons/heroicons';
|
|
4
|
-
|
|
5
|
-
export default function ConfigEditor({
|
|
6
|
-
config,
|
|
7
|
-
isEditing,
|
|
8
|
-
editValue,
|
|
9
|
-
onStartEdit,
|
|
10
|
-
onSaveEdit,
|
|
11
|
-
onCancelEdit,
|
|
12
|
-
onValueChange,
|
|
13
|
-
showSecrets,
|
|
14
|
-
onToggleSecrets,
|
|
15
|
-
}: ConfigEditorProps) {
|
|
16
|
-
if (!config) {
|
|
17
|
-
return (
|
|
18
|
-
<div className="flex items-center justify-center h-64 bg-gray-50 rounded-lg">
|
|
19
|
-
<div className="text-center">
|
|
20
|
-
<div className="text-gray-400 text-4xl mb-2"><DocumentIcon className="w-6 h-6 text-primary-600" /></div>
|
|
21
|
-
<p className="text-gray-500">
|
|
22
|
-
Select a configuration file to view or edit
|
|
23
|
-
</p>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const language = detectLanguage(config.name);
|
|
30
|
-
const displayContent = showSecrets
|
|
31
|
-
? config.content
|
|
32
|
-
: maskSecrets(config.content);
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className="bg-white rounded-lg shadow border h-full flex flex-col">
|
|
36
|
-
{/* File Header */}
|
|
37
|
-
<div className="p-4 border-b border-gray-200">
|
|
38
|
-
<div className="flex items-center space-x-3">
|
|
39
|
-
<div className="text-2xl"><DocumentIcon className="w-6 h-6 text-primary-600" /></div>
|
|
40
|
-
<div>
|
|
41
|
-
<h3 className="text-lg font-medium text-gray-900">{config.name}</h3>
|
|
42
|
-
<p className="text-sm text-gray-500">{config.path}</p>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
{/* Editor Content */}
|
|
48
|
-
<div className="flex-1 p-4">
|
|
49
|
-
{isEditing ? (
|
|
50
|
-
<div className="h-full">
|
|
51
|
-
<textarea
|
|
52
|
-
value={editValue}
|
|
53
|
-
onChange={e => onValueChange(e.target.value)}
|
|
54
|
-
className="w-full h-full font-mono text-sm border border-gray-300 rounded-lg p-4 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
|
|
55
|
-
placeholder="Enter configuration content..."
|
|
56
|
-
spellCheck={false}
|
|
57
|
-
/>
|
|
58
|
-
</div>
|
|
59
|
-
) : (
|
|
60
|
-
<div className="h-full">
|
|
61
|
-
<pre className="w-full h-full font-mono text-sm bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-auto whitespace-pre-wrap">
|
|
62
|
-
<code className={`language-${language}`}>{displayContent}</code>
|
|
63
|
-
</pre>
|
|
64
|
-
</div>
|
|
65
|
-
)}
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
{/* Editor Footer */}
|
|
69
|
-
<div className="p-4 border-t border-gray-200 bg-gray-50">
|
|
70
|
-
<div className="flex items-center justify-between text-sm text-gray-500">
|
|
71
|
-
<div className="flex items-center space-x-4">
|
|
72
|
-
<span>Language: {language.toUpperCase()}</span>
|
|
73
|
-
<span>Size: {config.content.length} characters</span>
|
|
74
|
-
{config.hasSecrets && (
|
|
75
|
-
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
|
|
76
|
-
🔒 Contains secrets
|
|
77
|
-
</span>
|
|
78
|
-
)}
|
|
79
|
-
</div>
|
|
80
|
-
<div>
|
|
81
|
-
{isEditing ? (
|
|
82
|
-
<span className="text-blue-600 font-medium">Editing mode</span>
|
|
83
|
-
) : config.isEditable ? (
|
|
84
|
-
<span className="text-green-600">Editable</span>
|
|
85
|
-
) : (
|
|
86
|
-
<span className="text-gray-400">Read-only</span>
|
|
87
|
-
)}
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { ArrowPathIcon } from '../../../../icons/heroicons';
|
|
2
|
-
|
|
3
|
-
interface ConfigInspectorHeaderProps {
|
|
4
|
-
onRefresh?: () => void;
|
|
5
|
-
loading?: boolean;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default function ConfigInspectorHeader({
|
|
9
|
-
onRefresh,
|
|
10
|
-
loading = false,
|
|
11
|
-
}: ConfigInspectorHeaderProps) {
|
|
12
|
-
return (
|
|
13
|
-
<div className="flex items-center justify-between">
|
|
14
|
-
<div>
|
|
15
|
-
<h1 className="text-2xl font-bold text-gray-900">
|
|
16
|
-
Configuration Inspector
|
|
17
|
-
</h1>
|
|
18
|
-
<p className="text-gray-600 mt-1">
|
|
19
|
-
View and manage configuration files across your monorepo
|
|
20
|
-
</p>
|
|
21
|
-
</div>
|
|
22
|
-
{onRefresh && (
|
|
23
|
-
<button
|
|
24
|
-
onClick={onRefresh}
|
|
25
|
-
disabled={loading}
|
|
26
|
-
className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-2 transition-colors"
|
|
27
|
-
>
|
|
28
|
-
<ArrowPathIcon
|
|
29
|
-
className={`w-5 h-5 ${loading ? 'animate-spin' : ''}`}
|
|
30
|
-
/>
|
|
31
|
-
<span>Refresh</span>
|
|
32
|
-
</button>
|
|
33
|
-
)}
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
}
|
package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigPreview.tsx
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { EyeIcon, EyeSlashIcon } from '../../../../icons/heroicons';
|
|
2
|
-
import { ConfigPreviewProps } from '../types/config.types';
|
|
3
|
-
import { maskSecrets, formatJson } from '../utils/config.utils';
|
|
4
|
-
|
|
5
|
-
export default function ConfigPreview({
|
|
6
|
-
content,
|
|
7
|
-
language,
|
|
8
|
-
showSecrets,
|
|
9
|
-
onToggleSecrets,
|
|
10
|
-
}: ConfigPreviewProps) {
|
|
11
|
-
const displayContent = showSecrets ? content : maskSecrets(content);
|
|
12
|
-
const formattedContent =
|
|
13
|
-
language === 'json' ? formatJson(displayContent) : displayContent;
|
|
14
|
-
|
|
15
|
-
const getLanguageDisplayName = (lang: string) => {
|
|
16
|
-
const names: Record<string, string> = {
|
|
17
|
-
json: 'JSON',
|
|
18
|
-
yaml: 'YAML',
|
|
19
|
-
javascript: 'JavaScript',
|
|
20
|
-
typescript: 'TypeScript',
|
|
21
|
-
env: 'Environment',
|
|
22
|
-
markdown: 'Markdown',
|
|
23
|
-
xml: 'XML',
|
|
24
|
-
toml: 'TOML',
|
|
25
|
-
text: 'Plain Text',
|
|
26
|
-
};
|
|
27
|
-
return names[lang] || lang.toUpperCase();
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const getSyntaxHighlightClass = (lang: string) => {
|
|
31
|
-
// In a real implementation, you might use a syntax highlighting library
|
|
32
|
-
// like Prism.js or highlight.js
|
|
33
|
-
return `language-${lang}`;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<div className="bg-white rounded-lg shadow border h-full flex flex-col">
|
|
38
|
-
{/* Header */}
|
|
39
|
-
<div className="flex items-center justify-between p-4 border-b border-gray-200 bg-gray-50">
|
|
40
|
-
<div className="flex items-center space-x-2">
|
|
41
|
-
<h3 className="text-sm font-medium text-gray-900">
|
|
42
|
-
{getLanguageDisplayName(language)} Preview
|
|
43
|
-
</h3>
|
|
44
|
-
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800">
|
|
45
|
-
{content.split('\n').length} lines
|
|
46
|
-
</span>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
{onToggleSecrets && (
|
|
50
|
-
<button
|
|
51
|
-
onClick={onToggleSecrets}
|
|
52
|
-
className="inline-flex items-center px-2 py-1 text-xs font-medium text-gray-600 hover:text-gray-800 transition-colors"
|
|
53
|
-
>
|
|
54
|
-
{showSecrets ? (
|
|
55
|
-
<>
|
|
56
|
-
<EyeSlashIcon className="w-3 h-3 mr-1" />
|
|
57
|
-
Hide
|
|
58
|
-
</>
|
|
59
|
-
) : (
|
|
60
|
-
<>
|
|
61
|
-
<EyeIcon className="w-3 h-3 mr-1" />
|
|
62
|
-
Show
|
|
63
|
-
</>
|
|
64
|
-
)}
|
|
65
|
-
</button>
|
|
66
|
-
)}
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
{/* Content */}
|
|
70
|
-
<div className="flex-1 overflow-auto">
|
|
71
|
-
<pre
|
|
72
|
-
className={`h-full p-4 text-sm font-mono bg-gray-50 overflow-auto ${getSyntaxHighlightClass(language)}`}
|
|
73
|
-
>
|
|
74
|
-
<code className="whitespace-pre-wrap break-words">
|
|
75
|
-
{formattedContent}
|
|
76
|
-
</code>
|
|
77
|
-
</pre>
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
{/* Footer */}
|
|
81
|
-
<div className="p-2 border-t border-gray-200 bg-gray-50">
|
|
82
|
-
<div className="flex items-center justify-between text-xs text-gray-500">
|
|
83
|
-
<span>{formattedContent.length} characters</span>
|
|
84
|
-
<span>Read-only preview</span>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
);
|
|
89
|
-
}
|
package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigSidebar.tsx
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { MagnifyingGlassIcon, FunnelIcon } from '../../../../icons/heroicons';
|
|
2
|
-
import { type ConfigSidebarProps } from '../types/config.types';
|
|
3
|
-
import {
|
|
4
|
-
getTypeColor,
|
|
5
|
-
formatFileSize,
|
|
6
|
-
formatDate,
|
|
7
|
-
getConfigIcon,
|
|
8
|
-
getUniqueTypes,
|
|
9
|
-
} from '../utils/config.utils';
|
|
10
|
-
import { FolderIcon } from '../../../../icons/heroicons';
|
|
11
|
-
|
|
12
|
-
export default function ConfigSidebar({
|
|
13
|
-
configs,
|
|
14
|
-
selectedConfig,
|
|
15
|
-
onConfigSelect,
|
|
16
|
-
filters,
|
|
17
|
-
onFiltersChange,
|
|
18
|
-
}: ConfigSidebarProps) {
|
|
19
|
-
const availableTypes = getUniqueTypes(configs);
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div className="bg-white rounded-lg shadow border h-full flex flex-col max-h-[calc(100vh-180px)]">
|
|
23
|
-
{/* Header */}
|
|
24
|
-
<div className="p-4 border-b border-gray-200">
|
|
25
|
-
<h3 className="text-lg font-medium text-gray-900 mb-4">
|
|
26
|
-
Configuration Files
|
|
27
|
-
</h3>
|
|
28
|
-
|
|
29
|
-
{/* Search */}
|
|
30
|
-
<div className="relative mb-4">
|
|
31
|
-
<MagnifyingGlassIcon className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
|
32
|
-
<input
|
|
33
|
-
type="text"
|
|
34
|
-
placeholder="Search config files..."
|
|
35
|
-
value={filters.search}
|
|
36
|
-
onChange={e =>
|
|
37
|
-
onFiltersChange({ ...filters, search: e.target.value })
|
|
38
|
-
}
|
|
39
|
-
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm"
|
|
40
|
-
/>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
{/* Filters */}
|
|
44
|
-
<div className="space-y-3">
|
|
45
|
-
<div className="flex items-center space-x-2">
|
|
46
|
-
<FunnelIcon className="h-4 w-4 text-gray-400" />
|
|
47
|
-
<select
|
|
48
|
-
value={filters.type}
|
|
49
|
-
onChange={e =>
|
|
50
|
-
onFiltersChange({ ...filters, type: e.target.value })
|
|
51
|
-
}
|
|
52
|
-
className="flex-1 border border-gray-300 rounded-md px-3 py-1 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
53
|
-
>
|
|
54
|
-
<option value="all">All Types</option>
|
|
55
|
-
{availableTypes.map(type => (
|
|
56
|
-
<option key={type} value={type}>
|
|
57
|
-
{type.charAt(0).toUpperCase() + type.slice(1)}
|
|
58
|
-
</option>
|
|
59
|
-
))}
|
|
60
|
-
</select>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<select
|
|
64
|
-
value={filters.status}
|
|
65
|
-
onChange={e =>
|
|
66
|
-
onFiltersChange({ ...filters, status: e.target.value })
|
|
67
|
-
}
|
|
68
|
-
className="w-full border border-gray-300 rounded-md px-3 py-1 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
69
|
-
>
|
|
70
|
-
<option value="all">All Files</option>
|
|
71
|
-
<option value="standard">Standard Files</option>
|
|
72
|
-
<option value="secrets">Files with Secrets</option>
|
|
73
|
-
</select>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
{/* File List */}
|
|
78
|
-
<div className="flex-1 overflow-y-auto">
|
|
79
|
-
{configs.length === 0 ? (
|
|
80
|
-
<div className="p-4 text-center text-gray-500">
|
|
81
|
-
<div className="text-4xl mb-2"><FolderIcon className="w-6 h-6 text-primary-600" /></div>
|
|
82
|
-
<p className="text-sm">No configuration files found</p>
|
|
83
|
-
</div>
|
|
84
|
-
) : (
|
|
85
|
-
<div className="p-2">
|
|
86
|
-
{configs.map(config => (
|
|
87
|
-
<button
|
|
88
|
-
key={config.id}
|
|
89
|
-
onClick={() => onConfigSelect(config.id)}
|
|
90
|
-
className={`w-full text-left p-3 rounded-lg mb-2 transition-colors ${
|
|
91
|
-
selectedConfig === config.id
|
|
92
|
-
? 'bg-blue-50 border border-blue-200'
|
|
93
|
-
: 'hover:bg-gray-50 border border-transparent'
|
|
94
|
-
}`}
|
|
95
|
-
>
|
|
96
|
-
<div className="flex items-start space-x-3">
|
|
97
|
-
<div className="text-2xl">{getConfigIcon(config.name)}</div>
|
|
98
|
-
<div className="flex-1 min-w-0">
|
|
99
|
-
<div className="flex items-center space-x-2 mb-1">
|
|
100
|
-
<p className="text-sm font-medium text-gray-900 truncate">
|
|
101
|
-
{config.name}
|
|
102
|
-
</p>
|
|
103
|
-
{config.hasSecrets && (
|
|
104
|
-
<span className="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800">
|
|
105
|
-
🔒
|
|
106
|
-
</span>
|
|
107
|
-
)}
|
|
108
|
-
</div>
|
|
109
|
-
<p className="text-xs text-gray-500 truncate mb-1">
|
|
110
|
-
{config.path}
|
|
111
|
-
</p>
|
|
112
|
-
<div className="flex items-center justify-between">
|
|
113
|
-
<span
|
|
114
|
-
className={`inline-flex px-2 py-0.5 text-xs font-semibold rounded-full ${getTypeColor(config.type)}`}
|
|
115
|
-
>
|
|
116
|
-
{config.type}
|
|
117
|
-
</span>
|
|
118
|
-
<span className="text-xs text-gray-400">
|
|
119
|
-
{formatFileSize(config.size)}
|
|
120
|
-
</span>
|
|
121
|
-
</div>
|
|
122
|
-
<p className="text-xs text-gray-400 mt-1">
|
|
123
|
-
{formatDate(config.lastModified)}
|
|
124
|
-
</p>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
</button>
|
|
128
|
-
))}
|
|
129
|
-
</div>
|
|
130
|
-
)}
|
|
131
|
-
</div>
|
|
132
|
-
|
|
133
|
-
{/* Summary */}
|
|
134
|
-
<div className="p-4 border-t border-gray-200">
|
|
135
|
-
<div className="text-xs text-gray-500">
|
|
136
|
-
{configs.length} file{configs.length !== 1 ? 's' : ''} found
|
|
137
|
-
</div>
|
|
138
|
-
</div>
|
|
139
|
-
</div>
|
|
140
|
-
);
|
|
141
|
-
}
|
package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigToolbar.tsx
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PencilIcon,
|
|
3
|
-
CheckIcon,
|
|
4
|
-
XMarkIcon,
|
|
5
|
-
EyeIcon,
|
|
6
|
-
EyeSlashIcon,
|
|
7
|
-
ArrowPathIcon,
|
|
8
|
-
DocumentDuplicateIcon,
|
|
9
|
-
DocumentCheckIcon,
|
|
10
|
-
} from '../../../../icons/heroicons';
|
|
11
|
-
import { type ConfigToolbarProps } from '../types/config.types';
|
|
12
|
-
import { useState } from 'react';
|
|
13
|
-
|
|
14
|
-
export default function ConfigToolbar({
|
|
15
|
-
isEditing,
|
|
16
|
-
canEdit,
|
|
17
|
-
hasSecrets,
|
|
18
|
-
showSecrets,
|
|
19
|
-
saving,
|
|
20
|
-
onStartEdit,
|
|
21
|
-
onSaveEdit,
|
|
22
|
-
onCancelEdit,
|
|
23
|
-
onToggleSecrets,
|
|
24
|
-
onRefresh,
|
|
25
|
-
content,
|
|
26
|
-
}: ConfigToolbarProps) {
|
|
27
|
-
const [copied, setCopied] = useState(false);
|
|
28
|
-
|
|
29
|
-
// const copyToClipboard = () => {
|
|
30
|
-
// // In a real implementation, this would copy the config content
|
|
31
|
-
// navigator.clipboard.writeText('Config content copied');
|
|
32
|
-
// };
|
|
33
|
-
|
|
34
|
-
const copyToClipboard = async () => {
|
|
35
|
-
try {
|
|
36
|
-
// Use the content prop that's passed from ConfigInspector
|
|
37
|
-
const contentToCopy = content || 'No content available';
|
|
38
|
-
|
|
39
|
-
await navigator.clipboard.writeText(contentToCopy);
|
|
40
|
-
setCopied(true);
|
|
41
|
-
|
|
42
|
-
// Reset the copied state after 2 seconds
|
|
43
|
-
setTimeout(() => {
|
|
44
|
-
setCopied(false);
|
|
45
|
-
}, 4000);
|
|
46
|
-
} catch (err) {
|
|
47
|
-
console.error('Failed to copy to clipboard:', err);
|
|
48
|
-
// Fallback for older browsers
|
|
49
|
-
// const textArea = document.createElement('textarea');
|
|
50
|
-
// textArea.value = content || 'No content available';
|
|
51
|
-
// document.body.appendChild(textArea);
|
|
52
|
-
// textArea.select();
|
|
53
|
-
// document.execCommand('copy');
|
|
54
|
-
// document.body.removeChild(textArea);
|
|
55
|
-
|
|
56
|
-
setCopied(true);
|
|
57
|
-
setTimeout(() => setCopied(false), 2000);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
if (saving) {
|
|
62
|
-
return (
|
|
63
|
-
<div className="flex items-center justify-between p-4 bg-gray-50 border-b border-gray-200">
|
|
64
|
-
<div className="flex items-center space-x-2">
|
|
65
|
-
<div className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-orange-600 bg-white border border-gray-300 rounded-lg">
|
|
66
|
-
<ArrowPathIcon className="w-4 h-4 mr-1 animate-spin" />
|
|
67
|
-
Saving...
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
{/* Keep refresh available even during save */}
|
|
72
|
-
<div className="flex items-center space-x-2">
|
|
73
|
-
<button
|
|
74
|
-
onClick={onRefresh}
|
|
75
|
-
className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
76
|
-
>
|
|
77
|
-
<ArrowPathIcon className="w-4 h-4 mr-1" />
|
|
78
|
-
Refresh
|
|
79
|
-
</button>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<div className="flex items-center justify-between p-4 bg-gray-50 border-b border-gray-200">
|
|
87
|
-
<div className="flex items-center space-x-2">
|
|
88
|
-
{/* Edit Controls */}
|
|
89
|
-
{isEditing ? (
|
|
90
|
-
<>
|
|
91
|
-
<button
|
|
92
|
-
onClick={onSaveEdit}
|
|
93
|
-
className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700 transition-colors"
|
|
94
|
-
>
|
|
95
|
-
<CheckIcon className="w-4 h-4 mr-1" />
|
|
96
|
-
Save
|
|
97
|
-
</button>
|
|
98
|
-
<button
|
|
99
|
-
onClick={onCancelEdit}
|
|
100
|
-
className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
101
|
-
>
|
|
102
|
-
<XMarkIcon className="w-4 h-4 mr-1" />
|
|
103
|
-
Cancel
|
|
104
|
-
</button>
|
|
105
|
-
</>
|
|
106
|
-
) : (
|
|
107
|
-
canEdit && (
|
|
108
|
-
<button
|
|
109
|
-
onClick={onStartEdit}
|
|
110
|
-
className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
111
|
-
>
|
|
112
|
-
<PencilIcon className="w-4 h-4 mr-1" />
|
|
113
|
-
Edit
|
|
114
|
-
</button>
|
|
115
|
-
)
|
|
116
|
-
)}
|
|
117
|
-
|
|
118
|
-
{/* Secret Toggle */}
|
|
119
|
-
{hasSecrets && (
|
|
120
|
-
<button
|
|
121
|
-
onClick={onToggleSecrets}
|
|
122
|
-
className={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
|
|
123
|
-
showSecrets
|
|
124
|
-
? 'text-red-700 bg-red-100 hover:bg-red-200'
|
|
125
|
-
: 'text-yellow-700 bg-yellow-100 hover:bg-yellow-200'
|
|
126
|
-
}`}
|
|
127
|
-
>
|
|
128
|
-
{showSecrets ? (
|
|
129
|
-
<>
|
|
130
|
-
<EyeSlashIcon className="w-4 h-4 mr-1" />
|
|
131
|
-
Hide Secrets
|
|
132
|
-
</>
|
|
133
|
-
) : (
|
|
134
|
-
<>
|
|
135
|
-
<EyeIcon className="w-4 h-4 mr-1" />
|
|
136
|
-
Show Secrets
|
|
137
|
-
</>
|
|
138
|
-
)}
|
|
139
|
-
</button>
|
|
140
|
-
)}
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<div className="flex items-center space-x-2">
|
|
144
|
-
{/* Copy Button */}
|
|
145
|
-
<button
|
|
146
|
-
onClick={copyToClipboard}
|
|
147
|
-
className={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
|
|
148
|
-
copied
|
|
149
|
-
? 'text-green-700 bg-green-100 border border-green-300'
|
|
150
|
-
: 'text-gray-700 bg-white border border-gray-300 hover:bg-gray-50'
|
|
151
|
-
}`}
|
|
152
|
-
>
|
|
153
|
-
{copied ? (
|
|
154
|
-
<>
|
|
155
|
-
<DocumentCheckIcon className="w-4 h-4 mr-1" />
|
|
156
|
-
Copied!
|
|
157
|
-
</>
|
|
158
|
-
) : (
|
|
159
|
-
<>
|
|
160
|
-
<DocumentDuplicateIcon className="w-4 h-4 mr-1" />
|
|
161
|
-
Copy
|
|
162
|
-
</>
|
|
163
|
-
)}
|
|
164
|
-
</button>
|
|
165
|
-
{/* <button
|
|
166
|
-
onClick={copyToClipboard}
|
|
167
|
-
className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
168
|
-
>
|
|
169
|
-
<DocumentDuplicateIcon className="w-4 h-4 mr-1" />
|
|
170
|
-
Copy
|
|
171
|
-
</button> */}
|
|
172
|
-
|
|
173
|
-
{/* Refresh Button */}
|
|
174
|
-
{/* <button
|
|
175
|
-
onClick={onRefresh}
|
|
176
|
-
className="inline-flex items-center px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
177
|
-
>
|
|
178
|
-
<ArrowPathIcon className="w-4 h-4 mr-1" />
|
|
179
|
-
Refresh
|
|
180
|
-
</button> */}
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ExclamationTriangleIcon } from '../../../../icons/heroicons';
|
|
2
|
-
|
|
3
|
-
interface ErrorStateProps {
|
|
4
|
-
error: string;
|
|
5
|
-
onRetry?: () => void;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default function ErrorState({ error, onRetry }: ErrorStateProps) {
|
|
9
|
-
return (
|
|
10
|
-
<div className="flex items-center justify-center h-64">
|
|
11
|
-
<div className="text-center">
|
|
12
|
-
<ExclamationTriangleIcon className="w-12 h-12 text-red-500 mx-auto" />
|
|
13
|
-
<p className="mt-4 text-red-600">{error}</p>
|
|
14
|
-
{onRetry && (
|
|
15
|
-
<button
|
|
16
|
-
onClick={onRetry}
|
|
17
|
-
className="mt-4 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
|
|
18
|
-
>
|
|
19
|
-
Retry
|
|
20
|
-
</button>
|
|
21
|
-
)}
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
);
|
|
25
|
-
}
|
package/monodog-dashboard/src/components/modules/config-inspector/components/LoadingState.tsx
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
interface LoadingStateProps {
|
|
2
|
-
message?: string;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export default function LoadingState({
|
|
6
|
-
message = 'Loading configuration files...',
|
|
7
|
-
}: LoadingStateProps) {
|
|
8
|
-
return (
|
|
9
|
-
<div className="flex items-center justify-center h-64">
|
|
10
|
-
<div className="text-center">
|
|
11
|
-
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto"></div>
|
|
12
|
-
<p className="mt-4 text-gray-600">{message}</p>
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
15
|
-
);
|
|
16
|
-
}
|