Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fbc057a
feat: implemented view page, filters and display
nazarli-shabnam Mar 15, 2026
2d909f1
feat: send current display + filters navigate to new view after create
nazarli-shabnam Mar 15, 2026
7186fe8
WorkspaceViewsPage: apply saved view filters/display when viewId present
nazarli-shabnam Mar 15, 2026
6941fb8
feat: making icon components accept and forward className
nazarli-shabnam Mar 15, 2026
9a469d1
Adding sort params and implementing static view filters, sorting, and…
nazarli-shabnam Mar 15, 2026
4de584f
Implementing static view filters, sorting, and layout rendering in Wo…
nazarli-shabnam Mar 15, 2026
525728e
Sidebar Views link should go to /views/all-issues (the table view), n…
nazarli-shabnam Mar 15, 2026
0318466
fix: lint errors. again
nazarli-shabnam Mar 15, 2026
012777e
fix: Add an explicit check so ts can narrow the type
nazarli-shabnam Mar 15, 2026
cf9c819
lowercase tokens in parseList for consistency
nazarli-shabnam Mar 15, 2026
c287611
stabilize the location.pathname dependency in the view-apply effect
nazarli-shabnam Mar 15, 2026
56065dc
ref: copilot warnings fix
nazarli-shabnam Mar 15, 2026
9f5dd06
[FIX] Remove new work item button
martian56 Mar 15, 2026
4273a61
[FIX] Make table horizontally scrollable
martian56 Mar 15, 2026
d58f198
[FIX] Fix user avatar on asignees column
martian56 Mar 15, 2026
6de1e83
[FIX] Fix Filters modal avatar issue
martian56 Mar 15, 2026
5d53b60
[FIX] Add better default placeholders to columns
martian56 Mar 15, 2026
9aa096d
[FIX] Implement Filters & Display button on Create View modal
martian56 Mar 15, 2026
aee145a
[FIX] Fix lint and build errors
martian56 Mar 15, 2026
accff93
[FIX] Update UI version
martian56 Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 56 additions & 2 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Devlane UI",
"private": true,
"version": "0.3.4",
"version": "0.4.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
48 changes: 48 additions & 0 deletions ui/src/components/CreateWorkItemModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ export function CreateWorkItemModal({
const [labelSearch, setLabelSearch] = useState("");
const [cycleSearch, setCycleSearch] = useState("");
const [moduleSearch, setModuleSearch] = useState("");
const [createLabelLoading, setCreateLabelLoading] = useState(false);
const [createLabelError, setCreateLabelError] = useState<string | null>(null);

useEffect(() => {
if (!openDropdown) {
Expand All @@ -232,6 +234,7 @@ export function CreateWorkItemModal({
setLabelSearch("");
setCycleSearch("");
setModuleSearch("");
setCreateLabelError(null);
}
}, [openDropdown]);

Expand Down Expand Up @@ -462,6 +465,26 @@ export function CreateWorkItemModal({
);
};

const handleCreateLabel = async () => {
const name = labelSearch.trim();
if (!name || !workspaceSlug || !pid) return;
setCreateLabelError(null);
setCreateLabelLoading(true);
try {
const created = await labelService.create(workspaceSlug, pid, { name });
setLabels((prev) => [...prev, created]);
setLabelIds((prev) => [...prev, created.id]);
setLabelSearch("");
setOpenDropdown(null);
} catch (err) {
setCreateLabelError(
err instanceof Error ? err.message : "Failed to create label.",
);
} finally {
setCreateLabelLoading(false);
}
};

if (!open) return null;

return createPortal(
Expand Down Expand Up @@ -690,6 +713,31 @@ export function CreateWorkItemModal({
{l.name}
</button>
))}
{labelSearch.trim() &&
!labels.some(
(l) =>
l.name.toLowerCase() ===
labelSearch.trim().toLowerCase(),
) && (
<>
<div className="my-1 border-t border-[var(--border-subtle)]" />
<button
type="button"
onClick={handleCreateLabel}
disabled={createLabelLoading}
className="w-full text-left text-[var(--brand-default)] hover:bg-[var(--bg-layer-1-hover)] disabled:opacity-50"
>
{createLabelLoading
? "Creating…"
: `Create label "${labelSearch.trim()}"`}
</button>
{createLabelError && (
<p className="px-2 py-1 text-xs text-red-600">
{createLabelError}
</p>
)}
</>
)}
</div>
</Dropdown>
<DatePickerTrigger
Expand Down
30 changes: 19 additions & 11 deletions ui/src/components/layout/AppShell.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { Outlet } from "react-router-dom";
import { Outlet, useLocation } from "react-router-dom";
import { WorkspaceViewsStateProvider } from "../../contexts/WorkspaceViewsStateContext";
import { PageHeader } from "./PageHeader";
import { Sidebar } from "./Sidebar";

export function AppShell() {
const { pathname } = useLocation();
const isViewsRoute = pathname.includes("/views");

return (
<div className="flex h-screen flex-col overflow-hidden bg-[var(--bg-screen)] p-3">
<div className="flex min-h-0 flex-1 overflow-hidden rounded-[var(--radius-lg)] bg-[var(--bg-surface-1)] shadow-[var(--shadow-container)]">
<Sidebar />
<main className="flex min-h-0 flex-1 flex-col overflow-hidden bg-[var(--bg-canvas)]">
<PageHeader />
<div className="main-content-scroll min-h-0 flex-1 overflow-auto p-[var(--padding-page)]">
<Outlet />
</div>
</main>
<WorkspaceViewsStateProvider>
<div className="flex h-screen flex-col overflow-hidden bg-[var(--bg-screen)] p-3">
<div className="flex min-h-0 flex-1 overflow-hidden rounded-[var(--radius-lg)] bg-[var(--bg-surface-1)] shadow-[var(--shadow-container)]">
<Sidebar />
<main className="flex min-h-0 flex-1 flex-col overflow-hidden bg-[var(--bg-canvas)]">
<PageHeader />
<div
className={`main-content-scroll min-h-0 flex-1 overflow-auto p-[var(--padding-page)] ${isViewsRoute ? "pl-0" : ""}`}
>
<Outlet />
</div>
</main>
</div>
</div>
</div>
</WorkspaceViewsStateProvider>
);
}
Loading
Loading