Skip to content

Commit 855bbae

Browse files
committed
fix(platform): fold helper copy lines into labels, placeholders and options
Drop the second line of copy under fields, form dialogs, settings rows and page headers across the product routes, and the hint data that fed them. Each line is deleted when it restated its label, baked into the placeholder, label or option when it carried a format, bound or trade-off, or left to the dialog's Setup guide when it was setup steps. Validation moves to error, a locked control's reason to disabledReason, and a preference's explanation into its existing About tooltip. Kept lines carry what nothing else can: one-time secrets, irreversible consequences, security or privacy exposure, and state the viewer cannot otherwise see.
1 parent 9334996 commit 855bbae

91 files changed

Lines changed: 177 additions & 603 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/sim/app/(product)/_components/access-requests/review-modal.tsx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ export function ReviewModal({ organizationId, requestId, onClose }: ReviewModalP
138138
inputMode='numeric'
139139
value={newLimit}
140140
onChange={setNewLimit}
141-
hint='Enter a whole number above the current limit.'
141+
error={
142+
newLimit.trim() && !review.isValidLimit(parsedLimit)
143+
? 'Enter a whole number above the current limit.'
144+
: undefined
145+
}
142146
/>
143147
)}
144148
</>

‎apps/sim/app/(product)/_components/access-requests/review-requests.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export function ReviewRequests({ organizationId }: ReviewRequestsProps) {
5656
label='Allow requests'
5757
description={
5858
settings.allowed
59-
? 'People can send requests for administrators to review.'
59+
? undefined
6060
: 'New requests and approvals are paused. You can still view history and decline pending requests.'
6161
}
6262
>

‎apps/sim/app/(product)/_components/chat/panel/browser-session/page-prompts.tsx‎

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ interface ChoicePromptProps {
130130
fieldLabel: string
131131
placeholder: string
132132
options: readonly { value: string; label: string }[]
133-
hintFor?: (choiceId: string) => string | undefined
134133
/** A refusal the page should remember, offered beside Cancel. */
135134
refuse?: { label: string; onSelect: () => void }
136135
onCancel: () => void
@@ -147,7 +146,6 @@ function ChoicePrompt({
147146
fieldLabel,
148147
placeholder,
149148
options,
150-
hintFor,
151149
refuse,
152150
onCancel,
153151
onChoose,
@@ -191,7 +189,6 @@ function ChoicePrompt({
191189
options={options}
192190
value={choiceId || undefined}
193191
onValueChange={setChoiceId}
194-
hint={choiceId ? hintFor?.(choiceId) : undefined}
195192
/>
196193
</div>
197194
</Modal>
@@ -227,14 +224,8 @@ function ClientCertificatePrompt({ prompt, respond }: PromptModalProps<'client-c
227224
placeholder='Choose a certificate'
228225
options={prompt.certificates.map((certificate) => ({
229226
value: certificate.id,
230-
label: certificate.subject || certificate.id,
227+
label: `${certificate.subject || certificate.id} · ${certificate.issuer || 'Unknown issuer'} · Expires ${formatInstantDate(certificate.expiresAt)}`,
231228
}))}
232-
hintFor={(choiceId) => {
233-
const chosen = prompt.certificates.find((certificate) => certificate.id === choiceId)
234-
return chosen
235-
? `Issued by ${chosen.issuer || 'unknown issuer'} · Expires ${formatInstantDate(chosen.expiresAt)}`
236-
: undefined
237-
}}
238229
refuse={{
239230
label: "Don't send",
240231
onSelect: () => respond({ allowed: false, remember: true }),

‎apps/sim/app/(product)/_components/links-page/link-editor.tsx‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export function LinkEditor({
3636
}: LinkEditorProps) {
3737
const editor = useLinkEditor(organizationId, link, initialName, initialUrl)
3838
const { draft, errors, pending } = editor
39+
const accessReason = editor.canManage
40+
? undefined
41+
: 'Only the creator or an organization admin can change access.'
3942
return (
4043
<Modal
4144
open
@@ -65,7 +68,6 @@ export function LinkEditor({
6568
value={draft.defaultUrl ?? ''}
6669
onChange={(value) => editor.change('defaultUrl', value || null)}
6770
error={errors.defaultUrl}
68-
hint={`Opens when no value fills ${LINK_LIMITS.variable}.`}
6971
/>
7072
)}
7173
<TextField
@@ -87,25 +89,20 @@ export function LinkEditor({
8789
onChange={(value) => editor.change('description', value)}
8890
error={errors.description}
8991
/>
90-
<FieldFrame
91-
label='Access'
92-
hint={
93-
editor.canManage
94-
? undefined
95-
: 'Only the creator or an organization admin can change access.'
96-
}
97-
>
92+
<FieldFrame label='Access'>
9893
<div className={styles.access}>
9994
<Checkbox
10095
label='Hide from the Links page'
10196
checked={draft.unlisted}
10297
disabled={!editor.canManage || pending}
98+
disabledReason={accessReason}
10399
onCheckedChange={(checked) => editor.change('unlisted', checked)}
104100
/>
105101
<Checkbox
106102
label='Only the creator and admins can edit'
107103
checked={draft.restrictEdit}
108104
disabled={!editor.canManage || pending}
105+
disabledReason={accessReason}
109106
onCheckedChange={(checked) => editor.change('restrictEdit', checked)}
110107
/>
111108
</div>

‎apps/sim/app/(product)/_components/oauth-connect-modal/oauth-connect-modal.tsx‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ export function OAuthConnectModal({
112112
value={connect.clientFieldValues[field.id] ?? ''}
113113
onValueChange={(value) => connect.setClientField(field.id, value)}
114114
options={field.options}
115-
hint={field.hint}
116115
/>
117116
) : field.secret ? (
118117
<SecretField
@@ -123,7 +122,6 @@ export function OAuthConnectModal({
123122
placeholder={field.placeholder}
124123
autoComplete='new-password'
125124
required
126-
hint={field.hint}
127125
/>
128126
) : (
129127
<TextField
@@ -134,7 +132,6 @@ export function OAuthConnectModal({
134132
placeholder={field.placeholder}
135133
autoComplete='off'
136134
required
137-
hint={field.hint}
138135
/>
139136
)
140137
)}

‎apps/sim/app/(product)/_components/service-account-modal/service-account-modal.dom.test.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ it('adds a keyless AWS role: shows what to paste into AWS and submits the signed
268268

269269
it('adds AWS access keys: submits only the keys, never a subject, and requires both', async () => {
270270
const dialog = await open('aws-service-account', 'AWS')
271-
await chooseAuthType(dialog, 'Access keys')
271+
await chooseAuthType(dialog, 'Access keys (long-lived)')
272272

273273
expect(labelled(dialog, 'Issuer')).toBeNull()
274274
expect(labelled(dialog, 'Role ARN')).toBeNull()
@@ -287,12 +287,12 @@ it('adds AWS access keys: submits only the keys, never a subject, and requires b
287287

288288
it('drops a secret when the auth type that used it is left', async () => {
289289
const dialog = await open('aws-service-account', 'AWS')
290-
await chooseAuthType(dialog, 'Access keys')
290+
await chooseAuthType(dialog, 'Access keys (long-lived)')
291291
type(input(dialog, 'Access key ID'), 'AKIAEXAMPLEKEY12345')
292292
type(input(dialog, 'Secret access key'), 'first-secret')
293293

294294
await chooseAuthType(dialog, 'IAM role (keyless, via Sim OIDC)')
295-
await chooseAuthType(dialog, 'Access keys')
295+
await chooseAuthType(dialog, 'Access keys (long-lived)')
296296

297297
expect(input(dialog, 'Secret access key').value).toBe('')
298298
expect(input(dialog, 'Access key ID').value).toBe('AKIAEXAMPLEKEY12345')
@@ -322,7 +322,7 @@ it('offers keyless sign-in disabled, with no instructions, where the deployment
322322
keyless = { available: false }
323323
const dialog = await open('aws-service-account', 'AWS')
324324

325-
expect(authTypeTrigger(dialog).textContent).toContain('Access keys')
325+
expect(authTypeTrigger(dialog).textContent).toContain('Access keys (long-lived)')
326326
expect(labelled(dialog, 'Issuer')).toBeNull()
327327
act(() => authTypeTrigger(dialog).click())
328328
await settle()
@@ -336,7 +336,7 @@ it('never offers keyless sign-in to an organization credential, and never mints
336336
scope: { kind: 'organization', organizationId: 'org-1' },
337337
})
338338

339-
expect(authTypeTrigger(dialog).textContent).toContain('Access keys')
339+
expect(authTypeTrigger(dialog).textContent).toContain('Access keys (long-lived)')
340340
expect(requests.some((request) => request.path === '/api/credentials/workload-identity')).toBe(
341341
false
342342
)

‎apps/sim/app/(product)/_components/service-account-modal/service-account-modal.tsx‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,9 @@ function KeyFormModal({
194194
placeholder={field.placeholder}
195195
viewOnly
196196
spellCheck={false}
197-
hint={field.hint}
198197
/>
199198
) : (
200-
<CopyField key={field.id} label={field.label} value={field.value} hint={field.hint} />
199+
<CopyField key={field.id} label={field.label} value={field.value} />
201200
)
202201
) : field.options ? (
203202
<SelectField
@@ -206,7 +205,6 @@ function KeyFormModal({
206205
value={field.value}
207206
onValueChange={(value) => form.setField(field.id, value)}
208207
options={field.options}
209-
hint={field.hint}
210208
error={field.error}
211209
optional={!field.required}
212210
/>
@@ -221,7 +219,7 @@ function KeyFormModal({
221219
spellCheck={false}
222220
required={field.required}
223221
optional={!field.required}
224-
hint={field.hint}
222+
hint={field.formatWarning}
225223
error={field.error}
226224
/>
227225
) : field.secret ? (
@@ -234,7 +232,7 @@ function KeyFormModal({
234232
autoComplete='new-password'
235233
required={field.required}
236234
optional={!field.required}
237-
hint={field.hint}
235+
hint={field.formatWarning}
238236
error={field.error}
239237
/>
240238
) : (
@@ -247,7 +245,7 @@ function KeyFormModal({
247245
autoComplete='off'
248246
required={field.required}
249247
optional={!field.required}
250-
hint={field.hint}
248+
hint={field.formatWarning}
251249
error={field.error}
252250
/>
253251
)
@@ -256,15 +254,15 @@ function KeyFormModal({
256254
label='Display name'
257255
value={form.displayName}
258256
onChange={form.setDisplayName}
259-
placeholder={form.displayNamePlaceholder}
257+
placeholder={`${form.vendorName ?? serviceName} ${form.connectNoun}`}
260258
autoComplete='off'
261259
optional
262260
/>
263261
<TextAreaField
264262
label='Description'
265263
value={form.description}
266264
onChange={form.setDescription}
267-
placeholder='Optional description'
265+
placeholder='What will you use this connection for?'
268266
maxLength={500}
269267
optional
270268
/>

‎apps/sim/app/(product)/_components/settings-parts/saved-settings.tsx‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,31 @@ export function SavedSettingsSection({ title, children }: SavedSettingsSectionPr
2626
interface BooleanRowProps {
2727
setting: Parameters<typeof useBooleanSetting>[0]
2828
label: string
29-
description: string
30-
preview?: 'auto-connect-on-drop' | 'auto-focus-on-click' | 'canvas-error-notification'
29+
/** A clip of the behavior and the one line that explains it, both in the row's About tooltip. */
30+
preview?: {
31+
clip: 'auto-connect-on-drop' | 'auto-focus-on-click' | 'canvas-error-notification'
32+
caption: string
33+
}
3134
}
3235

3336
/** A saved on-or-off preference. */
34-
export function BooleanRow({ setting, label, description, preview }: BooleanRowProps) {
37+
export function BooleanRow({ setting, label, preview }: BooleanRowProps) {
3538
const { checked, disabled, set } = useBooleanSetting(setting)
3639
return (
37-
<SettingsRow label={label} description={description}>
40+
<SettingsRow label={label}>
3841
{preview && (
3942
<Tooltip
40-
label={description}
43+
label={preview.caption}
4144
panel={
4245
<span className={styles.preview} data-material='floating' data-elevation='menu'>
43-
<span data-type='T060'>{description}</span>
46+
<span data-type='T060'>{preview.caption}</span>
4447
<video
4548
aria-label={`${label} example`}
4649
autoPlay
4750
muted
4851
playsInline
49-
loop={preview !== 'canvas-error-notification'}
50-
src={`/tooltips/${preview}.mp4`}
52+
loop={preview.clip !== 'canvas-error-notification'}
53+
src={`/tooltips/${preview.clip}.mp4`}
5154
/>
5255
</span>
5356
}

‎apps/sim/app/(product)/_components/skill-fields/skill-fields.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ interface SkillFieldsProps {
2828
onEdit: (next: SkillDraft, changed: readonly (keyof SkillDraft)[]) => void
2929
viewOnly?: boolean
3030
disabled?: boolean
31-
/** Guidance under the name, such as why the skill cannot be edited. */
32-
nameHint?: string
31+
/** Why a view-only skill cannot be edited, which a read-only field cannot otherwise show. */
32+
readOnlyReason?: string
3333
}
3434

3535
/**
@@ -42,7 +42,7 @@ export function SkillFields({
4242
onEdit,
4343
viewOnly = false,
4444
disabled = false,
45-
nameHint,
45+
readOnlyReason,
4646
}: SkillFieldsProps) {
4747
function editContent(value: string) {
4848
const parsed = parseSkillMarkdown(value)
@@ -58,8 +58,8 @@ export function SkillFields({
5858
<TextField
5959
label='Name'
6060
name='name'
61-
placeholder='Skill name'
62-
hint={nameHint}
61+
placeholder='my-skill'
62+
hint={readOnlyReason}
6363
error={errors.name}
6464
value={draft.name}
6565
onChange={(name) => onEdit({ ...draft, name }, ['name'])}

‎apps/sim/app/(product)/_components/workspace/knowledge/connector-modal/connector-modal.tsx‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,6 @@ function ConnectorDialog({
297297
label: credential.name || credential.provider,
298298
}))}
299299
disabled={busy}
300-
hint={
301-
isSearchIndex
302-
? 'Members sync with their own accounts connected in Integrations.'
303-
: undefined
304-
}
305300
/>
306301
)}
307302
{fields(

0 commit comments

Comments
 (0)