Skip to content

Commit 69f644c

Browse files
committed
Refine UI components and enhance documentation for contents management
1 parent 3c0134b commit 69f644c

6 files changed

Lines changed: 126 additions & 75 deletions

File tree

docs/_static/icons/contents.svg

Lines changed: 3 additions & 0 deletions
Loading

docs/how-to-guides/manage-folder-contents-in-bulk.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Each action works on one or several items at once.
1414

1515
## Open the folder contents view
1616

17-
Navigate to a folder, then select the {guilabel}`Contents` button — the folder icon — in the toolbar.
17+
Navigate to a folder, then select the {guilabel}`Contents` button <img alt="Contents" src="../_static/icons/contents.svg" class="inline"> in the toolbar.
1818
The view lists the items in the folder together with a toolbar of actions.
1919

2020
## Select the items to act on
@@ -34,10 +34,14 @@ Each action applies to the current selection.
3434

3535
The {guilabel}`Short name` is the last segment of the item's URL.
3636

37-
```{warning}
37+
````{warning}
3838
Changing the {guilabel}`Short name` changes the item's URL.
39-
Links and bookmarks that point to the old URL stop working.
39+
Existing links to the old URL no longer resolve unless a redirect is in place.
40+
41+
```{todo}
42+
Replace the above sentence with a reference to the to-be-documented and to-be-created redirect feature in Aurora.
4043
```
44+
````
4145

4246
## Change the workflow state
4347

packages/contents/components/PropertiesModal/PropertiesModal.tsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Heading } from 'react-aria-components';
44
import { useTranslation } from 'react-i18next';
55
import {
66
Button,
7+
Checkbox,
78
DateTimePicker,
89
Dialog,
910
Input,
@@ -170,6 +171,11 @@ export default function PropertiesModal() {
170171
value={values.rights ?? ''}
171172
placeholder={mixedPlaceholder('rights')}
172173
onChange={(e) => setField('rights', e.target.value)}
174+
className={`
175+
rounded-lg border border-quanta-silver bg-quanta-air px-3 py-2
176+
hover:bg-quanta-air
177+
focus:border-quanta-sapphire
178+
`}
173179
/>
174180
</Field>
175181
<Field label={t('contents.modal_properties.creators')}>
@@ -181,21 +187,28 @@ export default function PropertiesModal() {
181187
t('contents.modal_properties.creators_hint')
182188
}
183189
onChange={(e) => setField('creators', e.target.value)}
190+
className={`
191+
rounded-lg border border-quanta-silver bg-quanta-air px-3 py-2
192+
hover:bg-quanta-air
193+
focus:border-quanta-sapphire
194+
`}
184195
/>
185196
</Field>
186-
<label className="flex items-center gap-2 text-sm">
187-
<input
188-
type="checkbox"
189-
checked={!!values.exclude_from_nav}
190-
onChange={(e) => setField('exclude_from_nav', e.target.checked)}
191-
/>
192-
{t('contents.modal_properties.exclude_from_nav')}
193-
{initial.exclude_from_nav.mixed && (
194-
<span className="text-quanta-graphite">
195-
({t('contents.modal_properties.mixed')})
196-
</span>
197-
)}
198-
</label>
197+
<Checkbox
198+
className="text-sm"
199+
isSelected={!!values.exclude_from_nav}
200+
onChange={(checked) => setField('exclude_from_nav', checked)}
201+
>
202+
<span className="relative top-px leading-5">
203+
{t('contents.modal_properties.exclude_from_nav')}
204+
{initial.exclude_from_nav.mixed && (
205+
<span className="text-quanta-graphite">
206+
{' '}
207+
({t('contents.modal_properties.mixed')})
208+
</span>
209+
)}
210+
</span>
211+
</Checkbox>
199212

200213
<div className="mt-4 flex justify-center gap-3">
201214
<Button

packages/contents/components/RenameModal/RenameModal.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export default function RenameModal() {
101101
<div className="mx-auto max-w-2xl">
102102
<table className="mb-6 w-full border-collapse text-sm">
103103
<thead>
104-
<tr className="text-quanta-graphite border-b border-quanta-silver text-left">
104+
<tr className="text-quanta-graphite text-left">
105105
<th className="pb-2 font-normal">
106106
{t('contents.modal_rename.columns.name')}
107107
</th>
@@ -112,13 +112,18 @@ export default function RenameModal() {
112112
</thead>
113113
<tbody>
114114
{rows.map((row, index) => (
115-
<tr key={row['@id']} className="border-b border-quanta-silver">
115+
<tr key={row['@id']}>
116116
<td className="py-3 pe-3">
117117
<Input
118118
type="text"
119119
value={row.id}
120120
onChange={(e) => updateRow(index, 'id', e.target.value)}
121121
aria-label={`${t('contents.modal_rename.columns.name')}: ${row.originalId}`}
122+
className={`
123+
w-full rounded-lg border border-quanta-silver bg-quanta-air px-3 py-2
124+
hover:bg-quanta-air
125+
focus:border-quanta-sapphire
126+
`}
122127
/>
123128
</td>
124129
<td className="py-3">
@@ -129,6 +134,11 @@ export default function RenameModal() {
129134
updateRow(index, 'title', e.target.value)
130135
}
131136
aria-label={`${t('contents.modal_rename.columns.title')}: ${row.originalTitle}`}
137+
className={`
138+
w-full rounded-lg border border-quanta-silver bg-quanta-air px-3 py-2
139+
hover:bg-quanta-air
140+
focus:border-quanta-sapphire
141+
`}
132142
/>
133143
</td>
134144
</tr>

packages/contents/components/TagsModal/TagsModal.tsx

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { useEffect, useMemo, useState } from 'react';
22
import { useFetcher, useRevalidator, type SubmitTarget } from 'react-router';
33
import { Heading } from 'react-aria-components';
44
import { useTranslation } from 'react-i18next';
5-
import { Button, Dialog, Input, Modal } from '@plone/components/quanta';
6-
import { CloseIcon, TagIcon } from '@plone/components/Icons';
5+
import { Button, Dialog, Modal } from '@plone/components/quanta';
6+
import { CloseIcon, TagIcon, ChevrondownIcon } from '@plone/components/Icons';
77
import { type ToastItem } from '@plone/layout/config/toast';
88
import { useContentsContext } from '../../providers/contents';
99
import { buildTagsPayload, unionSubjects } from '../../helpers/tags';
@@ -114,12 +114,7 @@ export default function TagsModal() {
114114
<span className="mb-2 block text-sm font-bold">
115115
{t('contents.modal_tags.current_label')}
116116
</span>
117-
<div
118-
className={`
119-
mb-5 flex min-h-12 flex-wrap items-center gap-2 rounded-lg border border-quanta-silver
120-
bg-quanta-snow p-2
121-
`}
122-
>
117+
<div className="mb-5 flex min-h-8 flex-wrap items-center gap-2">
123118
{visibleExisting.map((tag) => (
124119
<TagChip
125120
key={`e-${tag}`}
@@ -145,21 +140,40 @@ export default function TagsModal() {
145140
<label className="mb-1 block text-sm font-bold" htmlFor="tags-add">
146141
{t('contents.modal_tags.add_label')}
147142
</label>
148-
<Input
149-
id="tags-add"
150-
type="text"
151-
list="tags-vocabulary"
152-
value={input}
153-
placeholder={t('contents.modal_tags.add_placeholder')}
154-
onChange={(e) => setInput(e.target.value)}
155-
onKeyDown={(e) => {
156-
if (e.key === 'Enter') {
157-
e.preventDefault();
158-
addTag(input);
159-
}
160-
}}
161-
aria-label={t('contents.modal_tags.add_label')}
162-
/>
143+
<div
144+
className={`
145+
flex items-center gap-2 rounded-lg border border-quanta-silver bg-quanta-air pe-3
146+
transition-colors
147+
focus-within:border-quanta-sapphire
148+
`}
149+
>
150+
<input
151+
id="tags-add"
152+
type="text"
153+
list="tags-vocabulary"
154+
value={input}
155+
placeholder={t('contents.modal_tags.add_placeholder')}
156+
onChange={(e) => setInput(e.target.value)}
157+
onKeyDown={(e) => {
158+
if (e.key === 'Enter') {
159+
e.preventDefault();
160+
addTag(input);
161+
}
162+
}}
163+
aria-label={t('contents.modal_tags.add_label')}
164+
className={`
165+
min-w-0 flex-1 appearance-none bg-transparent py-2 ps-3 text-sm outline-0
166+
placeholder:text-quanta-pigeon
167+
[&::-webkit-calendar-picker-indicator]:hidden!
168+
[&::-webkit-calendar-picker-indicator]:appearance-none
169+
`}
170+
/>
171+
<ChevrondownIcon
172+
aria-hidden
173+
size="base"
174+
className="pointer-events-none shrink-0 text-quanta-pigeon"
175+
/>
176+
</div>
163177
<p className="text-quanta-graphite mt-1 text-xs">
164178
{t('contents.modal_tags.add_hint')}
165179
</p>
@@ -209,7 +223,8 @@ function TagChip({
209223
<span
210224
className={`
211225
inline-flex items-center gap-1 rounded-full py-1 ps-3 pe-1 text-sm font-medium
212-
${added ? 'bg-quanta-tiffany text-quanta-puya' : 'bg-quanta-azure text-quanta-puya'}
226+
text-quanta-space
227+
${added ? 'bg-quanta-tiffany' : 'bg-quanta-azure'}
213228
`}
214229
>
215230
{label}
@@ -218,13 +233,12 @@ function TagChip({
218233
onClick={onRemove}
219234
aria-label={t('contents.modal_tags.remove', { tag: label })}
220235
className={`
221-
flex h-5 w-5 items-center justify-center rounded-full text-lg leading-none opacity-60
222-
transition-colors
223-
hover:bg-black/10 hover:opacity-100
236+
flex h-5 w-5 items-center justify-center rounded-full transition-colors
237+
hover:bg-black/10
224238
focus-visible:outline-2 focus-visible:outline-quanta-sapphire
225239
`}
226240
>
227-
<span aria-hidden="true">×</span>
241+
<CloseIcon aria-hidden className="h-3 w-3" />
228242
</button>
229243
</span>
230244
);

packages/contents/components/WorkflowModal/WorkflowModal.tsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import { useEffect, useMemo, useState } from 'react';
22
import { useFetcher, useRevalidator } from 'react-router';
33
import { Heading } from 'react-aria-components';
44
import { useTranslation } from 'react-i18next';
5-
import { Button, Dialog, Input, Modal } from '@plone/components/quanta';
5+
import {
6+
Button,
7+
Checkbox,
8+
Dialog,
9+
Input,
10+
Modal,
11+
Select,
12+
} from '@plone/components/quanta';
613
import { CloseIcon, StateIcon } from '@plone/components/Icons';
714
import { type ToastItem } from '@plone/layout/config/toast';
815
import { useContentsContext } from '../../providers/contents';
@@ -114,32 +121,26 @@ export default function WorkflowModal() {
114121
</p>
115122
)}
116123

117-
<label className="grid gap-1 text-sm">
118-
<span className="font-bold">
119-
{t('contents.modal_workflow.transition')}
120-
</span>
121-
<select
122-
className="rounded border border-quanta-silver p-2"
123-
value={transition}
124-
onChange={(e) => setTransition(e.target.value)}
124+
<div className="grid gap-1 text-sm">
125+
<Select
126+
label={t('contents.modal_workflow.transition')}
127+
labelClassnames="font-bold"
125128
aria-label={t('contents.modal_workflow.transition')}
126-
disabled={loadingTransitions}
127-
>
128-
<option value="">
129-
{t('contents.modal_workflow.select_transition')}
130-
</option>
131-
{transitions.map((tr) => (
132-
<option key={tr.id} value={tr.id}>
133-
{tr.title}
134-
</option>
135-
))}
136-
</select>
129+
items={transitions.map((tr) => ({
130+
label: tr.title,
131+
value: tr.id,
132+
}))}
133+
selectedKey={transition || null}
134+
onSelectionChange={(key) => setTransition(String(key))}
135+
placeholder={t('contents.modal_workflow.select_transition')}
136+
isDisabled={loadingTransitions}
137+
/>
137138
{!loadingTransitions && transitions.length === 0 && (
138139
<span className="text-quanta-candy">
139140
{t('contents.modal_workflow.no_common_transitions')}
140141
</span>
141142
)}
142-
</label>
143+
</div>
143144

144145
<label className="grid gap-1 text-sm">
145146
<span className="font-bold">
@@ -150,17 +151,23 @@ export default function WorkflowModal() {
150151
value={comment}
151152
onChange={(e) => setComment(e.target.value)}
152153
aria-label={t('contents.modal_workflow.comment')}
154+
className={`
155+
rounded-lg border border-quanta-silver bg-quanta-air px-3 py-2
156+
hover:bg-quanta-air
157+
focus:border-quanta-sapphire
158+
`}
153159
/>
154160
</label>
155161

156-
<label className="flex items-center gap-2 text-sm">
157-
<input
158-
type="checkbox"
159-
checked={includeChildren}
160-
onChange={(e) => setIncludeChildren(e.target.checked)}
161-
/>
162-
{t('contents.modal_workflow.include_children')}
163-
</label>
162+
<Checkbox
163+
className="text-sm"
164+
isSelected={includeChildren}
165+
onChange={setIncludeChildren}
166+
>
167+
<span className="relative top-px leading-5">
168+
{t('contents.modal_workflow.include_children')}
169+
</span>
170+
</Checkbox>
164171

165172
<div className="mt-4 flex justify-center gap-3">
166173
<Button

0 commit comments

Comments
 (0)