Add open issues status filter
Build / build (push) Successful in 12s

This commit is contained in:
2026-07-18 12:49:15 -05:00
parent 389afb3162
commit c9c2a71dcd
9 changed files with 80 additions and 16 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ Use `.env.local` for local secrets. Keep `.env.local` and any real token-bearing
- Newly created issues must be created with the `Change Request` label. - Newly created issues must be created with the `Change Request` label.
- When creating an issue, upload the selected rendered agent file as an issue asset along with screenshots and files. - When creating an issue, upload the selected rendered agent file as an issue asset along with screenshots and files.
- If the Ready checkbox is checked, create the issue first, upload the rendered agent file plus screenshots/files as issue assets second, and apply the `ready` label last. - If the Ready checkbox is checked, create the issue first, upload the rendered agent file plus screenshots/files as issue assets second, and apply the `ready` label last.
- Open Issues owns issue browsing and follow-up. It must list recent issues ordered by creation time, default to limiting the table to the active URL's linked repo, and provide a checkbox to show issues across all loaded repos. - Open Issues owns issue browsing and follow-up. It must list recent issues ordered by creation time, default to open issues for the active URL's linked repo, provide a checkbox to show issues across all loaded repos, and provide a status dropdown for Open, Closed, or Open + Closed.
- Selecting an Open Issues row must show a direct Open in Gitea link, editable issue subject/content fields, issue attachments, and comment chain, followed by a comment form that can add text, take additional screenshots, attach files, upload those files as issue assets, and submit a Gitea comment with attachment links. - Selecting an Open Issues row must show a direct Open in Gitea link, editable issue subject/content fields, issue attachments, and comment chain, followed by a comment form that can add text, take additional screenshots, attach files, upload those files as issue assets, and submit a Gitea comment with attachment links.
- Existing issue rows must allow applying the `ready` label and deleting the issue. Existing issue attachments must be removable. Deletion must require user confirmation. - Existing issue rows must allow applying the `ready` label and deleting the issue. Existing issue attachments must be removable. Deletion must require user confirmation.
- Text-entry updates in Add Issue, selected issue edits, Open Issues comments, and Agents must not re-render the focused form control or blur the user while they type. - Text-entry updates in Add Issue, selected issue edits, Open Issues comments, and Agents must not re-render the focused form control or blur the user while they type.
+1 -1
View File
@@ -26,7 +26,7 @@ The deployable extension output is `dist/`. Load `dist/` in Chrome as an unpacke
Static assets, including the extension icon assets, live in `public/` and are copied into `dist/` during the build. Static assets, including the extension icon assets, live in `public/` and are copied into `dist/` during the build.
The app opens in the Chrome side panel. The top icon menu includes Add URL, URLs, Gitea repos, Workspaces, Agents, Open Issues, and Add Issue. Add URL is enabled only for an active tab base URL that is not already in the URLs list. URLs can be deleted from the list. The Agents view manages persisted agent files, starting with `GLOBAL AGENT` from `AGENTS.md`; agents can use variables such as `{{git}}`, `{{workspace}}`, and `{{url}}` in their markdown content. Add Issue is enabled when the active tab base URL is already linked to a Gitea repo; it shows the active URL being attached, creates an issue with the selected agent and `Change Request` label, uploads the rendered agent file plus accumulated screenshots and files as issue assets, and can apply the `ready` label after uploads. Captured screenshots can be expanded, removed, or cropped with a wider no-horizontal-scroll crop panel. Open Issues lists recent issues by creation time, defaults to the current repo, can expand to all loaded repos, and lets a selected issue open directly in Gitea, edit subject/content, view attachments and comments, and add a comment with screenshots and file attachments. Rows can be marked Ready or deleted, and existing issue attachments can be deleted. The app opens in the Chrome side panel. The top icon menu includes Add URL, URLs, Gitea repos, Workspaces, Agents, Open Issues, and Add Issue. Add URL is enabled only for an active tab base URL that is not already in the URLs list. URLs can be deleted from the list. The Agents view manages persisted agent files, starting with `GLOBAL AGENT` from `AGENTS.md`; agents can use variables such as `{{git}}`, `{{workspace}}`, and `{{url}}` in their markdown content. Add Issue is enabled when the active tab base URL is already linked to a Gitea repo; it shows the active URL being attached, creates an issue with the selected agent and `Change Request` label, uploads the rendered agent file plus accumulated screenshots and files as issue assets, and can apply the `ready` label after uploads. Captured screenshots can be expanded, removed, or cropped with a wider no-horizontal-scroll crop panel. Open Issues lists recent issues by creation time, defaults to open issues for the current repo, can expand to all loaded repos, can filter Open/Closed/Open + Closed, and lets a selected issue open directly in Gitea, edit subject/content, view attachments and comments, and add a comment with screenshots and file attachments. Rows can be marked Ready or deleted, and existing issue attachments can be deleted.
Builds generate `public/local-context.json` from `/Users/Tabitha/.openclaw/workspace_Father`. That snapshot links known workspaces to local Gitea repos and is copied into `dist/` so the built extension is self-contained. Builds generate `public/local-context.json` from `/Users/Tabitha/.openclaw/workspace_Father`. That snapshot links known workspaces to local Gitea repos and is copied into `dist/` so the built extension is self-contained.
+1
View File
@@ -56,6 +56,7 @@ Required variables:
- The primary Open Issues panel lists recent issues ordered by creation time. - The primary Open Issues panel lists recent issues ordered by creation time.
- The `Only current repo` checkbox defaults to checked and limits the table to the active URL's linked Gitea repo. - The `Only current repo` checkbox defaults to checked and limits the table to the active URL's linked Gitea repo.
- Turning off `Only current repo` loads recent issues from all repos already loaded in the extension. - Turning off `Only current repo` loads recent issues from all repos already loaded in the extension.
- The status dropdown defaults to `Open` and supports `Open`, `Closed`, and `Open + Closed`.
- Selecting an issue shows a direct Open in Gitea link, editable issue subject/content fields, issue attachments, comment chain, and a comment form for text, additional screenshots, and file attachments. - Selecting an issue shows a direct Open in Gitea link, editable issue subject/content fields, issue attachments, comment chain, and a comment form for text, additional screenshots, and file attachments.
- Issue comments should upload screenshots/files as issue assets first, then create a comment containing links to those attachments. - Issue comments should upload screenshots/files as issue assets first, then create a comment containing links to those attachments.
- Existing issue attachments can be deleted from the selected issue. - Existing issue attachments can be deleted from the selected issue.
+1 -1
View File
@@ -19,7 +19,7 @@ Important files:
Build with `npm run build`. The deployable output directory is `dist/`; load that folder in Chrome as an unpacked extension or point deployment tooling at it. Do not edit `dist/` directly. Build with `npm run build`. The deployable output directory is `dist/`; load that folder in Chrome as an unpacked extension or point deployment tooling at it. Do not edit `dist/` directly.
UI behavior: the app renders as a Chrome side panel, not a draggable window. The menu items are Add URL, URLs, Gitea Repos, Workspaces, Agents, Open Issues, and Add Issue. Add URL is enabled only when the active tab base URL is not already known; the user must choose either a workspace or a Gitea repo, and the app infers the linked counterpart. URLs can be deleted from the list; user-added URLs are removed from storage, while generated known URLs are hidden through stored deleted bases. The Agents view manages persisted agent files and starts with `GLOBAL AGENT` backed by `AGENTS.md`; agent markdown can use `{{git}}`, `{{repo}}`, `{{workspace}}`, `{{url}}`, `{{baseUrl}}`, `{{profile}}`, and `{{issue}}` template variables. Add Issue is enabled only when the active tab base URL is known and linked to a Gitea repo. It shows the target repo and active URL, captures visible-tab screenshots with thumbnails, accepts accumulated file attachments, lets the user select an agent file, creates the Gitea issue with the `Change Request` label, uploads the rendered agent file plus all screenshots/files, then applies the `ready` label if requested. Captured screenshots can be expanded, removed, or cropped with a wider no-horizontal-scroll draggable/resizable crop panel. Created issue bodies include `Chrome profile: Silma` and the selected agent. Open Issues lists recent issues by creation time, defaults to the active URL's linked repo through an `Only current repo` checkbox, can load recent issues across all loaded repos, and shows selected issue subject/content edit fields, a direct Open in Gitea link, attachments, comment chains, and a comment form with text, screenshots, and file attachments. Existing issue rows can be marked Ready or deleted after confirmation, and existing issue attachments can be deleted. Text-entry state updates must not blur focused Add Issue, selected issue edit, Open Issues comment, or Agents editor controls. Gitea repos are ordered by latest default-branch commit. Workspace and URL views show established links between local workspaces, known URLs, and Gitea repos. UI behavior: the app renders as a Chrome side panel, not a draggable window. The menu items are Add URL, URLs, Gitea Repos, Workspaces, Agents, Open Issues, and Add Issue. Add URL is enabled only when the active tab base URL is not already known; the user must choose either a workspace or a Gitea repo, and the app infers the linked counterpart. URLs can be deleted from the list; user-added URLs are removed from storage, while generated known URLs are hidden through stored deleted bases. The Agents view manages persisted agent files and starts with `GLOBAL AGENT` backed by `AGENTS.md`; agent markdown can use `{{git}}`, `{{repo}}`, `{{workspace}}`, `{{url}}`, `{{baseUrl}}`, `{{profile}}`, and `{{issue}}` template variables. Add Issue is enabled only when the active tab base URL is known and linked to a Gitea repo. It shows the target repo and active URL, captures visible-tab screenshots with thumbnails, accepts accumulated file attachments, lets the user select an agent file, creates the Gitea issue with the `Change Request` label, uploads the rendered agent file plus all screenshots/files, then applies the `ready` label if requested. Captured screenshots can be expanded, removed, or cropped with a wider no-horizontal-scroll draggable/resizable crop panel. Created issue bodies include `Chrome profile: Silma` and the selected agent. Open Issues lists recent issues by creation time, defaults to open issues for the active URL's linked repo through an `Only current repo` checkbox, can load recent issues across all loaded repos, supports Open/Closed/Open + Closed status filtering, and shows selected issue subject/content edit fields, a direct Open in Gitea link, attachments, comment chains, and a comment form with text, screenshots, and file attachments. Existing issue rows can be marked Ready or deleted after confirmation, and existing issue attachments can be deleted. Text-entry state updates must not blur focused Add Issue, selected issue edit, Open Issues comment, or Agents editor controls. Gitea repos are ordered by latest default-branch commit. Workspace and URL views show established links between local workspaces, known URLs, and Gitea repos.
Extension management rule: use the Codex Chrome extension with the Chrome profile named `Silma`. Do not use `Profile 1`. Extension management rule: use the Codex Chrome extension with the Chrome profile named `Silma`. Do not use `Profile 1`.
+1 -1
View File
@@ -60,7 +60,7 @@
"add_url_behavior": "The user must pick either a workspace or a Gitea repo. The app infers the linked counterpart from local context and stores the URL link in chrome.storage.local.", "add_url_behavior": "The user must pick either a workspace or a Gitea repo. The app infers the linked counterpart from local context and stores the URL link in chrome.storage.local.",
"delete_url_behavior": "URLs can be deleted from the list. User-added URLs are removed from chrome.storage.local; generated known URLs are hidden by storing their base URL in silmaAide.deletedUrlBases.", "delete_url_behavior": "URLs can be deleted from the list. User-added URLs are removed from chrome.storage.local; generated known URLs are hidden by storing their base URL in silmaAide.deletedUrlBases.",
"add_issue_behavior": "The form shows the target repo and active URL for the active known URL, lets the user select an agent file, captures visible-tab screenshots with thumbnails, accepts accumulated file attachments, creates a Gitea issue with the Change Request label, uploads the rendered agent file plus all screenshots/files as issue assets, then applies the ready label after uploads when requested. Captured screenshots can be expanded, removed, or cropped with a wider no-horizontal-scroll draggable/resizable crop panel. Issue bodies include Chrome profile: Silma and the selected agent. The view intentionally omits the redundant Add Issue header copy and keeps the Ready checkbox label short.", "add_issue_behavior": "The form shows the target repo and active URL for the active known URL, lets the user select an agent file, captures visible-tab screenshots with thumbnails, accepts accumulated file attachments, creates a Gitea issue with the Change Request label, uploads the rendered agent file plus all screenshots/files as issue assets, then applies the ready label after uploads when requested. Captured screenshots can be expanded, removed, or cropped with a wider no-horizontal-scroll draggable/resizable crop panel. Issue bodies include Chrome profile: Silma and the selected agent. The view intentionally omits the redundant Add Issue header copy and keeps the Ready checkbox label short.",
"open_issues_behavior": "Open Issues lists recent issues ordered by creation time. The Only current repo checkbox defaults to true and limits rows to the active URL's linked Gitea repo; disabling it loads recent issues from all repos already loaded by the extension.", "open_issues_behavior": "Open Issues lists recent issues ordered by creation time. The Only current repo checkbox defaults to true and limits rows to the active URL's linked Gitea repo; disabling it loads recent issues from all repos already loaded by the extension. The status dropdown defaults to Open and supports Open, Closed, and Open + Closed.",
"issue_comment_behavior": "Open Issues owns existing issue follow-up. Selecting an issue shows a direct Open in Gitea link, editable issue subject/content fields, issue attachments, comment chain, and a comment form that accepts text, screenshots, and file attachments, uploads attachments as issue assets, and submits a Gitea issue comment with attachment links. Existing issue attachments can be deleted. Issue rows can apply the ready label or delete the issue after confirmation. Draft text-entry updates must not blur focused Add Issue, selected issue edit, Open Issues comment, or Agents editor controls.", "issue_comment_behavior": "Open Issues owns existing issue follow-up. Selecting an issue shows a direct Open in Gitea link, editable issue subject/content fields, issue attachments, comment chain, and a comment form that accepts text, screenshots, and file attachments, uploads attachments as issue assets, and submits a Gitea issue comment with attachment links. Existing issue attachments can be deleted. Issue rows can apply the ready label or delete the issue after confirmation. Draft text-entry updates must not blur focused Add Issue, selected issue edit, Open Issues comment, or Agents editor controls.",
"known_urls": [ "known_urls": [
{ {
+4 -2
View File
@@ -131,6 +131,8 @@ export interface GiteaRepoSummary {
lastCommitMessage: string; lastCommitMessage: string;
} }
export type GiteaIssueStateFilter = "open" | "closed" | "all";
function toIssueSummary(issue: GiteaIssueResponse, owner: string, repo: string, issueNumber = issue.number ?? 0): GiteaIssueSummary { function toIssueSummary(issue: GiteaIssueResponse, owner: string, repo: string, issueNumber = issue.number ?? 0): GiteaIssueSummary {
return { return {
number: issue.number ?? issueNumber, number: issue.number ?? issueNumber,
@@ -223,7 +225,7 @@ export async function updateGiteaIssue(
export async function getGiteaIssues( export async function getGiteaIssues(
owner: string, owner: string,
repo: string, repo: string,
options: { limit?: number; sort?: "created" | "updated"; order?: "asc" | "desc" } = {} options: { limit?: number; sort?: "created" | "updated"; order?: "asc" | "desc"; state?: GiteaIssueStateFilter } = {}
): Promise<GiteaIssueSummary[]> { ): Promise<GiteaIssueSummary[]> {
const client = createGiteaClient(); const client = createGiteaClient();
const response = await client.get<GiteaIssueResponse[]>(`/repos/${owner}/${repo}/issues`, { const response = await client.get<GiteaIssueResponse[]>(`/repos/${owner}/${repo}/issues`, {
@@ -232,7 +234,7 @@ export async function getGiteaIssues(
order: options.order ?? "desc", order: options.order ?? "desc",
page: 1, page: 1,
sort: options.sort ?? "created", sort: options.sort ?? "created",
state: "all", state: options.state ?? "all",
type: "issues" type: "issues"
} }
}); });
+15 -2
View File
@@ -8,6 +8,7 @@ import {
type AddUrlMode, type AddUrlMode,
type AppView, type AppView,
type OpenIssue, type OpenIssue,
type OpenIssuesStateFilter,
type ScreenshotAttachment type ScreenshotAttachment
} from "./store"; } from "./store";
import type { GiteaIssueAttachment, GiteaIssueComment, GiteaIssueSummary, GiteaRepoSummary } from "./api"; import type { GiteaIssueAttachment, GiteaIssueComment, GiteaIssueSummary, GiteaRepoSummary } from "./api";
@@ -656,6 +657,14 @@ function renderOpenIssues(): string {
<input id="limit-open-issues" type="checkbox" ${state.openIssuesLimitToCurrentRepo ? "checked" : ""} /> <input id="limit-open-issues" type="checkbox" ${state.openIssuesLimitToCurrentRepo ? "checked" : ""} />
<span>Only current repo</span> <span>Only current repo</span>
</label> </label>
<label class="compact-select-label">
<span>Status</span>
<select id="open-issues-state-filter">
<option value="open"${state.openIssuesStateFilter === "open" ? " selected" : ""}>Open</option>
<option value="closed"${state.openIssuesStateFilter === "closed" ? " selected" : ""}>Closed</option>
<option value="all"${state.openIssuesStateFilter === "all" ? " selected" : ""}>Open + Closed</option>
</select>
</label>
<button id="refresh-target-issues" class="secondary-button compact-button" type="button" ${state.isLoadingTargetIssues ? "disabled" : ""}> <button id="refresh-target-issues" class="secondary-button compact-button" type="button" ${state.isLoadingTargetIssues ? "disabled" : ""}>
${state.isLoadingTargetIssues ? "Loading..." : "Refresh"} ${state.isLoadingTargetIssues ? "Loading..." : "Refresh"}
</button> </button>
@@ -862,6 +871,10 @@ function bindViewActions(): void {
appStore.getState().setOpenIssuesLimit((event.target as HTMLInputElement).checked); appStore.getState().setOpenIssuesLimit((event.target as HTMLInputElement).checked);
}); });
viewContent?.querySelector<HTMLSelectElement>("#open-issues-state-filter")?.addEventListener("change", (event) => {
appStore.getState().setOpenIssuesStateFilter((event.target as HTMLSelectElement).value as OpenIssuesStateFilter);
});
viewContent?.querySelector<HTMLInputElement>("#issue-subject")?.addEventListener("input", (event) => { viewContent?.querySelector<HTMLInputElement>("#issue-subject")?.addEventListener("input", (event) => {
appStore.getState().setIssueDraft({ appStore.getState().setIssueDraft({
subject: (event.target as HTMLInputElement).value subject: (event.target as HTMLInputElement).value
@@ -1253,8 +1266,8 @@ function render(): void {
function ensureOpenIssuesLoaded(): void { function ensureOpenIssuesLoaded(): void {
const state = appStore.getState(); const state = appStore.getState();
const scopeKey = state.openIssuesLimitToCurrentRepo const scopeKey = state.openIssuesLimitToCurrentRepo
? `current:${getActiveKnownUrl()?.giteaRepo?.fullName ?? "none"}` ? `current:${getActiveKnownUrl()?.giteaRepo?.fullName ?? "none"}:${state.openIssuesStateFilter}`
: "all"; : `all-repos:${state.openIssuesStateFilter}`;
if ( if (
state.activeView === "open-issues" && state.activeView === "open-issues" &&
+34 -8
View File
@@ -13,6 +13,7 @@ import {
giteaConfig, giteaConfig,
type GiteaIssueAttachment, type GiteaIssueAttachment,
type GiteaIssueDetail, type GiteaIssueDetail,
type GiteaIssueStateFilter,
type GiteaIssueSummary, type GiteaIssueSummary,
type GiteaRepoSummary, type GiteaRepoSummary,
type GiteaUser, type GiteaUser,
@@ -26,6 +27,7 @@ export type StatusTone = "neutral" | "success" | "error";
export type AppView = "urls" | "repos" | "workspaces" | "agents" | "open-issues" | "add-url" | "add-issue"; export type AppView = "urls" | "repos" | "workspaces" | "agents" | "open-issues" | "add-url" | "add-issue";
export type AddUrlMode = "workspace" | "repo"; export type AddUrlMode = "workspace" | "repo";
export type ScreenshotTarget = "issue" | "comment"; export type ScreenshotTarget = "issue" | "comment";
export type OpenIssuesStateFilter = GiteaIssueStateFilter;
export const CHROME_PROFILE_NAME = "Silma"; export const CHROME_PROFILE_NAME = "Silma";
@@ -154,6 +156,7 @@ interface AppState {
targetIssues: GiteaIssueSummary[]; targetIssues: GiteaIssueSummary[];
openIssues: OpenIssue[]; openIssues: OpenIssue[];
openIssuesLimitToCurrentRepo: boolean; openIssuesLimitToCurrentRepo: boolean;
openIssuesStateFilter: OpenIssuesStateFilter;
openIssuesScopeKey: string; openIssuesScopeKey: string;
issueListRepoFullName: string; issueListRepoFullName: string;
selectedIssueNumber: number | null; selectedIssueNumber: number | null;
@@ -194,6 +197,7 @@ interface AppState {
applyScreenshotCrop: () => Promise<void>; applyScreenshotCrop: () => Promise<void>;
removePreviewScreenshot: () => void; removePreviewScreenshot: () => void;
setOpenIssuesLimit: (limitToCurrentRepo: boolean) => void; setOpenIssuesLimit: (limitToCurrentRepo: boolean) => void;
setOpenIssuesStateFilter: (stateFilter: OpenIssuesStateFilter) => void;
setSelectedIssueEditDraft: (draft: Partial<IssueEditDraft>) => void; setSelectedIssueEditDraft: (draft: Partial<IssueEditDraft>) => void;
saveSelectedIssueEdits: () => Promise<void>; saveSelectedIssueEdits: () => Promise<void>;
selectIssue: (issueNumber: number, repoFullName?: string) => void; selectIssue: (issueNumber: number, repoFullName?: string) => void;
@@ -389,11 +393,8 @@ function getIssueTarget(state: AppState, repoFullName = state.selectedIssueRepoF
} }
function getOpenIssuesScopeKey(state: AppState): string { function getOpenIssuesScopeKey(state: AppState): string {
if (!state.openIssuesLimitToCurrentRepo) { const repoScope = state.openIssuesLimitToCurrentRepo ? `current:${getTargetRepo(state)?.fullName ?? "none"}` : "all-repos";
return "all"; return `${repoScope}:${state.openIssuesStateFilter}`;
}
return `current:${getTargetRepo(state)?.fullName ?? "none"}`;
} }
function toOpenIssue(issue: GiteaIssueSummary, target: RepoTarget): OpenIssue { function toOpenIssue(issue: GiteaIssueSummary, target: RepoTarget): OpenIssue {
@@ -708,6 +709,7 @@ export const appStore = createStore<AppState>()((set, get) => ({
targetIssues: [], targetIssues: [],
openIssues: [], openIssues: [],
openIssuesLimitToCurrentRepo: true, openIssuesLimitToCurrentRepo: true,
openIssuesStateFilter: "open",
openIssuesScopeKey: "", openIssuesScopeKey: "",
issueListRepoFullName: "", issueListRepoFullName: "",
selectedIssueNumber: null, selectedIssueNumber: null,
@@ -990,6 +992,25 @@ export const appStore = createStore<AppState>()((set, get) => ({
files: [] files: []
} }
}), }),
setOpenIssuesStateFilter: (stateFilter) =>
set({
openIssuesStateFilter: stateFilter,
openIssuesScopeKey: "",
openIssues: [],
selectedIssueNumber: null,
selectedIssueRepoFullName: "",
selectedIssueDetail: null,
selectedIssueDetailNumber: null,
selectedIssueEditDraft: {
subject: "",
content: ""
},
issueCommentDraft: {
content: "",
screenshots: [],
files: []
}
}),
selectIssue: (issueNumber, repoFullName) => selectIssue: (issueNumber, repoFullName) =>
set((state) => ({ set((state) => ({
selectedIssueNumber: issueNumber, selectedIssueNumber: issueNumber,
@@ -1059,9 +1080,14 @@ export const appStore = createStore<AppState>()((set, get) => ({
const issueGroups = await Promise.all( const issueGroups = await Promise.all(
targets.map(async (target) => targets.map(async (target) =>
(await getGiteaIssues(target.owner, target.repo, { limit: 25, sort: "created", order: "desc" })).map((issue) => (
toOpenIssue(issue, target) await getGiteaIssues(target.owner, target.repo, {
) limit: 25,
order: "desc",
sort: "created",
state: state.openIssuesStateFilter
})
).map((issue) => toOpenIssue(issue, target))
) )
); );
const openIssues = issueGroups const openIssues = issueGroups
+22
View File
@@ -668,6 +668,28 @@ input[readonly] {
gap: 8px; gap: 8px;
} }
.compact-select-label {
display: flex;
align-items: center;
gap: 5px;
min-width: 0;
}
.compact-select-label span {
color: #52616f;
font-size: 10px;
font-weight: 850;
text-transform: uppercase;
}
.compact-select-label select {
width: auto;
min-width: 104px;
min-height: 26px;
padding: 3px 6px;
font-size: 11px;
}
.target-label, .target-label,
.attachment-heading > span { .attachment-heading > span {
color: #52616f; color: #52616f;