Skip to content

Commit 229b9b9

Browse files
authored
Merge pull request #3134 from gitbutlerapp/Commit-box-two-fields
Add summary and description fields. Show tooltip for long summary messages
2 parents 1cdf126 + 180d0ee commit 229b9b9

File tree

8 files changed

+195
-88
lines changed

8 files changed

+195
-88
lines changed

gitbutler-ui/src/lib/components/CommitCard.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import BranchFiles from './BranchFiles.svelte';
33
import Tag from '$lib/components/Tag.svelte';
44
import TimeAgo from '$lib/components/TimeAgo.svelte';
5-
import { projectCurrentCommitMessage } from '$lib/config/config';
5+
import { persistedCommitMessage } from '$lib/config/config';
66
import { draggable } from '$lib/dragging/draggable';
77
import { draggableCommit, nonDraggable } from '$lib/dragging/draggables';
88
import { openExternalUrl } from '$lib/utils/url';
@@ -34,7 +34,7 @@
3434
export let branchId: string | undefined = undefined;
3535
3636
const selectedOwnership = writable(Ownership.default());
37-
const currentCommitMessage = projectCurrentCommitMessage(projectId, branchId || '');
37+
const currentCommitMessage = persistedCommitMessage(projectId, branchId || '');
3838
3939
let showFiles = false;
4040

gitbutler-ui/src/lib/components/CommitDialog.svelte

Lines changed: 163 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import Button from '$lib/components/Button.svelte';
55
import Checkbox from '$lib/components/Checkbox.svelte';
66
import DropDownButton from '$lib/components/DropDownButton.svelte';
7+
import Icon from '$lib/components/Icon.svelte';
78
import ContextMenu from '$lib/components/contextmenu/ContextMenu.svelte';
89
import ContextMenuItem from '$lib/components/contextmenu/ContextMenuItem.svelte';
910
import ContextMenuSection from '$lib/components/contextmenu/ContextMenuSection.svelte';
@@ -12,17 +13,16 @@
1213
projectCommitGenerationExtraConcise,
1314
projectCommitGenerationUseEmojis,
1415
projectRunCommitHooks,
15-
projectCurrentCommitMessage
16+
persistedCommitMessage
1617
} from '$lib/config/config';
1718
import { persisted } from '$lib/persisted/persisted';
1819
import * as toasts from '$lib/utils/toasts';
1920
import { tooltip } from '$lib/utils/tooltip';
20-
import { useAutoHeight } from '$lib/utils/useAutoHeight';
21-
import { invoke } from '@tauri-apps/api/tauri';
21+
import { setAutoHeight } from '$lib/utils/useAutoHeight';
22+
import { useResize } from '$lib/utils/useResize';
2223
import { createEventDispatcher } from 'svelte';
2324
import { quintOut } from 'svelte/easing';
24-
import { get } from 'svelte/store';
25-
import { slide } from 'svelte/transition';
25+
import { fly, slide } from 'svelte/transition';
2626
import type { User, getCloudApiClient } from '$lib/backend/cloud';
2727
import type { BranchController } from '$lib/vbranches/branchController';
2828
import type { Ownership } from '$lib/vbranches/ownership';
@@ -39,49 +39,66 @@
3939
export let cloud: ReturnType<typeof getCloudApiClient>;
4040
export let user: User | undefined;
4141
export let selectedOwnership: Writable<Ownership>;
42+
export const expanded = persisted<boolean>(false, 'commitBoxExpanded_' + branch.id);
4243
4344
const aiGenEnabled = projectAiGenEnabled(projectId);
4445
const runCommitHooks = projectRunCommitHooks(projectId);
45-
const currentCommitMessage = projectCurrentCommitMessage(projectId, branch.id);
46-
export const expanded = persisted<boolean>(false, 'commitBoxExpanded_' + branch.id);
46+
const commitMessage = persistedCommitMessage(projectId, branch.id);
47+
const commitGenerationExtraConcise = projectCommitGenerationExtraConcise(projectId);
48+
const commitGenerationUseEmojis = projectCommitGenerationUseEmojis(projectId);
4749
48-
let commitMessage: string = get(currentCommitMessage) || '';
4950
let isCommitting = false;
50-
let textareaElement: HTMLTextAreaElement;
51-
$: if (textareaElement && commitMessage && expanded) {
52-
textareaElement.style.height = 'auto';
53-
textareaElement.style.height = `${textareaElement.scrollHeight + 2}px`;
51+
let aiLoading = false;
52+
53+
let contextMenu: ContextMenu;
54+
let summarizer: Summarizer | undefined;
55+
56+
let titleTextArea: HTMLTextAreaElement;
57+
let descriptionTextArea: HTMLTextAreaElement;
58+
59+
$: [title, description] = splitMessage($commitMessage);
60+
$: if ($commitMessage) updateHeights();
61+
$: if (user) {
62+
const aiProvider = new ButlerAIProvider(cloud, user);
63+
summarizer = new Summarizer(aiProvider);
5464
}
5565
56-
function focusTextareaOnMount(el: HTMLTextAreaElement) {
57-
if (el) el.focus();
66+
function splitMessage(message: string) {
67+
const parts = message.split(/\n+(.*)/s);
68+
return [parts[0] || '', parts[1] || ''];
5869
}
5970
60-
function commit() {
61-
if (!commitMessage) return;
62-
isCommitting = true;
63-
branchController
64-
.commitBranch(branch.id, commitMessage, $selectedOwnership.toString(), $runCommitHooks)
65-
.then(() => {
66-
commitMessage = '';
67-
currentCommitMessage.set('');
68-
})
69-
.finally(() => (isCommitting = false));
71+
function concatMessage(title: string, description: string) {
72+
return `${title}\n\n${description}`;
7073
}
7174
72-
export function git_get_config(params: { key: string }) {
73-
return invoke<string>('git_get_global_config', params);
75+
function focusTextareaOnMount(el: HTMLTextAreaElement) {
76+
el.focus();
7477
}
7578
76-
let summarizer: Summarizer | undefined;
77-
$: if (user) {
78-
const aiProvider = new ButlerAIProvider(cloud, user);
79+
function updateHeights() {
80+
setAutoHeight(titleTextArea);
81+
setAutoHeight(descriptionTextArea);
82+
}
7983
80-
summarizer = new Summarizer(aiProvider);
84+
async function commit() {
85+
const message = concatMessage(title, description);
86+
isCommitting = true;
87+
try {
88+
await branchController.commitBranch(
89+
branch.id,
90+
message.trim(),
91+
$selectedOwnership.toString(),
92+
$runCommitHooks
93+
);
94+
$commitMessage = '';
95+
} finally {
96+
isCommitting = false;
97+
}
8198
}
8299
83-
let isGeneratingCommitMessage = false;
84100
async function generateCommitMessage(files: LocalFile[]) {
101+
if (!user || !summarizer) return;
85102
const diff = files
86103
.map((f) => f.hunks.filter((h) => $selectedOwnership.containsHunk(f.id, h.id)))
87104
.flat()
@@ -90,9 +107,6 @@
90107
.join('\n')
91108
.slice(0, 5000);
92109
93-
if (!user) return;
94-
if (!summarizer) return;
95-
96110
// Branches get their names generated only if there are at least 4 lines of code
97111
// If the change is a 'one-liner', the branch name is either left as "virtual branch"
98112
// or the user has to manually trigger the name generation from the meatball menu
@@ -101,53 +115,99 @@
101115
dispatch('action', 'generate-branch-name');
102116
}
103117
104-
isGeneratingCommitMessage = true;
105-
summarizer
106-
.commit(diff, $commitGenerationUseEmojis, $commitGenerationExtraConcise)
107-
.then((message) => {
108-
commitMessage = message;
109-
currentCommitMessage.set(message);
110-
111-
setTimeout(() => {
112-
textareaElement.focus();
113-
}, 0);
114-
})
115-
.catch(() => {
116-
toasts.error('Failed to generate commit message');
117-
})
118-
.finally(() => {
119-
isGeneratingCommitMessage = false;
120-
});
121-
}
122-
const commitGenerationExtraConcise = projectCommitGenerationExtraConcise(projectId);
123-
const commitGenerationUseEmojis = projectCommitGenerationUseEmojis(projectId);
118+
aiLoading = true;
119+
try {
120+
$commitMessage = await summarizer.commit(
121+
diff,
122+
$commitGenerationUseEmojis,
123+
$commitGenerationExtraConcise
124+
);
125+
} catch {
126+
toasts.error('Failed to generate commit message');
127+
} finally {
128+
aiLoading = false;
129+
}
124130
125-
let contextMenu: ContextMenu;
131+
setTimeout(() => {
132+
updateHeights();
133+
descriptionTextArea.focus();
134+
}, 0);
135+
}
126136
</script>
127137

128138
<div class="commit-box" class:commit-box__expanded={$expanded}>
129139
{#if $expanded}
130140
<div class="commit-box__expander" transition:slide={{ duration: 150, easing: quintOut }}>
131-
<div class="commit-box__textarea-wrapper">
141+
<div class="commit-box__textarea-wrapper text-input">
132142
<textarea
133-
bind:this={textareaElement}
134-
bind:value={commitMessage}
143+
value={title}
144+
placeholder="Commit summary"
145+
disabled={aiLoading}
146+
class="text-base-body-13 text-semibold commit-box__textarea commit-box__textarea__title"
147+
class:commit-box__textarea_bottom-padding={title.length == 0 && description.length == 0}
148+
spellcheck="false"
149+
rows="1"
150+
bind:this={titleTextArea}
135151
use:focusTextareaOnMount
136-
on:input={useAutoHeight}
137-
on:focus={useAutoHeight}
138-
on:change={() => currentCommitMessage.set(commitMessage)}
152+
use:useResize={() => {
153+
setAutoHeight(titleTextArea);
154+
setAutoHeight(descriptionTextArea);
155+
}}
156+
on:focus={(e) => setAutoHeight(e.currentTarget)}
157+
on:input={(e) => {
158+
$commitMessage = concatMessage(e.currentTarget.value, description);
159+
}}
139160
on:keydown={(e) => {
140-
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
141-
commit();
161+
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') commit();
162+
if (e.key === 'Tab' || e.key === 'Enter') {
163+
e.preventDefault();
164+
descriptionTextArea.focus();
142165
}
143166
}}
144-
spellcheck={false}
145-
class="text-input text-base-body-13 commit-box__textarea"
146-
rows="1"
147-
disabled={isGeneratingCommitMessage}
148-
placeholder="Your commit message here"
149167
/>
150168

169+
{#if title.length > 0}
170+
<textarea
171+
value={description}
172+
disabled={aiLoading}
173+
placeholder="Commit description (optional)"
174+
class="text-base-body-13 commit-box__textarea commit-box__textarea__description"
175+
class:commit-box__textarea_bottom-padding={description.length > 0 || title.length > 0}
176+
spellcheck="false"
177+
rows="1"
178+
bind:this={descriptionTextArea}
179+
on:focus={(e) => setAutoHeight(e.currentTarget)}
180+
on:input={(e) => {
181+
$commitMessage = concatMessage(title, e.currentTarget.value);
182+
}}
183+
on:keydown={(e) => {
184+
const value = e.currentTarget.value;
185+
if (e.key == 'Backspace' && value.length == 0) {
186+
e.preventDefault();
187+
titleTextArea.focus();
188+
setAutoHeight(e.currentTarget);
189+
} else if (e.key == 'a' && (e.metaKey || e.ctrlKey) && value.length == 0) {
190+
// select previous textarea on cmd+a if this textarea is empty
191+
e.preventDefault();
192+
titleTextArea.select();
193+
}
194+
}}
195+
/>
196+
{/if}
197+
198+
{#if title.length > 50}
199+
<div
200+
transition:fly={{ y: 2, duration: 150 }}
201+
class="commit-box__textarea-tooltip"
202+
use:tooltip={{
203+
text: '50 characters or less is best. Extra info can be added in the description.',
204+
delay: 200
205+
}}
206+
>
207+
<Icon name="blitz" />
208+
</div>
209+
{/if}
210+
151211
<div
152212
class="commit-box__texarea-actions"
153213
use:tooltip={$aiGenEnabled && user
@@ -159,7 +219,7 @@
159219
icon="ai-small"
160220
color="neutral"
161221
disabled={!$aiGenEnabled || !user}
162-
loading={isGeneratingCommitMessage}
222+
loading={aiLoading}
163223
on:click={() => generateCommitMessage(branch.files)}
164224
>
165225
Generate message
@@ -203,7 +263,7 @@
203263
color="primary"
204264
kind="filled"
205265
loading={isCommitting}
206-
disabled={(isCommitting || !commitMessage || $selectedOwnership.isEmpty()) && $expanded}
266+
disabled={(isCommitting || !title || $selectedOwnership.isEmpty()) && $expanded}
207267
id="commit-to-branch"
208268
on:click={() => {
209269
if ($expanded) {
@@ -228,27 +288,57 @@
228288
transition: background-color var(--transition-medium);
229289
border-radius: 0 0 var(--radius-m) var(--radius-m);
230290
}
291+
231292
.commit-box__expander {
232293
display: flex;
233294
flex-direction: column;
234295
margin-bottom: var(--space-12);
235296
}
297+
236298
.commit-box__textarea-wrapper {
237299
position: relative;
238300
display: flex;
239301
flex-direction: column;
302+
gap: var(--space-4);
303+
padding: 0;
240304
}
305+
241306
.commit-box__textarea {
242307
overflow: hidden;
243308
display: flex;
244309
flex-direction: column;
245-
246-
padding: var(--space-12) var(--space-12) var(--space-48) var(--space-12);
247310
align-items: flex-end;
248311
gap: var(--space-16);
249-
312+
background: none;
250313
resize: none;
314+
&:focus {
315+
outline: none;
316+
}
251317
}
318+
319+
.commit-box__textarea-tooltip {
320+
position: absolute;
321+
display: flex;
322+
bottom: var(--space-12);
323+
left: var(--space-12);
324+
padding: var(--space-2);
325+
border-radius: 100%;
326+
background: var(--clr-theme-container-pale);
327+
color: var(--clr-theme-scale-ntrl-40);
328+
}
329+
330+
.commit-box__textarea__title {
331+
padding: var(--space-12) var(--space-12) 0 var(--space-12);
332+
}
333+
334+
.commit-box__textarea__description {
335+
padding: 0 var(--space-12) var(--space-12) var(--space-12);
336+
}
337+
338+
.commit-box__textarea_bottom-padding {
339+
padding-bottom: var(--space-48);
340+
}
341+
252342
.commit-box__texarea-actions {
253343
position: absolute;
254344
display: flex;
@@ -262,7 +352,6 @@
262352
gap: var(--space-6);
263353
}
264354
265-
/* modifiers */
266355
.commit-box__expanded {
267356
background-color: var(--clr-theme-container-pale);
268357
}

gitbutler-ui/src/lib/config/config.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ export function projectLaneCollapsed(projectId: string, laneId: string): Persist
5151
return persisted(false, key + projectId + '_' + laneId);
5252
}
5353

54-
export function projectCurrentCommitMessage(
55-
projectId: string,
56-
branchId: string
57-
): Persisted<string> {
58-
const key = 'projectCurrentCommitMessage_';
59-
return persisted('', key + projectId + '_' + branchId);
54+
export function persistedCommitMessage(projectId: string, branchId: string): Persisted<string> {
55+
return persisted('', 'projectCurrentCommitMessage_' + projectId + '_' + branchId);
6056
}

gitbutler-ui/src/lib/icons/icons.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
"info-small": "M8 2.5C4.96244 2.5 2.5 4.96243 2.5 8C2.5 11.0376 4.96243 13.5 8 13.5C11.0376 13.5 13.5 11.0376 13.5 8C13.5 4.96243 11.0376 2.5 8 2.5ZM9 8.57143C9 8.01914 8.55229 7.57143 8 7.57143C7.44772 7.57143 7 8.01914 7 8.57143V10C7 10.5523 7.44772 11 8 11C8.55229 11 9 10.5523 9 10V8.57143ZM9 5.85714C9 5.38376 8.61625 5 8.14286 5H7.85715C7.38376 5 7 5.38376 7 5.85714C7 6.33053 7.38376 6.71429 7.85714 6.71429H8.14286C8.61625 6.71429 9 6.33053 9 5.85714Z",
4141
"instagram": "M1 5C1 2.79086 2.79086 1 5 1H11C13.2091 1 15 2.79086 15 5V11C15 13.2091 13.2091 15 11 15H5C2.79086 15 1 13.2091 1 11V5ZM11 8C11 9.65685 9.65685 11 8 11C6.34315 11 5 9.65685 5 8C5 6.34315 6.34315 5 8 5C9.65685 5 11 6.34315 11 8ZM4 5C4.55228 5 5 4.55228 5 4C5 3.44772 4.55228 3 4 3C3.44772 3 3 3.44772 3 4C3 4.55228 3.44772 5 4 5Z",
4242
"integrations": "M4.96429 2C4.96429 1.0335 5.74779 0.25 6.71429 0.25H7.5C8.4665 0.25 9.25 1.0335 9.25 2V2.78571C9.25 2.92379 9.36193 3.03571 9.5 3.03571H11.2143C12.1808 3.03571 12.9643 3.81922 12.9643 4.78571V6.5C12.9643 6.63807 13.0762 6.75 13.2143 6.75H14C14.9665 6.75 15.75 7.5335 15.75 8.5V9.28571C15.75 10.2522 14.9665 11.0357 14 11.0357H13.2143C13.0762 11.0357 12.9643 11.1476 12.9643 11.2857V13C12.9643 13.9665 12.1808 14.75 11.2143 14.75H9.5C8.5335 14.75 7.75 13.9665 7.75 13V12.2143C7.75 12.0762 7.63807 11.9643 7.5 11.9643H6.71429C6.57621 11.9643 6.46429 12.0762 6.46429 12.2143V13C6.46429 13.9665 5.68078 14.75 4.71429 14.75H3C2.0335 14.75 1.25 13.9665 1.25 13V11.2857C1.25 10.3192 2.0335 9.53571 3 9.53571H3.78571C3.92379 9.53571 4.03571 9.42379 4.03571 9.28571V8.5C4.03571 8.36193 3.92379 8.25 3.78571 8.25H3C2.0335 8.25 1.25 7.4665 1.25 6.5V4.78571C1.25 3.81922 2.0335 3.03571 3 3.03571H4.71429C4.85236 3.03571 4.96429 2.92379 4.96429 2.78571V2ZM6.71429 1.75C6.57621 1.75 6.46429 1.86193 6.46429 2V2.78571C6.46429 3.75221 5.68078 4.53571 4.71429 4.53571H3C2.86193 4.53571 2.75 4.64764 2.75 4.78571V6.5C2.75 6.63807 2.86193 6.75 3 6.75H3.78571C4.75221 6.75 5.53571 7.5335 5.53571 8.5V9.28571C5.53571 10.2522 4.75221 11.0357 3.78571 11.0357H3C2.86193 11.0357 2.75 11.1476 2.75 11.2857V13C2.75 13.1381 2.86193 13.25 3 13.25H4.71429C4.85236 13.25 4.96429 13.1381 4.96429 13V12.2143C4.96429 11.2478 5.74779 10.4643 6.71429 10.4643H7.5C8.4665 10.4643 9.25 11.2478 9.25 12.2143V13C9.25 13.1381 9.36193 13.25 9.5 13.25H11.2143C11.3524 13.25 11.4643 13.1381 11.4643 13V11.2857C11.4643 10.3192 12.2478 9.53571 13.2143 9.53571H14C14.1381 9.53571 14.25 9.42379 14.25 9.28571V8.5C14.25 8.36193 14.1381 8.25 14 8.25H13.2143C12.2478 8.25 11.4643 7.4665 11.4643 6.5V4.78571C11.4643 4.64764 11.3524 4.53571 11.2143 4.53571H9.5C8.5335 4.53571 7.75 3.75221 7.75 2.78571V2C7.75 1.86193 7.63807 1.75 7.5 1.75H6.71429Z",
43+
"idea": "M2.25 5.94187C2.25 3.07448 4.57448 0.75 7.44187 0.75H8.55813C11.4255 0.75 13.75 3.07448 13.75 5.94187C13.75 7.1208 13.3488 8.26463 12.6123 9.18521L11.6201 10.4254C11.4453 10.644 11.35 10.9156 11.35 11.1955V11.9C11.35 13.7502 9.85015 15.25 8 15.25C6.14985 15.25 4.65 13.7502 4.65 11.9V11.1955C4.65 10.9156 4.55474 10.644 4.37988 10.4254L3.3877 9.18521C2.65123 8.26463 2.25 7.1208 2.25 5.94187ZM7.44187 2.25C5.40291 2.25 3.75 3.90291 3.75 5.94187C3.75 6.78019 4.03531 7.59355 4.55901 8.24817L5.55118 9.48839C5.7476 9.73391 5.89871 10.0096 6 10.3026V10.25H7.25V7.81066L5.46967 6.03033L6.53033 4.96967L8 6.43934L9.46967 4.96967L10.5303 6.03033L8.75 7.81066V10.25H10V10.3026C10.1013 10.0096 10.2524 9.73391 10.4488 9.48839L11.441 8.24817C11.9647 7.59355 12.25 6.78019 12.25 5.94187C12.25 3.90291 10.5971 2.25 8.55813 2.25H7.44187ZM6.15 11.9V11.75H9.85V11.9C9.85 12.9217 9.02173 13.75 8 13.75C6.97827 13.75 6.15 12.9217 6.15 11.9Z",
44+
"idea-small": "M3.40384 6.41683C3.40384 4.11555 5.26939 2.25 7.57067 2.25H8.42932C10.7306 2.25 12.5961 4.11555 12.5961 6.41683C12.5961 7.36299 12.2741 8.28099 11.6831 9.01982L10.9199 9.97384C10.8099 10.1113 10.75 10.2821 10.75 10.4581V11C10.75 12.5188 9.51878 13.75 7.99999 13.75C6.48121 13.75 5.24999 12.5188 5.24999 11V10.4581C5.24999 10.2821 5.19009 10.1113 5.08013 9.97384L4.31692 9.01982C3.72585 8.28099 3.40384 7.36299 3.40384 6.41683ZM7.57067 3.75C6.09782 3.75 4.90384 4.94398 4.90384 6.41683C4.90384 7.02239 5.10993 7.60992 5.48822 8.08278L6.25144 9.03679C6.37941 9.19676 6.48428 9.37211 6.56425 9.55769H7.25001V7.92605L5.93121 6.60725L6.99187 5.54659L8 6.55473L9.00814 5.54659L10.0688 6.60725L8.75 7.92605V9.55769H9.43573C9.51571 9.37211 9.62058 9.19676 9.74855 9.03679L10.5118 8.08278C10.8901 7.60992 11.0961 7.02239 11.0961 6.41683C11.0961 4.94398 9.90217 3.75 8.42932 3.75H7.57067ZM7.99999 12.25C7.32897 12.25 6.78145 11.7213 6.7513 11.0577H9.24868C9.21854 11.7213 8.67101 12.25 7.99999 12.25Z",
45+
"blitz": "M7.864 3.6025L5.55525 7.2965C5.15978 7.92925 5.61469 8.75 6.36085 8.75H8.64681L6.864 11.6025L8.136 12.3975L10.4447 8.7035C10.8402 8.07075 10.3853 7.25 9.63915 7.25H7.35319L9.136 4.3975L7.864 3.6025Z M8 0.25C3.71979 0.25 0.25 3.71979 0.25 8C0.25 12.2802 3.71979 15.75 8 15.75C12.2802 15.75 15.75 12.2802 15.75 8C15.75 3.71979 12.2802 0.25 8 0.25ZM1.75 8C1.75 4.54822 4.54822 1.75 8 1.75C11.4518 1.75 14.25 4.54822 14.25 8C14.25 11.4518 11.4518 14.25 8 14.25C4.54822 14.25 1.75 11.4518 1.75 8Z",
46+
"blitz-small": "M8 2.5C4.96243 2.5 2.5 4.96243 2.5 8C2.5 11.0376 4.96243 13.5 8 13.5C11.0376 13.5 13.5 11.0376 13.5 8C13.5 4.96243 11.0376 2.5 8 2.5ZM7.739 4.6025L6.05525 7.2965C5.65979 7.92925 6.11469 8.75 6.86085 8.75L8.14682 8.75L6.989 10.6025L8.261 11.3975L9.94475 8.7035C10.3402 8.07075 9.88532 7.25 9.13915 7.25L7.85319 7.25L9.011 5.3975L7.739 4.6025Z",
4347
"kebab": "M4 8C4 8.82843 3.32843 9.5 2.5 9.5C1.67157 9.5 1 8.82843 1 8C1 7.17157 1.67157 6.5 2.5 6.5C3.32843 6.5 4 7.17157 4 8Z M9.5 8C9.5 8.82843 8.82843 9.5 8 9.5C7.17157 9.5 6.5 8.82843 6.5 8C6.5 7.17157 7.17157 6.5 8 6.5C8.82843 6.5 9.5 7.17157 9.5 8Z M13.5 9.5C14.3284 9.5 15 8.82843 15 8C15 7.17157 14.3284 6.5 13.5 6.5C12.6716 6.5 12 7.17157 12 8C12 8.82843 12.6716 9.5 13.5 9.5Z",
4448
"list-view": "M2 3.25H14V4.75H2V3.25Z M2 7.25H14V8.75H2V7.25Z M14 11.25H2V12.75H14V11.25Z",
4549
"locked": "M8.75 9V12H7.25V9H8.75Z M8 1.25C5.92893 1.25 4.25 2.92893 4.25 5V6.25H4C3.0335 6.25 2.25 7.0335 2.25 8V13C2.25 13.9665 3.0335 14.75 4 14.75H12C12.9665 14.75 13.75 13.9665 13.75 13V8C13.75 7.0335 12.9665 6.25 12 6.25H11.75V5C11.75 2.92893 10.0711 1.25 8 1.25ZM10.25 6.25V5C10.25 3.75736 9.24264 2.75 8 2.75C6.75736 2.75 5.75 3.75736 5.75 5V6.25H10.25ZM3.75 8C3.75 7.86193 3.86193 7.75 4 7.75H12C12.1381 7.75 12.25 7.86193 12.25 8V13C12.25 13.1381 12.1381 13.25 12 13.25H4C3.86193 13.25 3.75 13.1381 3.75 13V8Z",

0 commit comments

Comments
 (0)