mirror of
https://github.com/umami-software/umami.git
synced 2026-02-10 15:47:13 +01:00
Use i18n for board component strings, show controls in edit mode, require website before editing
Some checks are pending
Node.js CI / build (push) Waiting to run
Some checks are pending
Node.js CI / build (push) Waiting to run
- Replace raw strings with useMessages hook in BoardColumn and BoardComponentSelect - Show WebsiteControls on edit screen so users can test filters - Disable board body editing until a website is selected - Scope website select to team websites when editing a team board Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
87bde9da1f
commit
2c7ab2b734
6 changed files with 23 additions and 22 deletions
|
|
@ -255,6 +255,7 @@
|
|||
"select-date": "Select date",
|
||||
"select-filter": "Select filter",
|
||||
"select-role": "Select role",
|
||||
"select-component": "Select component",
|
||||
"select-website": "Select website",
|
||||
"session": "Session",
|
||||
"session-data": "Session data",
|
||||
|
|
@ -371,6 +372,8 @@
|
|||
"reset-website": "To reset this website, type {confirmation} in the box below to confirm.",
|
||||
"reset-website-warning": "All statistics for this website will be deleted, but your settings will remain intact.",
|
||||
"saved": "Saved.",
|
||||
"select-component-preview": "Select a component to preview",
|
||||
"select-website-first": "Select a website first",
|
||||
"sever-error": "Server error",
|
||||
"share-url": "Your website stats are publicly available at the following URL:",
|
||||
"team-already-member": "You are already a member of the team.",
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ export function BoardBody() {
|
|||
});
|
||||
};
|
||||
|
||||
const websiteId = board?.parameters?.websiteId;
|
||||
const canEdit = editing && !!websiteId;
|
||||
const rows = board?.parameters?.rows ?? [];
|
||||
const minHeight = (rows?.length || 1) * MAX_ROW_HEIGHT + BUTTON_ROW_HEIGHT;
|
||||
|
||||
|
|
@ -121,7 +123,7 @@ export function BoardBody() {
|
|||
rowId={row.id}
|
||||
rowIndex={index}
|
||||
rowCount={rows?.length}
|
||||
editing={editing}
|
||||
editing={canEdit}
|
||||
onRemove={handleRemoveRow}
|
||||
onMoveUp={handleMoveRowUp}
|
||||
onMoveDown={handleMoveRowDown}
|
||||
|
|
@ -131,7 +133,7 @@ export function BoardBody() {
|
|||
{index < rows?.length - 1 && <Separator />}
|
||||
</Fragment>
|
||||
))}
|
||||
{editing && (
|
||||
{canEdit && (
|
||||
<Panel minSize={BUTTON_ROW_HEIGHT}>
|
||||
<Row padding="3">
|
||||
<TooltipTrigger delay={0}>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
TooltipTrigger,
|
||||
} from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { useBoard } from '@/components/hooks';
|
||||
import { useBoard, useMessages } from '@/components/hooks';
|
||||
import { Pencil, Plus, X } from '@/components/icons';
|
||||
import type { BoardComponentConfig } from '@/lib/types';
|
||||
import { BoardComponentRenderer } from './BoardComponentRenderer';
|
||||
|
|
@ -32,6 +32,7 @@ export function BoardColumn({
|
|||
}) {
|
||||
const [showSelect, setShowSelect] = useState(false);
|
||||
const { board } = useBoard();
|
||||
const { t, labels } = useMessages();
|
||||
const websiteId = board?.parameters?.websiteId;
|
||||
|
||||
const handleSelect = (config: BoardComponentConfig) => {
|
||||
|
|
@ -91,7 +92,7 @@ export function BoardColumn({
|
|||
)}
|
||||
<Modal isOpen={showSelect} onOpenChange={setShowSelect}>
|
||||
<Dialog
|
||||
title="Add component"
|
||||
title={t(labels.selectComponent)}
|
||||
style={{
|
||||
width: '750px',
|
||||
maxWidth: 'calc(100vw - 40px)',
|
||||
|
|
|
|||
|
|
@ -1,15 +1,6 @@
|
|||
import {
|
||||
Box,
|
||||
Button,
|
||||
Column,
|
||||
Focusable,
|
||||
Heading,
|
||||
ListItem,
|
||||
Row,
|
||||
Select,
|
||||
Text,
|
||||
} from '@umami/react-zen';
|
||||
import { Box, Button, Column, Focusable, ListItem, Row, Select, Text } from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import type { BoardComponentConfig } from '@/lib/types';
|
||||
import {
|
||||
CATEGORIES,
|
||||
|
|
@ -28,6 +19,7 @@ export function BoardComponentSelect({
|
|||
onSelect: (config: BoardComponentConfig) => void;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const { t, labels, messages } = useMessages();
|
||||
const [selectedDef, setSelectedDef] = useState<ComponentDefinition | null>(null);
|
||||
const [configValues, setConfigValues] = useState<Record<string, any>>({});
|
||||
|
||||
|
|
@ -79,13 +71,13 @@ export function BoardComponentSelect({
|
|||
|
||||
return (
|
||||
<Column gap="4">
|
||||
<Row gap="4" style={{ height: 500 }}>
|
||||
<Row gap="4" style={{ height: 600 }}>
|
||||
<Column gap="1" style={{ width: 200, flexShrink: 0, overflowY: 'auto' }}>
|
||||
{CATEGORIES.map(cat => {
|
||||
const components = getComponentsByCategory(cat.key);
|
||||
return (
|
||||
<Column key={cat.key} gap="1" marginBottom="2">
|
||||
<Heading size="md">{cat.name}</Heading>
|
||||
<Text weight="bold">{cat.name}</Text>
|
||||
{components.map(def => (
|
||||
<Focusable key={def.type}>
|
||||
<Row
|
||||
|
|
@ -155,7 +147,7 @@ export function BoardComponentSelect({
|
|||
) : (
|
||||
<Column alignItems="center" justifyContent="center" height="100%">
|
||||
<Text color="muted">
|
||||
{websiteId ? 'Select a component to preview' : 'Select a website first'}
|
||||
{websiteId ? t(messages.selectComponentPreview) : t(messages.selectWebsiteFirst)}
|
||||
</Text>
|
||||
</Column>
|
||||
)}
|
||||
|
|
@ -164,10 +156,10 @@ export function BoardComponentSelect({
|
|||
</Row>
|
||||
<Row justifyContent="flex-end" gap="2" paddingTop="4" border="top">
|
||||
<Button variant="quiet" onPress={onClose}>
|
||||
Cancel
|
||||
{t(labels.cancel)}
|
||||
</Button>
|
||||
<Button variant="primary" onPress={handleAdd} isDisabled={!selectedDef}>
|
||||
Add
|
||||
{t(labels.add)}
|
||||
</Button>
|
||||
</Row>
|
||||
</Column>
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ export function BoardPage({ boardId, editing = false }: { boardId?: string; edit
|
|||
}
|
||||
|
||||
function BoardControls() {
|
||||
const { board, editing } = useBoard();
|
||||
const { board } = useBoard();
|
||||
const websiteId = board?.parameters?.websiteId;
|
||||
|
||||
if (editing || !websiteId) {
|
||||
if (!websiteId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@ export const labels: Record<string, string> = {
|
|||
pixel: 'label.pixel',
|
||||
pixels: 'label.pixels',
|
||||
addBoard: 'label.add-board',
|
||||
selectComponent: 'label.select-component',
|
||||
addLink: 'label.add-link',
|
||||
addPixel: 'label.add-pixel',
|
||||
maximize: 'label.maximize',
|
||||
|
|
@ -367,6 +368,8 @@ export const messages: Record<string, string> = {
|
|||
noResultsFound: 'message.no-results-found',
|
||||
noWebsitesConfigured: 'message.no-websites-configured',
|
||||
noTeamWebsites: 'message.no-team-websites',
|
||||
selectComponentPreview: 'message.select-component-preview',
|
||||
selectWebsiteFirst: 'message.select-website-first',
|
||||
teamWebsitesInfo: 'message.team-websites-info',
|
||||
noMatchPassword: 'message.no-match-password',
|
||||
goToSettings: 'message.go-to-settings',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue