+21
-13
@@ -51,6 +51,7 @@ interface GiteaIssueResponse {
|
||||
login?: string;
|
||||
};
|
||||
comments?: number;
|
||||
labels?: GiteaLabelResponse[];
|
||||
}
|
||||
|
||||
interface GiteaIssueCommentResponse {
|
||||
@@ -67,6 +68,7 @@ interface GiteaIssueCommentResponse {
|
||||
interface GiteaLabelResponse {
|
||||
id: number;
|
||||
name: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
interface GiteaAttachmentResponse {
|
||||
@@ -93,6 +95,7 @@ export interface GiteaIssueSummary {
|
||||
updatedAt: string;
|
||||
author: string;
|
||||
comments: number;
|
||||
labels: string[];
|
||||
}
|
||||
|
||||
export interface GiteaIssueAttachment {
|
||||
@@ -143,7 +146,8 @@ function toIssueSummary(issue: GiteaIssueResponse, owner: string, repo: string,
|
||||
createdAt: issue.created_at || "",
|
||||
updatedAt: issue.updated_at || "",
|
||||
author: issue.user?.login || "unknown",
|
||||
comments: issue.comments ?? 0
|
||||
comments: issue.comments ?? 0,
|
||||
labels: issue.labels?.map((label) => label.name).filter(Boolean) ?? []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -245,6 +249,22 @@ export async function updateGiteaIssue(
|
||||
}
|
||||
}
|
||||
|
||||
export async function setGiteaIssueLabels(
|
||||
owner: string,
|
||||
repo: string,
|
||||
issueNumber: number,
|
||||
labelIds: number[]
|
||||
): Promise<void> {
|
||||
const client = createGiteaClient();
|
||||
try {
|
||||
await client.put(`/repos/${owner}/${repo}/issues/${issueNumber}/labels`, {
|
||||
labels: labelIds
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(getGiteaErrorMessage(error, "Could not update the Gitea issue labels."));
|
||||
}
|
||||
}
|
||||
|
||||
export async function getGiteaIssues(
|
||||
owner: string,
|
||||
repo: string,
|
||||
@@ -396,18 +416,6 @@ export async function ensureGiteaLabel(owner: string, repo: string, name: string
|
||||
}
|
||||
}
|
||||
|
||||
export async function addGiteaIssueLabels(
|
||||
owner: string,
|
||||
repo: string,
|
||||
issueNumber: number,
|
||||
labelIds: number[]
|
||||
): Promise<void> {
|
||||
const client = createGiteaClient();
|
||||
await client.post(`/repos/${owner}/${repo}/issues/${issueNumber}/labels`, {
|
||||
labels: labelIds
|
||||
});
|
||||
}
|
||||
|
||||
export async function getReposOrderedByLastCommit(): Promise<GiteaRepoSummary[]> {
|
||||
const client = axios.create({
|
||||
baseURL: getApiBaseUrl(giteaConfig.baseUrl),
|
||||
|
||||
+47
-25
@@ -4,9 +4,11 @@ import {
|
||||
appStore,
|
||||
CHROME_PROFILE_NAME,
|
||||
findKnownUrlForBase,
|
||||
ISSUE_LABEL_OPTIONS,
|
||||
type AgentProfile,
|
||||
type AddUrlMode,
|
||||
type AppView,
|
||||
type IssueLabelOption,
|
||||
type OpenIssue,
|
||||
type OpenIssuesStateFilter,
|
||||
type ScreenshotAttachment
|
||||
@@ -389,6 +391,24 @@ function renderAgentOptions(agents: AgentProfile[], selectedAgentId: string): st
|
||||
.join("");
|
||||
}
|
||||
|
||||
function renderLabelOptions(selectedLabels: IssueLabelOption[], target: "draft" | "edit"): string {
|
||||
return `
|
||||
<fieldset class="label-fieldset">
|
||||
<legend>Labels</legend>
|
||||
<div class="label-option-grid">
|
||||
${ISSUE_LABEL_OPTIONS.map(
|
||||
(label) => `
|
||||
<label class="checkbox-row label-option">
|
||||
<input type="checkbox" value="${escapeHtml(label)}" data-label-target="${target}" ${selectedLabels.includes(label) ? "checked" : ""} />
|
||||
<span>${escapeHtml(label)}</span>
|
||||
</label>
|
||||
`
|
||||
).join("")}
|
||||
</div>
|
||||
</fieldset>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderBodyText(body: string, emptyText: string): string {
|
||||
const trimmed = body.trim();
|
||||
if (!trimmed) {
|
||||
@@ -540,7 +560,6 @@ function renderIssueRows(issues: OpenIssue[], selectedIssueNumber: number | null
|
||||
<span class="issue-state">${escapeHtml(issue.state)}</span>
|
||||
<span class="issue-meta">${formatDate(issue.createdAt)}</span>
|
||||
</button>
|
||||
<button class="secondary-button compact-button" type="button" data-ready-issue="${issue.number}" data-issue-repo="${escapeHtml(issue.repoFullName)}" ${state.isUpdatingIssue ? "disabled" : ""}>Ready</button>
|
||||
<button class="danger-button compact-button" type="button" data-delete-issue="${issue.number}" data-issue-repo="${escapeHtml(issue.repoFullName)}" ${state.isUpdatingIssue ? "disabled" : ""}>Delete</button>
|
||||
</div>
|
||||
`
|
||||
@@ -606,7 +625,11 @@ function renderSelectedIssueDetail(): string {
|
||||
}
|
||||
|
||||
const draft = state.selectedIssueEditDraft;
|
||||
const hasChanges = draft.subject !== detail.issue.title || draft.content !== detail.issue.body;
|
||||
const detailLabels = ISSUE_LABEL_OPTIONS.filter((label) => detail.issue.labels.includes(label));
|
||||
const hasChanges =
|
||||
draft.subject !== detail.issue.title ||
|
||||
draft.content !== detail.issue.body ||
|
||||
draft.labels.join("|") !== detailLabels.join("|");
|
||||
|
||||
return `
|
||||
<article class="item-card issue-detail-card">
|
||||
@@ -629,6 +652,7 @@ function renderSelectedIssueDetail(): string {
|
||||
<span>Content</span>
|
||||
<textarea id="selected-issue-content" rows="8">${escapeHtml(draft.content)}</textarea>
|
||||
</label>
|
||||
${renderLabelOptions(draft.labels, "edit")}
|
||||
<button id="save-selected-issue" class="primary-button" type="button" ${hasChanges && draft.subject.trim() && !state.isUpdatingIssue ? "" : "disabled"}>
|
||||
${state.isUpdatingIssue ? "Saving issue..." : "Save issue"}
|
||||
</button>
|
||||
@@ -741,6 +765,8 @@ function renderAddIssue(): string {
|
||||
</select>
|
||||
</label>
|
||||
|
||||
${renderLabelOptions(draft.labels, "draft")}
|
||||
|
||||
<section class="attachment-section">
|
||||
<div class="attachment-heading">
|
||||
<span>Screenshots</span>
|
||||
@@ -757,11 +783,6 @@ function renderAddIssue(): string {
|
||||
</label>
|
||||
${renderFileList(draft.files, "issue")}
|
||||
|
||||
<label class="checkbox-row">
|
||||
<input id="issue-ready" type="checkbox" ${draft.ready ? "checked" : ""} />
|
||||
<span>Ready</span>
|
||||
</label>
|
||||
|
||||
<button id="create-issue" class="primary-button" type="button" ${draft.subject.trim() && !state.isCreatingIssue ? "" : "disabled"}>
|
||||
${state.isCreatingIssue ? "Creating issue..." : "Create issue"}
|
||||
</button>
|
||||
@@ -893,12 +914,6 @@ function bindViewActions(): void {
|
||||
});
|
||||
});
|
||||
|
||||
viewContent?.querySelector<HTMLInputElement>("#issue-ready")?.addEventListener("change", (event) => {
|
||||
appStore.getState().setIssueDraft({
|
||||
ready: (event.target as HTMLInputElement).checked
|
||||
});
|
||||
});
|
||||
|
||||
viewContent?.querySelector<HTMLInputElement>("#issue-files")?.addEventListener("change", (event) => {
|
||||
const input = event.target as HTMLInputElement;
|
||||
appStore.getState().setIssueFiles(Array.from(input.files ?? []));
|
||||
@@ -947,16 +962,6 @@ function bindViewActions(): void {
|
||||
});
|
||||
});
|
||||
|
||||
viewContent?.querySelectorAll<HTMLButtonElement>("[data-ready-issue]").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const issueNumber = Number(button.dataset.readyIssue);
|
||||
const repoFullName = button.dataset.issueRepo;
|
||||
if (Number.isFinite(issueNumber)) {
|
||||
void appStore.getState().markIssueReady(issueNumber, repoFullName);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
viewContent?.querySelectorAll<HTMLButtonElement>("[data-delete-issue]").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const issueNumber = Number(button.dataset.deleteIssue);
|
||||
@@ -991,6 +996,21 @@ function bindViewActions(): void {
|
||||
void appStore.getState().saveSelectedIssueEdits();
|
||||
});
|
||||
|
||||
viewContent?.querySelectorAll<HTMLInputElement>("[data-label-target]").forEach((input) => {
|
||||
input.addEventListener("change", () => {
|
||||
const target = input.dataset.labelTarget;
|
||||
const labels = Array.from(
|
||||
viewContent.querySelectorAll<HTMLInputElement>(`input[data-label-target='${target}']:checked`)
|
||||
).map((checkedInput) => checkedInput.value as IssueLabelOption);
|
||||
|
||||
if (target === "draft") {
|
||||
appStore.getState().setIssueDraft({ labels });
|
||||
} else if (target === "edit") {
|
||||
appStore.getState().setSelectedIssueEditDraft({ labels });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
viewContent?.querySelectorAll<HTMLButtonElement>("[data-delete-issue-attachment]").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const attachmentId = Number(button.dataset.deleteIssueAttachment);
|
||||
@@ -1221,7 +1241,7 @@ function shouldRenderView(): boolean {
|
||||
}
|
||||
|
||||
return !activeElement.matches(
|
||||
"#issue-subject, #issue-content, #issue-agent, #issue-ready, #selected-issue-subject, #selected-issue-content, #issue-comment-content, #agent-name, #agent-file, #agent-description, #agent-content"
|
||||
"#issue-subject, #issue-content, #issue-agent, #selected-issue-subject, #selected-issue-content, #issue-comment-content, #agent-name, #agent-file, #agent-description, #agent-content, [data-label-target]"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1244,11 +1264,13 @@ function syncFocusedFormControls(): void {
|
||||
}
|
||||
|
||||
if (saveSelectedIssue && state.selectedIssueDetail) {
|
||||
const detailLabels = ISSUE_LABEL_OPTIONS.filter((label) => state.selectedIssueDetail?.issue.labels.includes(label));
|
||||
saveSelectedIssue.disabled =
|
||||
!state.selectedIssueEditDraft.subject.trim() ||
|
||||
state.isUpdatingIssue ||
|
||||
(state.selectedIssueEditDraft.subject === state.selectedIssueDetail.issue.title &&
|
||||
state.selectedIssueEditDraft.content === state.selectedIssueDetail.issue.body);
|
||||
state.selectedIssueEditDraft.content === state.selectedIssueDetail.issue.body &&
|
||||
state.selectedIssueEditDraft.labels.join("|") === detailLabels.join("|"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+58
-51
@@ -1,6 +1,5 @@
|
||||
import { createStore } from "zustand/vanilla";
|
||||
import {
|
||||
addGiteaIssueLabels,
|
||||
createGiteaIssueComment,
|
||||
createGiteaIssue,
|
||||
deleteGiteaIssue,
|
||||
@@ -11,6 +10,7 @@ import {
|
||||
getGiteaIssues,
|
||||
getReposOrderedByLastCommit,
|
||||
giteaConfig,
|
||||
setGiteaIssueLabels,
|
||||
type GiteaIssueAttachment,
|
||||
type GiteaIssueDetail,
|
||||
type GiteaIssueStateFilter,
|
||||
@@ -30,6 +30,17 @@ export type ScreenshotTarget = "issue" | "comment";
|
||||
export type OpenIssuesStateFilter = GiteaIssueStateFilter;
|
||||
|
||||
export const CHROME_PROFILE_NAME = "Silma";
|
||||
export const ISSUE_LABEL_OPTIONS = [
|
||||
"Change Request",
|
||||
"Idea",
|
||||
"Tabitha",
|
||||
"Orson",
|
||||
"Belisarius",
|
||||
"Ozymandias",
|
||||
"Ready"
|
||||
] as const;
|
||||
|
||||
export type IssueLabelOption = (typeof ISSUE_LABEL_OPTIONS)[number];
|
||||
|
||||
export interface AgentProfile {
|
||||
id: string;
|
||||
@@ -107,7 +118,7 @@ interface IssueDraft {
|
||||
subject: string;
|
||||
content: string;
|
||||
agentId: string;
|
||||
ready: boolean;
|
||||
labels: IssueLabelOption[];
|
||||
screenshots: ScreenshotAttachment[];
|
||||
files: File[];
|
||||
}
|
||||
@@ -121,6 +132,7 @@ interface IssueCommentDraft {
|
||||
interface IssueEditDraft {
|
||||
subject: string;
|
||||
content: string;
|
||||
labels: IssueLabelOption[];
|
||||
}
|
||||
|
||||
interface CropArea {
|
||||
@@ -204,7 +216,6 @@ interface AppState {
|
||||
loadOpenIssues: (force?: boolean) => Promise<void>;
|
||||
loadTargetIssues: (force?: boolean) => Promise<void>;
|
||||
loadSelectedIssueDetail: (force?: boolean) => Promise<void>;
|
||||
markIssueReady: (issueNumber: number, repoFullName?: string) => Promise<void>;
|
||||
deleteIssue: (issueNumber: number, repoFullName?: string) => Promise<void>;
|
||||
deleteSelectedIssueAttachment: (attachmentId: number) => Promise<void>;
|
||||
captureIssueCommentScreenshot: () => Promise<void>;
|
||||
@@ -544,6 +555,15 @@ function normalizeAgents(agents: AgentProfile[]): AgentProfile[] {
|
||||
return normalized.length ? normalized : AVAILABLE_AGENTS;
|
||||
}
|
||||
|
||||
function normalizeIssueLabels(labels: string[]): IssueLabelOption[] {
|
||||
return ISSUE_LABEL_OPTIONS.filter((option) => labels.some((label) => label.toLowerCase() === option.toLowerCase()));
|
||||
}
|
||||
|
||||
async function ensureIssueLabels(owner: string, repo: string, labels: IssueLabelOption[]): Promise<number[]> {
|
||||
const ensuredLabels = await Promise.all(labels.map((label) => ensureGiteaLabel(owner, repo, label)));
|
||||
return ensuredLabels.map((label) => label.id);
|
||||
}
|
||||
|
||||
function getAgentById(id: string, agents: AgentProfile[]): AgentProfile {
|
||||
return agents.find((agent) => agent.id === id) ?? agents[0] ?? AVAILABLE_AGENTS[0];
|
||||
}
|
||||
@@ -693,7 +713,7 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
subject: "",
|
||||
content: "",
|
||||
agentId: AVAILABLE_AGENTS[0].id,
|
||||
ready: false,
|
||||
labels: ["Change Request"],
|
||||
screenshots: [],
|
||||
files: []
|
||||
},
|
||||
@@ -718,7 +738,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
selectedIssueDetailNumber: null,
|
||||
selectedIssueEditDraft: {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
},
|
||||
isLoadingData: false,
|
||||
isLoadingTargetIssues: false,
|
||||
@@ -984,7 +1005,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
selectedIssueDetailNumber: null,
|
||||
selectedIssueEditDraft: {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
},
|
||||
issueCommentDraft: {
|
||||
content: "",
|
||||
@@ -1003,7 +1025,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
selectedIssueDetailNumber: null,
|
||||
selectedIssueEditDraft: {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
},
|
||||
issueCommentDraft: {
|
||||
content: "",
|
||||
@@ -1031,11 +1054,13 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
state.selectedIssueDetail
|
||||
? {
|
||||
subject: state.selectedIssueDetail.issue.title,
|
||||
content: state.selectedIssueDetail.issue.body
|
||||
content: state.selectedIssueDetail.issue.body,
|
||||
labels: normalizeIssueLabels(state.selectedIssueDetail.issue.labels)
|
||||
}
|
||||
: {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
},
|
||||
issueCommentDraft: {
|
||||
content: "",
|
||||
@@ -1072,7 +1097,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
selectedIssueDetailNumber: null,
|
||||
selectedIssueEditDraft: {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
}
|
||||
});
|
||||
return;
|
||||
@@ -1148,7 +1174,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
? current.selectedIssueEditDraft
|
||||
: {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
}
|
||||
}));
|
||||
} catch (error) {
|
||||
@@ -1236,7 +1263,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
selectedIssueDetailNumber: issueNumber,
|
||||
selectedIssueEditDraft: {
|
||||
subject: selectedIssueDetail.issue.title,
|
||||
content: selectedIssueDetail.issue.body
|
||||
content: selectedIssueDetail.issue.body,
|
||||
labels: normalizeIssueLabels(selectedIssueDetail.issue.labels)
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -1274,11 +1302,17 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
setStatus(set, `Saving issue #${issueNumber}...`, "neutral", { autoClear: false });
|
||||
|
||||
try {
|
||||
const labelIds = await ensureIssueLabels(target.owner, target.repo, state.selectedIssueEditDraft.labels);
|
||||
const updatedIssue = await updateGiteaIssue(target.owner, target.repo, issueNumber, {
|
||||
title: subject,
|
||||
body: state.selectedIssueEditDraft.content
|
||||
});
|
||||
const updatedOpenIssue = toOpenIssue(updatedIssue, target);
|
||||
await setGiteaIssueLabels(target.owner, target.repo, issueNumber, labelIds);
|
||||
const issueWithLabels = {
|
||||
...updatedIssue,
|
||||
labels: state.selectedIssueEditDraft.labels
|
||||
};
|
||||
const updatedOpenIssue = toOpenIssue(issueWithLabels, target);
|
||||
|
||||
set((current) => ({
|
||||
openIssues: current.openIssues.map((issue) =>
|
||||
@@ -1291,13 +1325,14 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
...current.selectedIssueDetail,
|
||||
issue: {
|
||||
...current.selectedIssueDetail.issue,
|
||||
...updatedIssue
|
||||
...issueWithLabels
|
||||
}
|
||||
}
|
||||
: current.selectedIssueDetail,
|
||||
selectedIssueEditDraft: {
|
||||
subject: updatedIssue.title,
|
||||
content: updatedIssue.body
|
||||
subject: issueWithLabels.title,
|
||||
content: issueWithLabels.body,
|
||||
labels: normalizeIssueLabels(issueWithLabels.labels)
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -1310,31 +1345,6 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
set({ isUpdatingIssue: false });
|
||||
}
|
||||
},
|
||||
markIssueReady: async (issueNumber, repoFullName) => {
|
||||
const target = getIssueTarget(appStore.getState(), repoFullName);
|
||||
|
||||
if (!target) {
|
||||
setStatus(set, "Open a known URL with a linked Gitea repo before updating an issue.", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
set({ isUpdatingIssue: true });
|
||||
setStatus(set, `Applying ready label to issue #${issueNumber}...`, "neutral", { autoClear: false });
|
||||
|
||||
try {
|
||||
const readyLabel = await ensureGiteaLabel(target.owner, target.repo, "ready");
|
||||
await addGiteaIssueLabels(target.owner, target.repo, issueNumber, [readyLabel.id]);
|
||||
await appStore.getState().loadOpenIssues(true);
|
||||
await appStore.getState().loadTargetIssues(true);
|
||||
await appStore.getState().loadSelectedIssueDetail(true);
|
||||
setStatus(set, `Applied ready label to issue #${issueNumber}.`, "success");
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Could not apply the ready label.";
|
||||
setStatus(set, message, "error");
|
||||
} finally {
|
||||
set({ isUpdatingIssue: false });
|
||||
}
|
||||
},
|
||||
deleteIssue: async (issueNumber, repoFullName) => {
|
||||
const target = getIssueTarget(appStore.getState(), repoFullName);
|
||||
|
||||
@@ -1373,7 +1383,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
state.selectedIssueNumber === issueNumber && state.selectedIssueRepoFullName === target.fullName
|
||||
? {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
}
|
||||
: state.selectedIssueEditDraft,
|
||||
issueCommentDraft:
|
||||
@@ -1551,13 +1562,13 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
setStatus(set, "Creating Gitea issue...", "neutral", { autoClear: false });
|
||||
|
||||
try {
|
||||
const changeRequestLabel = await ensureGiteaLabel(target.owner, target.repo, "Change Request", "1d76db");
|
||||
const labelIds = await ensureIssueLabels(target.owner, target.repo, state.issueDraft.labels);
|
||||
const issue = await createGiteaIssue(
|
||||
target.owner,
|
||||
target.repo,
|
||||
subject,
|
||||
buildIssueBody(state, target.knownUrl),
|
||||
[changeRequestLabel.id]
|
||||
labelIds
|
||||
);
|
||||
const agent = getAgentById(state.issueDraft.agentId, state.agents);
|
||||
const uploads = [
|
||||
@@ -1579,17 +1590,12 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
await uploadGiteaIssueAttachment(target.owner, target.repo, issue.number, upload.blob, upload.name);
|
||||
}
|
||||
|
||||
if (state.issueDraft.ready) {
|
||||
const readyLabel = await ensureGiteaLabel(target.owner, target.repo, "ready");
|
||||
await addGiteaIssueLabels(target.owner, target.repo, issue.number, [readyLabel.id]);
|
||||
}
|
||||
|
||||
set({
|
||||
issueDraft: {
|
||||
subject: "",
|
||||
content: "",
|
||||
agentId: appStore.getState().agents[0]?.id ?? AVAILABLE_AGENTS[0].id,
|
||||
ready: false,
|
||||
labels: ["Change Request"],
|
||||
screenshots: [],
|
||||
files: []
|
||||
},
|
||||
@@ -1656,7 +1662,8 @@ export const appStore = createStore<AppState>()((set, get) => ({
|
||||
activeBaseUrl !== currentBaseUrl && get().openIssuesLimitToCurrentRepo
|
||||
? {
|
||||
subject: "",
|
||||
content: ""
|
||||
content: "",
|
||||
labels: []
|
||||
}
|
||||
: get().selectedIssueEditDraft
|
||||
});
|
||||
|
||||
+25
-1
@@ -446,6 +446,30 @@ fieldset {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.label-fieldset {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.label-option-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 3px 7px;
|
||||
}
|
||||
|
||||
.label-option {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.label-option span {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: #334e68;
|
||||
font-size: 11px;
|
||||
font-weight: 750;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.radio-row {
|
||||
display: flex;
|
||||
grid-template-columns: auto 1fr;
|
||||
@@ -512,7 +536,7 @@ input[readonly] {
|
||||
|
||||
.issue-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto auto;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user