Skip to content

Commit

Permalink
Interaction polish (#188)
Browse files Browse the repository at this point in the history
* open transaction in interact screen (first pass)

* remove predefined interactions

* fix execution settings width

* consolidate section spacings

* tweak execution settings padding

* fix opened logs positioning

* move templates logic to a separate provider

* simplify/refactor interaction structures and logic

* fix empty interaction creation

* fix address builder overflow

* temporarily only show settings for mutable templates

* fixed interaction tab width

* fix transaction source overflow

* fix open transaction from history

* make transaction error handling more consistent

* fix transaction name when opened from source component

* fix layout body scrollbars

* fix contract details link

* fix basic layout

* collapse event table data

* tweak card scrollbars

* fix breadcrumbs filtration

* fix project update

* hide root scrollbars

* move interaction providers lower down the react tree

* fix interaction removal

* improve interaction creation logic

* display tabs in reverse order of stored templates

* fix focused transaction tab reset

* add unsupported import syntax notice

* improve error message

* remove bottom border from tabs

* settings screen tweaks

* change block menu item labels

* custom outline color

* fix external link overflow

* fix missing context
  • Loading branch information
bartolomej authored Sep 15, 2023
1 parent 59de3e5 commit 1210670
Show file tree
Hide file tree
Showing 44 changed files with 645 additions and 441 deletions.
17 changes: 13 additions & 4 deletions backend/src/projects/projects.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import * as fs from "fs";
import { CacheRemovalService } from "../core/services/cache-removal.service";
import { WalletService } from "../wallet/wallet.service";
import { FlowSnapshotService } from "../flow/services/snapshot.service";
import { FlowTemplatesService } from '../flow/services/templates.service';
import { FlowTemplatesService } from "../flow/services/templates.service";

const commandExists = require("command-exists");
const semver = require("semver");
Expand Down Expand Up @@ -58,7 +58,7 @@ export class ProjectsService {
this.flowSnapshotsService,
// Wallet service also depends on the gateway service (needs to initialize fcl).
this.walletService,
this.flowTemplatesService
this.flowTemplatesService,
];

constructor(
Expand Down Expand Up @@ -235,20 +235,29 @@ export class ProjectsService {

async update(id: string, updateProjectDto: UpdateProjectDto) {
const currentProject = this.getCurrentProject();
const currentPersistedProject = await this.projectRepository.findOneBy({
id,
});

const project = ProjectEntity.create(updateProjectDto);
project.markUpdated();

// Project can be persisted only in-memory
if (currentProject?.id === id) {
if (currentProject && currentProject.id === id) {
this.currentProject = project;
return this.currentProject;

// If this is an in-memory project, don't execute update to avoid http error.
if (!currentPersistedProject) {
return this.currentProject;
}
}

await this.projectRepository.update(
{ id },
// Prevent overwriting existing created date
{ ...project, createdAt: undefined }
);

return project;
}

Expand Down
12 changes: 9 additions & 3 deletions frontend/src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
@import "styles/typography";

* {
margin: 0;
padding: 0;
box-sizing: content-box;
margin: 0;
padding: 0;
box-sizing: content-box;
outline: none;

&:focus-visible {
outline: 2px solid $blue;
}
}

html,
Expand All @@ -23,6 +28,7 @@ body {
height: 100%;

scroll-behavior: smooth;

&::-webkit-scrollbar {
display: none;
}
Expand Down
42 changes: 26 additions & 16 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
useParams,
} from "react-router-dom";
import { Toaster } from "react-hot-toast";
import { BackButtonLayout, ProjectLayout } from "./components/layout/Layout";
import { ProjectLayout } from "./components/layout/ProjectLayout/ProjectLayout";
import "./App.scss";
import { toastOptions } from "./config/toast";

Expand Down Expand Up @@ -49,6 +49,8 @@ import { ContractsTable } from "./modules/contracts/ContractsTable";
import { ContractDetails } from "./modules/contracts/ContractDetails/ContractDetails";
import { EventsTable } from "./modules/events/EventsTable/EventsTable";
import { createCrumbHandle } from "./components/breadcrumbs/Breadcrumbs";
import { TemplatesRegistryProvider } from "./modules/interactions/contexts/templates.context";
import { BasicLayout } from "./components/layout/BasicLayout/BasicLayout";

const BrowserRouterEvents = (props: { children: ReactNode }): ReactElement => {
const location = useLocation();
Expand Down Expand Up @@ -84,18 +86,16 @@ export const FlowserClientApp = ({
<TimeoutPollingProvider enabled={enableTimeoutPolling}>
<ConfirmDialogProvider>
<PlatformAdapterProvider {...platformAdapter}>
<InteractionRegistryProvider>
<ConsentAnalytics />
<ProjectRequirements />
<RouterProvider
router={useHashRouter ? hashRouter : browserRouter}
/>
<Toaster
position="bottom-center"
gutter={8}
toastOptions={toastOptions}
/>
</InteractionRegistryProvider>
<ConsentAnalytics />
<ProjectRequirements />
<RouterProvider
router={useHashRouter ? hashRouter : browserRouter}
/>
<Toaster
position="bottom-center"
gutter={8}
toastOptions={toastOptions}
/>
</PlatformAdapterProvider>
</ConfirmDialogProvider>
</TimeoutPollingProvider>
Expand All @@ -117,6 +117,9 @@ const routes: RouteObject[] = [
</BrowserRouterEvents>
</ProjectProvider>
),
handle: createCrumbHandle({
crumbName: "Projects",
}),
children: [
{
index: true,
Expand All @@ -125,16 +128,23 @@ const routes: RouteObject[] = [
{
path: "create",
element: (
<BackButtonLayout>
<BasicLayout>
<ProjectSettingsPage />
</BackButtonLayout>
</BasicLayout>
),
handle: createCrumbHandle({
crumbName: "Create",
}),
},
{
path: ":projectId",
element: (
<ProjectLayout>
<Outlet />
<InteractionRegistryProvider>
<TemplatesRegistryProvider>
<Outlet />
</TemplatesRegistryProvider>
</InteractionRegistryProvider>
</ProjectLayout>
),
children: [
Expand Down
19 changes: 14 additions & 5 deletions frontend/src/components/breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { ReactElement } from "react";
import { NavLink, useMatches, useNavigate } from "react-router-dom";
import classes from "./Breadcrumbs.module.scss";
import { ReactComponent as IconBackButton } from "../../assets/icons/back-button.svg";
import classNames from "classnames";
import { FlowserIcon } from "../icons/Icons";
import { useCurrentProjectId } from "../../hooks/use-current-project-id";

type BreadcrumbsProps = {
className?: string;
Expand Down Expand Up @@ -35,10 +36,18 @@ function isMatchWithCrumb(match: Match): match is MatchWithCrumb {

export function Breadcrumbs(props: BreadcrumbsProps): ReactElement | null {
const navigate = useNavigate();
const currentUrl = window.location.pathname;
const projectId = useCurrentProjectId();

function shouldShowMatch(match: Match) {
// For project pages, only show matches from project-scoped routes.
// This is to avoid showing the "Projects" crumb on every page.
return !projectId || match.pathname.startsWith(`/projects/${projectId}`);
}

const matches: Match[] = useMatches();
const matchesWithCrumbs: MatchWithCrumb[] = matches.filter(isMatchWithCrumb);
const matchesWithCrumbs: MatchWithCrumb[] = matches
.filter(isMatchWithCrumb)
.filter(shouldShowMatch);
const breadcrumbs = matchesWithCrumbs.map(
(match): Breadcrumb => ({
to: match.pathname,
Expand All @@ -54,13 +63,13 @@ export function Breadcrumbs(props: BreadcrumbsProps): ReactElement | null {
<div className={classNames(classes.root, props.className)}>
{breadcrumbs.length > 1 && (
<div className={classes.backButtonWrapper} onClick={() => navigate(-1)}>
<IconBackButton className={classes.backButton} />
<FlowserIcon.Back className={classes.backButton} />
</div>
)}
<div className={classes.breadcrumbs}>
{breadcrumbs
.map<React.ReactNode>((item, key) => (
<NavLink key={key} to={item.to || currentUrl}>
<NavLink key={key} to={item.to}>
{item.label}
</NavLink>
))
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/card/Card.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
@import 'styles/rules';
@import 'styles/spacings';
@import 'styles/animations';
@import 'styles/scrollbars';

.root {
border-radius: $border-radius-card;
padding: $spacing-l;
border: 1px solid transparent;
position: relative;

@include hiddenScrollbars();

&.introAnimation {
@include addNewContentAnimation(.4s);
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import { ReactComponent as Exit } from "../../assets/icons/exit.svg";
import { ReactComponent as Restart } from "../../assets/icons/restart.svg";
import { ReactComponent as Open } from "../../assets/icons/open.svg";
import { ReactComponent as Share } from "../../assets/icons/share.svg";
import { ReactComponent as Back } from "../../assets/icons/back-button.svg";

export const FlowserIcon = {
Back: Back,
Account: Account,
Block: Block,
Contract: Contract,
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/components/layout/BasicLayout/BasicLayout.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import "styles/colors";

.root {
.header {
position: sticky;
top: 0;
background: $gray-110;
z-index: 100;
}
}
14 changes: 14 additions & 0 deletions frontend/src/components/layout/BasicLayout/BasicLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, { FC, ReactNode } from "react";
import { Breadcrumbs } from "../../breadcrumbs/Breadcrumbs";
import classes from "./BasicLayout.module.scss";

export const BasicLayout: FC<{ children: ReactNode }> = (props) => {
return (
<div className={classes.root}>
<div className={classes.header}>
<Breadcrumbs className={classes.breadcrumbs} />
</div>
{props.children}
</div>
);
};
48 changes: 0 additions & 48 deletions frontend/src/components/layout/Layout.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "styles/spacings";
@import "styles/colors";
@import "styles/scrollbars";

$side-nav-width: 80px;

Expand All @@ -20,6 +21,8 @@ $side-nav-width: 80px;
max-height: 100vh;
overflow-y: scroll;

@include hiddenScrollbars();

.breadcrumbs {
position: sticky;
top: 0;
Expand All @@ -34,6 +37,8 @@ $side-nav-width: 80px;
display: flex;
flex-direction: column;
flex: 1;

@include hiddenScrollbars();
}

.bodyWithBorderSpacing {
Expand Down
32 changes: 32 additions & 0 deletions frontend/src/components/layout/ProjectLayout/ProjectLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { FunctionComponent } from "react";
import classes from "./ProjectLayout.module.scss";
import { Logs } from "../../../modules/logs/Logs";
import { useLocation } from "react-router-dom";
import classNames from "classnames";
import { Breadcrumbs } from "../../breadcrumbs/Breadcrumbs";
import { SideNavigation } from "../../side-navigation/SideNavigation";

export const scrollableElementId = "flowser-scroll";

export const ProjectLayout: FunctionComponent = ({ children }) => {
const location = useLocation();
const showMargin = !location.pathname.endsWith("interactions");

return (
<div className={classes.root}>
<SideNavigation className={classes.sideNavigation} />
<div className={classes.mainContent}>
<Breadcrumbs className={classes.breadcrumbs} />
<div
id={scrollableElementId}
className={classNames(classes.body, {
[classes.bodyWithBorderSpacing]: showMargin,
})}
>
{children}
</div>
<Logs className={classes.logs} />
</div>
</div>
);
};
2 changes: 1 addition & 1 deletion frontend/src/components/links/ExternalLink.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
fill: $blue;
}
.url {
overflow: hidden;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
Loading

0 comments on commit 1210670

Please sign in to comment.