PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / InsightsMenu / InsightsDashboard.tsx

InsightsDashboard.tsx in Code Snippets 4.0.0-beta.2, at js/components/InsightsMenu/InsightsDashboard.tsx

201 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __ } from '@wordpress/i18n'
2 import React, { useState } from 'react'
3 import { REST_BASES } from '../../utils/restAPI'
4 import { SNIPPET_SCOPE_DESCRIPTIONS } from '../../utils/snippets/snippets'
5 import { buildUrl } from '../../utils/urls'
6 import { useRestAPI } from '../../hooks/useRestAPI'
7 import { InsightsChart, TotalsInsightsChart } from './InsightsCharts'
8 import type { InsightChartPreferencesSchema, InsightsChartEntry, InsightsChartViews, InsightsConfigurableChartKey, InsightsSummary } from '../../types/Insights'
9 import type { SnippetCodeScope, SnippetType } from '../../types/Snippet'
10
11 export const DEFAULT_INSIGHTS_CHART_VIEWS: InsightsChartViews = window.CODE_SNIPPETS?.insightsChartViews ?? {
12 type: 'bar',
13 activation: 'pie',
14 conditions: 'pie',
15 location: 'bar',
16 tags: 'bar'
17 }
18
19 export const INSIGHTS_TYPE_COLORS: Readonly<Record<SnippetType, string>> = {
20 php: '#2271b1',
21 html: '#cd4510',
22 css: '#9b59b6',
23 js: '#f7d67a',
24 cond: '#22826f'
25 }
26
27 export const INSIGHTS_ACTIVATION_COLORS: Readonly<Record<string, string>> = {
28 active: '#118822',
29 inactive: '#cd4510'
30 }
31
32 export const INSIGHTS_CONDITION_COLORS: Readonly<Record<string, string>> = {
33 with: '#22826f',
34 without: '#9b59b6'
35 }
36
37 export const INSIGHTS_LOCATION_COLORS: Readonly<Record<SnippetCodeScope, string>> = {
38 'global': '#ff9800',
39 'admin': '#03c7d2',
40 'front-end': '#d46f4d',
41 'single-use': '#00bcd4',
42 'content': '#2271b1',
43 'head-content': '#5865f2',
44 'body-content': '#3b5998',
45 'footer-content': '#9b59b6',
46 'admin-css': '#22826f',
47 'site-css': '#cd4510',
48 'site-head-js': '#f7d67a',
49 'site-footer-js': '#2b71a3'
50 }
51
52 interface StaticChartProps {
53 summary: InsightsSummary
54 }
55
56 interface ConfigurableChartProps<Chart extends InsightsConfigurableChartKey> extends StaticChartProps {
57 view: InsightsChartViews[Chart]
58 setView: (view: InsightsChartViews[Chart]) => void
59 }
60
61 const SnippetTypeChart: React.FC<ConfigurableChartProps<'type'>> = ({ summary, view, setView }) =>
62 <InsightsChart
63 chart="type"
64 title={__('Snippet type', 'code-snippets')}
65 entries={Object.fromEntries(
66 Object.entries(summary.typeCounts).map(([type, entry]) =>
67 [type, { ...entry, url: buildUrl(window.CODE_SNIPPETS?.urls.manage, { subpage: 'snippets', type }) }])
68 )}
69 colors={INSIGHTS_TYPE_COLORS}
70 views={['pie', 'bar']}
71 view={view}
72 setView={setView}
73 />
74
75 const ActivationStatusChart: React.FC<ConfigurableChartProps<'activation'>> = ({ summary, view, setView }) =>
76 <InsightsChart
77 chart="activation"
78 title={__('Activation status', 'code-snippets')}
79 entries={{
80 active: {
81 label: __('Active', 'code-snippets'),
82 count: summary.active,
83 url: buildUrl(window.CODE_SNIPPETS?.urls.manage, { subpage: 'snippets', status: 'active' })
84 },
85 inactive: {
86 label: __('Inactive', 'code-snippets'),
87 count: summary.inactive,
88 url: buildUrl(window.CODE_SNIPPETS?.urls.manage, { subpage: 'snippets', status: 'inactive' })
89 }
90 }}
91 colors={INSIGHTS_ACTIVATION_COLORS}
92 views={['pie', 'bar']}
93 view={view}
94 setView={setView}
95 />
96
97 const ConditionUsageChart: React.FC<ConfigurableChartProps<'conditions'>> = ({ summary, view, setView }) =>
98 <InsightsChart
99 chart="conditions"
100 title={__('Condition usage', 'code-snippets')}
101 entries={summary.conditionCounts}
102 colors={INSIGHTS_CONDITION_COLORS}
103 views={['pie', 'bar']}
104 view={view}
105 setView={setView}
106 />
107
108 const LocationChart = ({ summary, view, setView }: ConfigurableChartProps<'location'>) => {
109 const entries: Record<string, InsightsChartEntry> = Object.fromEntries(
110 Object.entries(summary.locationCounts).map(([scope, count]) =>
111 [scope, { label: SNIPPET_SCOPE_DESCRIPTIONS[scope as SnippetCodeScope], count }])
112 )
113
114 return (
115 <InsightsChart
116 chart="location"
117 title={__('Location', 'code-snippets')}
118 entries={entries}
119 colors={INSIGHTS_LOCATION_COLORS}
120 views={['pie', 'bar']}
121 view={view}
122 setView={setView}
123 />
124 )
125 }
126
127 const TagsChart: React.FC<ConfigurableChartProps<'tags'>> = ({ summary, view, setView }) =>
128 <InsightsChart
129 chart="tags"
130 title={__('Tags', 'code-snippets')}
131 entries={Object.fromEntries(
132 Object.entries(summary.tagCounts).map(([tag, entry]) =>
133 [tag, { ...entry, url: buildUrl(window.CODE_SNIPPETS?.urls.manage, { tag }) }])
134 )}
135 views={['bar', 'cloud']}
136 view={view}
137 setView={setView}
138 />
139
140 export interface InsightsDashboardProps {
141 summary: InsightsSummary
142 }
143
144 export const InsightsDashboard: React.FC<InsightsDashboardProps> = ({ summary }) => {
145 const { api } = useRestAPI()
146 const [chartViews, setChartViews] = useState<InsightsChartViews>(DEFAULT_INSIGHTS_CHART_VIEWS)
147 const updateChartView = <Chart extends InsightsConfigurableChartKey,>(chart: Chart, view: InsightsChartViews[Chart]) => {
148 const views: InsightsChartViews = { ...chartViews, [chart]: view }
149
150 setChartViews(views)
151
152 api.post<InsightChartPreferencesSchema, InsightChartPreferencesSchema>(REST_BASES.preferences.insights, { views })
153 .catch((error: unknown) => {
154 setChartViews(currentViews => currentViews === views ? chartViews : currentViews)
155 console.error(error)
156 })
157 }
158
159 return <>
160 <div className="snippets-page-header">
161 <h1>{__('Insights', 'code-snippets')}</h1>
162 </div>
163
164 <hr className="wp-header-end"></hr>
165
166 <section className="insights-chart-grid">
167 <TotalsInsightsChart chart="total" label={__('Total snippets', 'code-snippets')} count={Number(summary.active) + Number(summary.inactive)} />
168
169 <SnippetTypeChart
170 summary={summary}
171 view={chartViews.type}
172 setView={view => updateChartView('type', view)}
173 />
174
175 <ActivationStatusChart
176 summary={summary}
177 view={chartViews.activation}
178 setView={view => updateChartView('activation', view)}
179 />
180
181 <ConditionUsageChart
182 summary={summary}
183 view={chartViews.conditions}
184 setView={view => updateChartView('conditions', view)}
185 />
186
187 <LocationChart
188 summary={summary}
189 view={chartViews.location}
190 setView={view => updateChartView('location', view)}
191 />
192
193 <TagsChart
194 summary={summary}
195 view={chartViews.tags}
196 setView={view => updateChartView('tags', view)}
197 />
198 </section>
199 </>
200 }
201