forked from tsai/budibase
143 changed files with 2969 additions and 5550 deletions
@ -1,54 +1,60 @@ |
|||||
xcontext('Create Components', () => { |
xcontext("Create Components", () => { |
||||
|
before(() => { |
||||
|
cy.server() |
||||
|
cy.visit("localhost:4001/_builder") |
||||
|
// https://on.cypress.io/type
|
||||
|
cy.createApp("Table App", "Table App Description") |
||||
|
cy.createTable("dog", "name", "age") |
||||
|
cy.addRow("bob", "15") |
||||
|
}) |
||||
|
|
||||
before(() => { |
// https://on.cypress.io/interacting-with-elements
|
||||
cy.server() |
it("should add a container", () => { |
||||
cy.visit('localhost:4001/_builder') |
cy.navigateToFrontend() |
||||
// https://on.cypress.io/type
|
cy.get(".switcher > :nth-child(2)").click() |
||||
cy.createApp('Table App', 'Table App Description') |
cy.contains("Container").click() |
||||
cy.createTable('dog', 'name', 'age') |
}) |
||||
cy.addRow('bob', '15') |
it("should add a headline", () => { |
||||
}) |
cy.addHeadlineComponent("An Amazing headline!") |
||||
|
|
||||
// https://on.cypress.io/interacting-with-elements
|
getIframeBody().contains("An Amazing headline!") |
||||
it('should add a container', () => { |
}) |
||||
cy.contains('frontend').click() |
it("change the font size of the headline", () => { |
||||
cy.get('.switcher > :nth-child(2)').click() |
cy.contains("Typography").click() |
||||
|
cy.get("[data-cy=font-size-prop-control]").click() |
||||
|
cy.contains("60px").click() |
||||
|
cy.contains("Design").click() |
||||
|
|
||||
cy.contains('Container').click() |
getIframeBody() |
||||
}) |
.contains("An Amazing headline!") |
||||
it('should add a headline', () => { |
.should("have.css", "font-size", "60px") |
||||
cy.addHeadlineComponent('An Amazing headline!') |
}) |
||||
|
|
||||
getIframeBody().contains('An Amazing headline!') |
|
||||
}) |
|
||||
it('change the font size of the headline', () => { |
|
||||
cy.contains('Typography').click() |
|
||||
cy.get('[data-cy=font-size-prop-control]').click() |
|
||||
cy.contains("60px").click() |
|
||||
cy.contains('Design').click() |
|
||||
|
|
||||
getIframeBody().contains('An Amazing headline!').should('have.css', 'font-size', '60px') |
|
||||
}) |
|
||||
}) |
}) |
||||
|
|
||||
const getIframeDocument = () => { |
const getIframeDocument = () => { |
||||
return cy |
return ( |
||||
.get('iframe') |
cy |
||||
// Cypress yields jQuery element, which has the real
|
.get("iframe") |
||||
// DOM element under property "0".
|
// Cypress yields jQuery element, which has the real
|
||||
// From the real DOM iframe element we can get
|
// DOM element under property "0".
|
||||
// the "document" element, it is stored in "contentDocument" property
|
// From the real DOM iframe element we can get
|
||||
// Cypress "its" command can access deep properties using dot notation
|
// the "document" element, it is stored in "contentDocument" property
|
||||
// https://on.cypress.io/its
|
// Cypress "its" command can access deep properties using dot notation
|
||||
.its('0.contentDocument').should('exist') |
// https://on.cypress.io/its
|
||||
|
.its("0.contentDocument") |
||||
|
.should("exist") |
||||
|
) |
||||
} |
} |
||||
|
|
||||
const getIframeBody = () => { |
const getIframeBody = () => { |
||||
// get the document
|
// get the document
|
||||
return getIframeDocument() |
return ( |
||||
// automatically retries until body is loaded
|
getIframeDocument() |
||||
.its('body').should('not.be.undefined') |
// automatically retries until body is loaded
|
||||
// wraps "body" DOM element to allow
|
.its("body") |
||||
// chaining more Cypress commands, like ".find(...)"
|
.should("not.be.undefined") |
||||
.then(cy.wrap) |
// wraps "body" DOM element to allow
|
||||
|
// chaining more Cypress commands, like ".find(...)"
|
||||
|
.then(cy.wrap) |
||||
|
) |
||||
} |
} |
||||
@ -0,0 +1,136 @@ |
|||||
|
<script> |
||||
|
import { sortBy } from "lodash/fp" |
||||
|
import { automationStore } from "builderStore" |
||||
|
import { DropdownMenu, Modal } from "@budibase/bbui" |
||||
|
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns" |
||||
|
import analytics from "analytics" |
||||
|
import CreateWebhookModal from "../Shared/CreateWebhookModal.svelte" |
||||
|
|
||||
|
$: hasTrigger = $automationStore.selectedAutomation.hasTrigger() |
||||
|
$: tabs = [ |
||||
|
{ |
||||
|
label: "Trigger", |
||||
|
value: "TRIGGER", |
||||
|
icon: "ri-organization-chart", |
||||
|
disabled: hasTrigger, |
||||
|
}, |
||||
|
{ |
||||
|
label: "Action", |
||||
|
value: "ACTION", |
||||
|
icon: "ri-flow-chart", |
||||
|
disabled: !hasTrigger, |
||||
|
}, |
||||
|
{ |
||||
|
label: "Logic", |
||||
|
value: "LOGIC", |
||||
|
icon: "ri-filter-line", |
||||
|
disabled: !hasTrigger, |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
let selectedIndex |
||||
|
let anchors = [] |
||||
|
let popover |
||||
|
let webhookModal |
||||
|
$: selectedTab = selectedIndex == null ? null : tabs[selectedIndex].value |
||||
|
$: anchor = selectedIndex === -1 ? null : anchors[selectedIndex] |
||||
|
$: blocks = sortBy(entry => entry[1].name)( |
||||
|
Object.entries($automationStore.blockDefinitions[selectedTab] ?? {}) |
||||
|
) |
||||
|
|
||||
|
function onChangeTab(idx) { |
||||
|
selectedIndex = idx |
||||
|
popover.show() |
||||
|
} |
||||
|
|
||||
|
function closePopover() { |
||||
|
selectedIndex = null |
||||
|
popover.hide() |
||||
|
} |
||||
|
|
||||
|
function addBlockToAutomation(stepId, blockDefinition) { |
||||
|
const newBlock = { |
||||
|
...blockDefinition, |
||||
|
inputs: blockDefinition.inputs || {}, |
||||
|
stepId, |
||||
|
type: selectedTab, |
||||
|
} |
||||
|
automationStore.actions.addBlockToAutomation(newBlock) |
||||
|
analytics.captureEvent("Added Automation Block", { |
||||
|
name: blockDefinition.name, |
||||
|
}) |
||||
|
closePopover() |
||||
|
if (stepId === "WEBHOOK") { |
||||
|
webhookModal.show() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div class="tab-container"> |
||||
|
{#each tabs as tab, idx} |
||||
|
<div |
||||
|
bind:this={anchors[idx]} |
||||
|
class="tab" |
||||
|
class:disabled={tab.disabled} |
||||
|
on:click={tab.disabled ? null : () => onChangeTab(idx)} |
||||
|
class:active={idx === selectedIndex}> |
||||
|
{#if tab.icon}<i class={tab.icon} />{/if} |
||||
|
<span>{tab.label}</span> |
||||
|
<i class="ri-arrow-down-s-line arrow" /> |
||||
|
</div> |
||||
|
{/each} |
||||
|
</div> |
||||
|
<DropdownMenu |
||||
|
on:close={() => (selectedIndex = null)} |
||||
|
bind:this={popover} |
||||
|
{anchor} |
||||
|
align="left"> |
||||
|
<DropdownContainer> |
||||
|
{#each blocks as [stepId, blockDefinition]} |
||||
|
<DropdownItem |
||||
|
icon={blockDefinition.icon} |
||||
|
title={blockDefinition.name} |
||||
|
subtitle={blockDefinition.description} |
||||
|
on:click={() => addBlockToAutomation(stepId, blockDefinition)} /> |
||||
|
{/each} |
||||
|
</DropdownContainer> |
||||
|
</DropdownMenu> |
||||
|
<Modal bind:this={webhookModal} width="30%"> |
||||
|
<CreateWebhookModal /> |
||||
|
</Modal> |
||||
|
|
||||
|
<style> |
||||
|
.tab-container { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: flex-start; |
||||
|
align-items: center; |
||||
|
gap: var(--spacing-l); |
||||
|
min-height: 24px; |
||||
|
} |
||||
|
|
||||
|
.tab { |
||||
|
color: var(--grey-7); |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: flex-start; |
||||
|
align-items: center; |
||||
|
gap: var(--spacing-xs); |
||||
|
font-size: var(--font-size-xs); |
||||
|
} |
||||
|
.tab span { |
||||
|
font-weight: 500; |
||||
|
user-select: none; |
||||
|
} |
||||
|
.tab.active, |
||||
|
.tab:not(.disabled):hover { |
||||
|
color: var(--ink); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.tab.disabled { |
||||
|
color: var(--grey-5); |
||||
|
} |
||||
|
.tab i:not(:last-child) { |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
</style> |
||||
|
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 303 B |
@ -0,0 +1,34 @@ |
|||||
|
<script> |
||||
|
import { onMount } from "svelte" |
||||
|
import { automationStore } from "builderStore" |
||||
|
import NavItem from "components/common/NavItem.svelte" |
||||
|
import EditAutomationPopover from "./EditAutomationPopover.svelte" |
||||
|
|
||||
|
$: selectedAutomationId = $automationStore.selectedAutomation?.automation?._id |
||||
|
|
||||
|
onMount(() => { |
||||
|
automationStore.actions.fetch() |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<div class="automations-list"> |
||||
|
{#each $automationStore.automations as automation, idx} |
||||
|
<NavItem |
||||
|
border={idx > 0} |
||||
|
icon="ri-stackshare-line" |
||||
|
text={automation.name} |
||||
|
selected={automation._id === selectedAutomationId} |
||||
|
on:click={() => automationStore.actions.select(automation)}> |
||||
|
<EditAutomationPopover {automation} /> |
||||
|
</NavItem> |
||||
|
{/each} |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.automations-list { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: flex-start; |
||||
|
align-items: stretch; |
||||
|
} |
||||
|
</style> |
||||
@ -1,79 +0,0 @@ |
|||||
<script> |
|
||||
import { onMount } from "svelte" |
|
||||
import { automationStore } from "builderStore" |
|
||||
import CreateAutomationModal from "./CreateAutomationModal.svelte" |
|
||||
import { Button, Modal } from "@budibase/bbui" |
|
||||
|
|
||||
let modal |
|
||||
|
|
||||
$: selectedAutomationId = $automationStore.selectedAutomation?.automation?._id |
|
||||
|
|
||||
onMount(() => { |
|
||||
automationStore.actions.fetch() |
|
||||
}) |
|
||||
</script> |
|
||||
|
|
||||
<section> |
|
||||
<Button primary wide on:click={modal.show}>Create New Automation</Button> |
|
||||
<ul> |
|
||||
{#each $automationStore.automations as automation} |
|
||||
<li |
|
||||
class="automation-item" |
|
||||
class:selected={automation._id === selectedAutomationId} |
|
||||
on:click={() => automationStore.actions.select(automation)}> |
|
||||
<i class="ri-stackshare-line" class:live={automation.live} /> |
|
||||
{automation.name} |
|
||||
</li> |
|
||||
{/each} |
|
||||
</ul> |
|
||||
</section> |
|
||||
<Modal bind:this={modal}> |
|
||||
<CreateAutomationModal /> |
|
||||
</Modal> |
|
||||
|
|
||||
<style> |
|
||||
section { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
ul { |
|
||||
list-style-type: none; |
|
||||
padding: 0; |
|
||||
margin: var(--spacing-xl) 0 0 0; |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
i { |
|
||||
color: var(--grey-6); |
|
||||
} |
|
||||
i.live { |
|
||||
color: var(--ink); |
|
||||
} |
|
||||
|
|
||||
li { |
|
||||
font-size: 14px; |
|
||||
} |
|
||||
|
|
||||
.automation-item { |
|
||||
display: flex; |
|
||||
flex-direction: row; |
|
||||
justify-content: flex-start; |
|
||||
align-items: center; |
|
||||
border-radius: var(--border-radius-m); |
|
||||
padding: var(--spacing-s) var(--spacing-m); |
|
||||
margin-bottom: var(--spacing-xs); |
|
||||
color: var(--ink); |
|
||||
} |
|
||||
.automation-item i { |
|
||||
font-size: 24px; |
|
||||
margin-right: var(--spacing-m); |
|
||||
} |
|
||||
.automation-item:hover { |
|
||||
cursor: pointer; |
|
||||
background: var(--grey-1); |
|
||||
} |
|
||||
.automation-item.selected { |
|
||||
background: var(--grey-2); |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,82 +0,0 @@ |
|||||
<script> |
|
||||
import { backendUiStore, automationStore } from "builderStore" |
|
||||
import CreateWebookModal from "../../Shared/CreateWebhookModal.svelte" |
|
||||
import analytics from "analytics" |
|
||||
import { Modal } from "@budibase/bbui" |
|
||||
|
|
||||
export let blockDefinition |
|
||||
export let stepId |
|
||||
export let blockType |
|
||||
|
|
||||
let modal |
|
||||
|
|
||||
$: instanceId = $backendUiStore.selectedDatabase._id |
|
||||
$: automation = $automationStore.selectedAutomation?.automation |
|
||||
|
|
||||
function addBlockToAutomation() { |
|
||||
automationStore.actions.addBlockToAutomation({ |
|
||||
...blockDefinition, |
|
||||
inputs: blockDefinition.inputs || {}, |
|
||||
stepId, |
|
||||
type: blockType, |
|
||||
}) |
|
||||
if (stepId === "WEBHOOK") { |
|
||||
modal.show() |
|
||||
} |
|
||||
analytics.captureEvent("Added Automation Block", { |
|
||||
name: blockDefinition.name, |
|
||||
}) |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<div |
|
||||
class="automation-block hoverable" |
|
||||
on:click={addBlockToAutomation} |
|
||||
data-cy={stepId}> |
|
||||
<div><i class={blockDefinition.icon} /></div> |
|
||||
<div class="automation-text"> |
|
||||
<h4>{blockDefinition.name}</h4> |
|
||||
<p>{blockDefinition.description}</p> |
|
||||
</div> |
|
||||
</div> |
|
||||
<Modal bind:this={modal} width="30%"> |
|
||||
<CreateWebookModal /> |
|
||||
</Modal> |
|
||||
|
|
||||
<style> |
|
||||
.automation-block { |
|
||||
display: grid; |
|
||||
grid-template-columns: 20px auto; |
|
||||
align-items: center; |
|
||||
margin-top: var(--spacing-s); |
|
||||
padding: var(--spacing-m); |
|
||||
border-radius: var(--border-radius-m); |
|
||||
} |
|
||||
.automation-block:hover { |
|
||||
background-color: var(--grey-1); |
|
||||
} |
|
||||
.automation-block:first-child { |
|
||||
margin-top: 0; |
|
||||
} |
|
||||
|
|
||||
i { |
|
||||
color: var(--grey-7); |
|
||||
font-size: 20px; |
|
||||
} |
|
||||
|
|
||||
.automation-text { |
|
||||
margin-left: 16px; |
|
||||
} |
|
||||
.automation-text h4 { |
|
||||
font-size: 14px; |
|
||||
font-weight: 500; |
|
||||
margin-bottom: 5px; |
|
||||
margin-top: 0; |
|
||||
} |
|
||||
.automation-text p { |
|
||||
font-size: 12px; |
|
||||
line-height: 1.4; |
|
||||
color: var(--grey-7); |
|
||||
margin: 0; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,48 +0,0 @@ |
|||||
<script> |
|
||||
import { sortBy } from "lodash/fp" |
|
||||
import { automationStore } from "builderStore" |
|
||||
import AutomationBlock from "./AutomationBlock.svelte" |
|
||||
import FlatButtonGroup from "components/userInterface/FlatButtonGroup.svelte" |
|
||||
|
|
||||
let selectedTab = "TRIGGER" |
|
||||
let buttonProps = [] |
|
||||
$: blocks = sortBy(entry => entry[1].name)( |
|
||||
Object.entries($automationStore.blockDefinitions[selectedTab]) |
|
||||
) |
|
||||
|
|
||||
$: { |
|
||||
if ($automationStore.selectedAutomation.hasTrigger()) { |
|
||||
buttonProps = [ |
|
||||
{ value: "ACTION", text: "Action" }, |
|
||||
{ value: "LOGIC", text: "Logic" }, |
|
||||
] |
|
||||
if (selectedTab === "TRIGGER") { |
|
||||
selectedTab = "ACTION" |
|
||||
} |
|
||||
} else { |
|
||||
buttonProps = [{ value: "TRIGGER", text: "Trigger" }] |
|
||||
if (selectedTab !== "TRIGGER") { |
|
||||
selectedTab = "TRIGGER" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
function onChangeTab(tab) { |
|
||||
selectedTab = tab |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<section> |
|
||||
<FlatButtonGroup value={selectedTab} {buttonProps} onChange={onChangeTab} /> |
|
||||
<div id="blocklist"> |
|
||||
{#each blocks as [stepId, blockDefinition]} |
|
||||
<AutomationBlock {blockDefinition} {stepId} blockType={selectedTab} /> |
|
||||
{/each} |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<style> |
|
||||
#blocklist { |
|
||||
margin-top: var(--spacing-xl); |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,88 @@ |
|||||
|
<script> |
||||
|
import { automationStore, backendUiStore } from "builderStore" |
||||
|
import { notifier } from "builderStore/store/notifications" |
||||
|
import { DropdownMenu } from "@budibase/bbui" |
||||
|
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns" |
||||
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte" |
||||
|
|
||||
|
export let automation |
||||
|
|
||||
|
let anchor |
||||
|
let dropdown |
||||
|
let confirmDeleteDialog |
||||
|
$: instanceId = $backendUiStore.selectedDatabase._id |
||||
|
|
||||
|
function showModal() { |
||||
|
dropdown.hide() |
||||
|
confirmDeleteDialog.show() |
||||
|
} |
||||
|
|
||||
|
async function deleteAutomation() { |
||||
|
await automationStore.actions.delete({ |
||||
|
instanceId, |
||||
|
automation, |
||||
|
}) |
||||
|
notifier.success("Automation deleted.") |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div on:click|stopPropagation> |
||||
|
<div bind:this={anchor} class="icon" on:click={dropdown.show}> |
||||
|
<i class="ri-more-line" /> |
||||
|
</div> |
||||
|
<DropdownMenu align="left" {anchor} bind:this={dropdown}> |
||||
|
<DropdownContainer> |
||||
|
<DropdownItem |
||||
|
icon="ri-delete-bin-line" |
||||
|
title="Delete" |
||||
|
on:click={showModal} /> |
||||
|
</DropdownContainer> |
||||
|
</DropdownMenu> |
||||
|
</div> |
||||
|
<ConfirmDialog |
||||
|
bind:this={confirmDeleteDialog} |
||||
|
okText="Delete Automation" |
||||
|
onOk={deleteAutomation} |
||||
|
title="Confirm Deletion"> |
||||
|
Are you sure you wish to delete the automation |
||||
|
<i>{automation.name}?</i> |
||||
|
This action cannot be undone. |
||||
|
</ConfirmDialog> |
||||
|
|
||||
|
<style> |
||||
|
div.icon { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: flex-end; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
div.icon i { |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
|
||||
|
ul { |
||||
|
list-style: none; |
||||
|
margin: 0; |
||||
|
padding: var(--spacing-s) 0; |
||||
|
} |
||||
|
|
||||
|
li { |
||||
|
display: flex; |
||||
|
font-family: var(--font-sans); |
||||
|
font-size: var(--font-size-xs); |
||||
|
color: var(--ink); |
||||
|
padding: var(--spacing-s) var(--spacing-m); |
||||
|
margin: auto 0; |
||||
|
align-items: center; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
li:hover { |
||||
|
background-color: var(--grey-2); |
||||
|
} |
||||
|
|
||||
|
li:active { |
||||
|
color: var(--blue); |
||||
|
} |
||||
|
</style> |
||||
@ -1,3 +0,0 @@ |
|||||
export { default as AutomationPanel } from "./AutomationPanel.svelte" |
|
||||
export { default as BlockList } from "./BlockList/BlockList.svelte" |
|
||||
export { default as AutomationList } from "./AutomationList/AutomationList.svelte" |
|
||||
@ -1 +0,0 @@ |
|||||
export { default as SetupPanel } from "./SetupPanel.svelte" |
|
||||
@ -1,3 +0,0 @@ |
|||||
export { default as AutomationBuilder } from "./AutomationBuilder/AutomationBuilder.svelte" |
|
||||
export { default as SetupPanel } from "./SetupPanel/SetupPanel.svelte" |
|
||||
export { default as AutomationPanel } from "./AutomationPanel/AutomationPanel.svelte" |
|
||||
@ -1,70 +0,0 @@ |
|||||
<script> |
|
||||
export let disabled = false |
|
||||
export let hidden = false |
|
||||
export let secondary = false |
|
||||
export let primary = true |
|
||||
export let cancel = false |
|
||||
export let alert = false |
|
||||
export let warning = false |
|
||||
</script> |
|
||||
|
|
||||
<button |
|
||||
on:click |
|
||||
class="button" |
|
||||
class:hidden |
|
||||
class:secondary |
|
||||
class:primary |
|
||||
class:alert |
|
||||
class:cancel |
|
||||
class:warning |
|
||||
{disabled}> |
|
||||
<slot /> |
|
||||
</button> |
|
||||
|
|
||||
<style> |
|
||||
.primary { |
|
||||
color: #ffffff; |
|
||||
background: var(--blue); |
|
||||
border: solid 1px var(--blue); |
|
||||
} |
|
||||
|
|
||||
.alert { |
|
||||
color: white; |
|
||||
background: #e26d69; |
|
||||
border: solid 1px #e26d69; |
|
||||
} |
|
||||
|
|
||||
.cancel { |
|
||||
color: var(--secondary40); |
|
||||
background: none; |
|
||||
} |
|
||||
|
|
||||
.secondary { |
|
||||
color: var(--ink); |
|
||||
border: solid 1px var(--grey-4); |
|
||||
background: white; |
|
||||
} |
|
||||
|
|
||||
.button { |
|
||||
font-size: 14px; |
|
||||
font-weight: 500; |
|
||||
border-radius: 3px; |
|
||||
padding: 10px 20px; |
|
||||
height: 40px; |
|
||||
} |
|
||||
|
|
||||
.button:hover { |
|
||||
cursor: pointer; |
|
||||
filter: saturate(90%); |
|
||||
} |
|
||||
|
|
||||
.button:disabled { |
|
||||
color: rgba(22, 48, 87, 0.2); |
|
||||
cursor: default; |
|
||||
background: transparent; |
|
||||
} |
|
||||
|
|
||||
.hidden { |
|
||||
visibility: hidden; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,171 +0,0 @@ |
|||||
<script> |
|
||||
export let color = "primary" |
|
||||
export let className = "" |
|
||||
export let style = "" |
|
||||
export let groupPosition = "" |
|
||||
export let grouped = false |
|
||||
|
|
||||
$: borderClass = grouped ? "" : "border-normal" |
|
||||
</script> |
|
||||
|
|
||||
<button |
|
||||
class="{color} |
|
||||
{className} |
|
||||
{borderClass} |
|
||||
{grouped ? 'grouped' : ''}" |
|
||||
{style} |
|
||||
on:click> |
|
||||
<slot /> |
|
||||
</button> |
|
||||
|
|
||||
<style> |
|
||||
.border-normal { |
|
||||
border-radius: var(--borderradiusall); |
|
||||
} |
|
||||
.border-left { |
|
||||
border-radius: var(--borderradius) 0 0 var(--borderradius); |
|
||||
} |
|
||||
.border-right { |
|
||||
border-radius: 0 var(--borderradius) var(--borderradius) 0; |
|
||||
} |
|
||||
.border-middle { |
|
||||
border-radius: 0; |
|
||||
} |
|
||||
|
|
||||
button { |
|
||||
border-style: solid; |
|
||||
padding: 7.5px 15px; |
|
||||
cursor: pointer; |
|
||||
margin: 5px; |
|
||||
border-radius: 5px; |
|
||||
} |
|
||||
|
|
||||
/* ---- PRIMARY ----*/ |
|
||||
.primary { |
|
||||
background-color: var(--blue); |
|
||||
border-color: var(--blue); |
|
||||
color: var(--white); |
|
||||
} |
|
||||
|
|
||||
.primary:hover { |
|
||||
background-color: var(--blue); |
|
||||
border-color: var(--blue); |
|
||||
} |
|
||||
|
|
||||
.primary:active { |
|
||||
background-color: var(--primarydark); |
|
||||
border-color: var(--primarydark); |
|
||||
} |
|
||||
|
|
||||
.primary-outline { |
|
||||
background-color: var(--white); |
|
||||
border-color: var(--blue); |
|
||||
color: var(--blue); |
|
||||
} |
|
||||
|
|
||||
.primary-outline:hover { |
|
||||
background-color: var(--primary10); |
|
||||
} |
|
||||
|
|
||||
.primary-outline:pressed { |
|
||||
background-color: var(--primary25); |
|
||||
} |
|
||||
|
|
||||
/* ---- secondary ----*/ |
|
||||
|
|
||||
.secondary { |
|
||||
background-color: var(--ink); |
|
||||
border-color: var(--ink); |
|
||||
color: var(--white); |
|
||||
} |
|
||||
|
|
||||
.secondary:hover { |
|
||||
background-color: var(--secondary75); |
|
||||
border-color: var(--secondary75); |
|
||||
} |
|
||||
|
|
||||
.secondary:pressed { |
|
||||
background-color: var(--secondarydark); |
|
||||
border-color: var(--secondarydark); |
|
||||
} |
|
||||
|
|
||||
.secondary-outline { |
|
||||
background-color: var(--white); |
|
||||
border-color: var(--ink); |
|
||||
color: var(--ink); |
|
||||
} |
|
||||
|
|
||||
.secondary-outline:hover { |
|
||||
background-color: var(--secondary10); |
|
||||
} |
|
||||
|
|
||||
.secondary-outline:pressed { |
|
||||
background-color: var(--secondary25); |
|
||||
} |
|
||||
|
|
||||
/* ---- success ----*/ |
|
||||
.success { |
|
||||
background-color: var(--success100); |
|
||||
border-color: var(--success100); |
|
||||
color: var(--white); |
|
||||
} |
|
||||
|
|
||||
.success:hover { |
|
||||
background-color: var(--success75); |
|
||||
border-color: var(--success75); |
|
||||
} |
|
||||
|
|
||||
.success:pressed { |
|
||||
background-color: var(--successdark); |
|
||||
border-color: var(--successdark); |
|
||||
} |
|
||||
|
|
||||
.success-outline { |
|
||||
background-color: var(--white); |
|
||||
border-color: var(--success100); |
|
||||
color: var(--success100); |
|
||||
} |
|
||||
|
|
||||
.success-outline:hover { |
|
||||
background-color: var(--success10); |
|
||||
} |
|
||||
|
|
||||
.success-outline:pressed { |
|
||||
background-color: var(--success25); |
|
||||
} |
|
||||
|
|
||||
/* ---- deletion ----*/ |
|
||||
.deletion { |
|
||||
background-color: var(--red); |
|
||||
border-color: var(--red); |
|
||||
color: var(--white); |
|
||||
} |
|
||||
|
|
||||
.deletion:hover { |
|
||||
background-color: var(--red-light); |
|
||||
border-color: var(--red); |
|
||||
color: var(--red); |
|
||||
} |
|
||||
|
|
||||
.deletion:pressed { |
|
||||
background-color: var(--red-dark); |
|
||||
border-color: var(--red-dark); |
|
||||
color: var(--white); |
|
||||
} |
|
||||
|
|
||||
.deletion-outline { |
|
||||
background-color: var(--white); |
|
||||
border-color: var(--red); |
|
||||
color: var(--red); |
|
||||
} |
|
||||
|
|
||||
.deletion-outline:hover { |
|
||||
background-color: var(--red-light); |
|
||||
color: var(--red); |
|
||||
} |
|
||||
|
|
||||
.deletion-outline:pressed { |
|
||||
background-color: var(--red-dark); |
|
||||
color: var(--white); |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,15 +0,0 @@ |
|||||
<script> |
|
||||
export let style = "" |
|
||||
</script> |
|
||||
|
|
||||
<div class="root" {style}> |
|
||||
<slot /> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.root { |
|
||||
display: flex; |
|
||||
flex-direction: row; |
|
||||
justify-content: space-between; |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,13 @@ |
|||||
|
<div class="dropdown-container" on:click> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.dropdown-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: flex-start; |
||||
|
align-items: stretch; |
||||
|
padding: var(--spacing-s) 0; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,70 @@ |
|||||
|
<script> |
||||
|
export let icon |
||||
|
export let title |
||||
|
export let subtitle |
||||
|
export let disabled |
||||
|
</script> |
||||
|
|
||||
|
<div |
||||
|
class="dropdown-item" |
||||
|
class:disabled |
||||
|
on:click |
||||
|
class:big={subtitle != null} |
||||
|
{...$$restProps}> |
||||
|
{#if icon}<i class={icon} />{/if} |
||||
|
<div class="content"> |
||||
|
<div class="title">{title}</div> |
||||
|
{#if subtitle != null} |
||||
|
<div class="subtitle">{subtitle}</div> |
||||
|
{/if} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.dropdown-item { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: flex-start; |
||||
|
align-items: center; |
||||
|
gap: var(--spacing-m); |
||||
|
padding: var(--spacing-xs) var(--spacing-l); |
||||
|
color: var(--ink); |
||||
|
} |
||||
|
.dropdown-item.disabled, |
||||
|
.dropdown-item.disabled .subtitle { |
||||
|
pointer-events: none; |
||||
|
color: var(--grey-5); |
||||
|
} |
||||
|
.dropdown-item.big { |
||||
|
padding: var(--spacing-s) var(--spacing-l); |
||||
|
} |
||||
|
.dropdown-item:not(.disabled):hover { |
||||
|
background-color: var(--grey-2); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
|
||||
|
.title, |
||||
|
.subtitle { |
||||
|
font-size: var(--font-size-xs); |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
.subtitle { |
||||
|
color: var(--grey-7); |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
i { |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,2 @@ |
|||||
|
export { default as DropdownContainer } from "./DropdownContainer.svelte" |
||||
|
export { default as DropdownItem } from "./DropdownItem.svelte" |
||||
@ -0,0 +1,109 @@ |
|||||
|
<script> |
||||
|
export let icon |
||||
|
export let withArrow = false |
||||
|
export let withActions = true |
||||
|
export let indentLevel = 0 |
||||
|
export let text |
||||
|
export let border = true |
||||
|
export let selected = false |
||||
|
export let opened = false |
||||
|
export let draggable = false |
||||
|
</script> |
||||
|
|
||||
|
<div |
||||
|
class="nav-item" |
||||
|
class:border |
||||
|
class:selected |
||||
|
style={`padding-left: ${indentLevel * 18}px`} |
||||
|
{draggable} |
||||
|
on:dragend |
||||
|
on:dragstart |
||||
|
on:dragover |
||||
|
on:drop |
||||
|
on:click |
||||
|
ondragover="return false" |
||||
|
ondragenter="return false"> |
||||
|
<div class="content"> |
||||
|
{#if withArrow} |
||||
|
<div class:opened class="icon arrow"> |
||||
|
<i class="ri-arrow-right-s-line" /> |
||||
|
</div> |
||||
|
{/if} |
||||
|
{#if icon} |
||||
|
<div class="icon"><i class={icon} /></div> |
||||
|
{/if} |
||||
|
<div class="text">{text}</div> |
||||
|
{#if withActions} |
||||
|
<div class="actions"> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
{/if} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.nav-item { |
||||
|
border-radius: var(--border-radius-m); |
||||
|
cursor: pointer; |
||||
|
color: var(--grey-7); |
||||
|
} |
||||
|
.nav-item.border { |
||||
|
border-top: 1px solid var(--grey-1); |
||||
|
} |
||||
|
.nav-item.selected { |
||||
|
background-color: var(--grey-2); |
||||
|
color: var(--ink); |
||||
|
} |
||||
|
.nav-item:hover { |
||||
|
background-color: var(--grey-1); |
||||
|
} |
||||
|
.nav-item:hover .actions { |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
padding: 0 var(--spacing-m); |
||||
|
height: 32px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: flex-start; |
||||
|
align-items: center; |
||||
|
gap: var(--spacing-xs); |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
font-size: 16px; |
||||
|
flex: 0 0 20px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
.icon.arrow { |
||||
|
margin: 0 -2px 0 -6px; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
.icon.arrow.opened { |
||||
|
transform: rotate(90deg); |
||||
|
} |
||||
|
.icon + .icon { |
||||
|
margin-left: -4px; |
||||
|
} |
||||
|
|
||||
|
.text { |
||||
|
flex: 1 1 auto; |
||||
|
font-weight: 500; |
||||
|
font-size: var(--font-size-xs); |
||||
|
} |
||||
|
|
||||
|
.actions { |
||||
|
display: none; |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
cursor: pointer; |
||||
|
position: relative; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
</style> |
||||
@ -1,36 +0,0 @@ |
|||||
<script> |
|
||||
export let value |
|
||||
export let label |
|
||||
|
|
||||
const inputChanged = ev => { |
|
||||
try { |
|
||||
value = Number(ev.target.value) |
|
||||
} catch (_) { |
|
||||
value = null |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
let numberText = value === null || value === undefined ? "" : value.toString() |
|
||||
</script> |
|
||||
|
|
||||
<div class="numberbox"> |
|
||||
<label>{label}</label> |
|
||||
<input |
|
||||
class="budibase__input" |
|
||||
type="number" |
|
||||
{value} |
|
||||
on:change={inputChanged} /> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.numberbox { |
|
||||
display: grid; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
label { |
|
||||
font-size: 14px; |
|
||||
font-weight: 500; |
|
||||
margin-bottom: 8px; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,76 +0,0 @@ |
|||||
<script> |
|
||||
export let tabs = [] |
|
||||
export const selectTab = tabName => { |
|
||||
selected = tabName |
|
||||
selectedIndex = tabs.indexOf(selected) |
|
||||
} |
|
||||
|
|
||||
let selected = tabs.length > 0 && tabs[0] |
|
||||
let selectedIndex = 0 |
|
||||
|
|
||||
const isSelected = tab => selected === tab |
|
||||
</script> |
|
||||
|
|
||||
<div class="root"> |
|
||||
<div class="switcher"> |
|
||||
{#each tabs as tab} |
|
||||
<button class:selected={selected === tab} on:click={() => selectTab(tab)}> |
|
||||
{tab} |
|
||||
</button> |
|
||||
{/each} |
|
||||
</div> |
|
||||
|
|
||||
<div class="panel"> |
|
||||
{#if selectedIndex === 0} |
|
||||
<slot name="0" /> |
|
||||
{:else if selectedIndex === 1} |
|
||||
<slot name="1" /> |
|
||||
{:else if selectedIndex === 2} |
|
||||
<slot name="2" /> |
|
||||
{:else if selectedIndex === 3} |
|
||||
<slot name="3" /> |
|
||||
{/if} |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.root { |
|
||||
height: 100%; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
padding: 20px 20px; |
|
||||
border-left: solid 1px var(--grey-2); |
|
||||
box-sizing: border-box; |
|
||||
} |
|
||||
|
|
||||
.switcher { |
|
||||
display: flex; |
|
||||
margin: 0px 20px 20px 0px; |
|
||||
box-sizing: border-box; |
|
||||
} |
|
||||
|
|
||||
.switcher > button { |
|
||||
display: inline-block; |
|
||||
border: none; |
|
||||
margin: 0; |
|
||||
padding: 0; |
|
||||
cursor: pointer; |
|
||||
font-size: 18px; |
|
||||
font-weight: 600; |
|
||||
color: var(--grey-5); |
|
||||
margin-right: 20px; |
|
||||
background: none; |
|
||||
outline: none; |
|
||||
font-family: Inter; |
|
||||
} |
|
||||
|
|
||||
.switcher > .selected { |
|
||||
color: var(--ink); |
|
||||
} |
|
||||
|
|
||||
.panel { |
|
||||
min-height: 0; |
|
||||
height: 100%; |
|
||||
overflow-y: auto; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,3 +0,0 @@ |
|||||
import { flow } from "lodash/fp" |
|
||||
|
|
||||
export const pipe = (arg, funcs) => flow(funcs)(arg) |
|
||||
@ -1,13 +0,0 @@ |
|||||
import { eventHandlers } from "../../../../client/src/state/eventHandlers" |
|
||||
export { EVENT_TYPE_MEMBER_NAME } from "../../../../client/src/state/eventHandlers" |
|
||||
|
|
||||
export const allHandlers = () => { |
|
||||
const handlersObj = eventHandlers() |
|
||||
|
|
||||
const handlers = Object.keys(handlersObj).map(name => ({ |
|
||||
name, |
|
||||
...handlersObj[name], |
|
||||
})) |
|
||||
|
|
||||
return handlers |
|
||||
} |
|
||||
@ -1,32 +1,36 @@ |
|||||
<script> |
<script> |
||||
import SettingsModal from "./SettingsModal.svelte" |
import SettingsModal from "./SettingsModal.svelte" |
||||
import { SettingsIcon } from "components/common/Icons/" |
|
||||
import { Modal } from "@budibase/bbui" |
import { Modal } from "@budibase/bbui" |
||||
|
|
||||
let modal |
let modal |
||||
</script> |
</script> |
||||
|
|
||||
<span class="topnavitemright settings" on:click={modal.show}> |
<div class="topnavitemright settings" on:click={modal.show}> |
||||
<SettingsIcon /> |
<i class="ri-settings-3-line" /> |
||||
</span> |
</div> |
||||
<Modal bind:this={modal} width="600px"> |
<Modal bind:this={modal} width="600px"> |
||||
<SettingsModal /> |
<SettingsModal /> |
||||
</Modal> |
</Modal> |
||||
|
|
||||
<style> |
<style> |
||||
span:first-letter { |
i { |
||||
text-transform: capitalize; |
font-size: 18px; |
||||
|
color: var(--grey-7); |
||||
} |
} |
||||
.topnavitemright { |
.topnavitemright { |
||||
cursor: pointer; |
cursor: pointer; |
||||
color: var(--grey-7); |
color: var(--grey-7); |
||||
margin: 0 20px 0 0; |
margin: 0 12px 0 0; |
||||
font-weight: 500; |
font-weight: 500; |
||||
font-size: 1rem; |
font-size: 1rem; |
||||
height: 100%; |
|
||||
display: flex; |
display: flex; |
||||
flex: 1; |
flex-direction: row; |
||||
|
justify-content: center; |
||||
align-items: center; |
align-items: center; |
||||
box-sizing: border-box; |
height: 24px; |
||||
|
width: 24px; |
||||
|
} |
||||
|
.topnavitemright:hover i { |
||||
|
color: var(--ink); |
||||
} |
} |
||||
</style> |
</style> |
||||
|
|||||
@ -1,13 +0,0 @@ |
|||||
<h3> |
|
||||
<slot /> |
|
||||
</h3> |
|
||||
|
|
||||
<style> |
|
||||
h3 { |
|
||||
font-size: 18px; |
|
||||
font-weight: bold; |
|
||||
color: var(--ink); |
|
||||
margin-top: 40px; |
|
||||
margin-bottom: 20px; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,50 +0,0 @@ |
|||||
<script> |
|
||||
export let item |
|
||||
</script> |
|
||||
|
|
||||
<div data-cy={item.name} class="item-item" on:click> |
|
||||
<div class="item-icon"><i class={item.icon} /></div> |
|
||||
<div class="item-text"> |
|
||||
<div class="item-name">{item.name}</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.item-item { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
cursor: pointer; |
|
||||
padding: 12px 16px 16px 16px; |
|
||||
height: 80px; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background-color: var(--grey-1); |
|
||||
border-radius: 5px; |
|
||||
} |
|
||||
|
|
||||
.item-item:hover { |
|
||||
background: var(--grey-2); |
|
||||
transition: all 0.3s; |
|
||||
} |
|
||||
|
|
||||
.item-icon { |
|
||||
border-radius: 3px; |
|
||||
display: flex; |
|
||||
} |
|
||||
|
|
||||
.item-text { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
.item-name { |
|
||||
font-size: 14px; |
|
||||
font-weight: 400; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
i { |
|
||||
font-size: 24px; |
|
||||
color: var(--grey-7); |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,52 +0,0 @@ |
|||||
<script> |
|
||||
import { createEventDispatcher } from "svelte" |
|
||||
import { store } from "builderStore" |
|
||||
import Item from "./Item.svelte" |
|
||||
|
|
||||
const dispatch = createEventDispatcher() |
|
||||
|
|
||||
export let list |
|
||||
|
|
||||
let category = list |
|
||||
|
|
||||
const handleClick = item => { |
|
||||
if (item.children && item.children.length > 0) { |
|
||||
list = item |
|
||||
} else { |
|
||||
dispatch("selectItem", item) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const goBack = () => { |
|
||||
list = category |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
{#if !list.isCategory} |
|
||||
<button class="back-button" on:click={goBack}>Back</button> |
|
||||
{/if} |
|
||||
{#each list.children as item} |
|
||||
{#if !item.showOnPages || item.showOnPages.includes($store.currentPageName)} |
|
||||
<Item {item} on:click={() => handleClick(item)} /> |
|
||||
{/if} |
|
||||
{/each} |
|
||||
|
|
||||
<style> |
|
||||
.back-button { |
|
||||
grid-column: 1 / span 2; |
|
||||
font-size: 14px; |
|
||||
text-align: center; |
|
||||
height: 36px; |
|
||||
border-radius: 5px; |
|
||||
border: solid 1px var(--grey-3); |
|
||||
background: white; |
|
||||
cursor: pointer; |
|
||||
font-weight: 500; |
|
||||
font-family: Inter; |
|
||||
transition: all 0.3ms; |
|
||||
} |
|
||||
|
|
||||
.back-button:hover { |
|
||||
background: var(--grey-1); |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,193 +0,0 @@ |
|||||
<script> |
|
||||
import ComponentsHierarchy from "./ComponentsHierarchy.svelte" |
|
||||
import ComponentsHierarchyChildren from "./ComponentsHierarchyChildren.svelte" |
|
||||
import PageLayout from "./PageLayout.svelte" |
|
||||
import PagesList from "./PagesList.svelte" |
|
||||
import { store } from "builderStore" |
|
||||
import NewScreenModal from "./NewScreenModal.svelte" |
|
||||
import CurrentItemPreview from "./AppPreview/CurrentItemPreview.svelte" |
|
||||
import SettingsView from "./SettingsView.svelte" |
|
||||
import ComponentsPaneSwitcher from "./ComponentsPaneSwitcher.svelte" |
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte" |
|
||||
import { last } from "lodash/fp" |
|
||||
import { AddIcon } from "components/common/Icons" |
|
||||
import { Modal } from "@budibase/bbui" |
|
||||
|
|
||||
let newScreenPicker |
|
||||
let confirmDeleteDialog |
|
||||
let componentToDelete = "" |
|
||||
let settingsView |
|
||||
let modal |
|
||||
|
|
||||
const settings = () => { |
|
||||
settingsView.show() |
|
||||
} |
|
||||
|
|
||||
const lastPartOfName = c => (c ? last(c.split("/")) : "") |
|
||||
</script> |
|
||||
|
|
||||
<div class="root"> |
|
||||
<div class="ui-nav"> |
|
||||
<div class="pages-list-container"> |
|
||||
<div class="nav-header"> |
|
||||
<span class="navigator-title">Navigator</span> |
|
||||
<span class="components-nav-page">Pages</span> |
|
||||
</div> |
|
||||
<div class="nav-items-container"> |
|
||||
<PagesList /> |
|
||||
</div> |
|
||||
</div> |
|
||||
<PageLayout layout={$store.pages[$store.currentPageName]} /> |
|
||||
<div class="components-list-container"> |
|
||||
<div class="nav-group-header"> |
|
||||
<span class="components-nav-header" style="margin-top: 0;"> |
|
||||
Screens |
|
||||
</span> |
|
||||
<div> |
|
||||
<button on:click={modal.show}> |
|
||||
<AddIcon /> |
|
||||
</button> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="nav-items-container"> |
|
||||
<ComponentsHierarchy screens={$store.screens} /> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="preview-pane"> |
|
||||
<CurrentItemPreview /> |
|
||||
</div> |
|
||||
{#if $store.currentFrontEndType === 'screen' || $store.currentFrontEndType === 'page'} |
|
||||
<div class="components-pane"> |
|
||||
<ComponentsPaneSwitcher /> |
|
||||
</div> |
|
||||
{/if} |
|
||||
</div> |
|
||||
|
|
||||
<Modal bind:this={modal}> |
|
||||
<NewScreenModal /> |
|
||||
</Modal> |
|
||||
|
|
||||
<SettingsView bind:this={settingsView} /> |
|
||||
|
|
||||
<style> |
|
||||
button { |
|
||||
cursor: pointer; |
|
||||
outline: none; |
|
||||
border: none; |
|
||||
border-radius: 5px; |
|
||||
width: 20px; |
|
||||
padding-bottom: 10px; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 0; |
|
||||
} |
|
||||
|
|
||||
.root { |
|
||||
display: grid; |
|
||||
grid-template-columns: 300px 1fr 300px; |
|
||||
height: 100%; |
|
||||
width: 100%; |
|
||||
background: var(--grey-1); |
|
||||
} |
|
||||
|
|
||||
.ui-nav { |
|
||||
grid-column: 1; |
|
||||
background-color: var(--white); |
|
||||
height: calc(100vh - 49px); |
|
||||
padding: 0; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
.preview-pane { |
|
||||
grid-column: 2; |
|
||||
margin: 40px; |
|
||||
background: #fff; |
|
||||
border-radius: 5px; |
|
||||
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05); |
|
||||
} |
|
||||
|
|
||||
.components-pane { |
|
||||
grid-column: 3; |
|
||||
background-color: var(--white); |
|
||||
height: calc(100vh - 49px); |
|
||||
} |
|
||||
|
|
||||
.components-nav-page { |
|
||||
font-size: 13px; |
|
||||
color: var(--ink); |
|
||||
text-transform: uppercase; |
|
||||
padding-left: 20px; |
|
||||
margin-top: 20px; |
|
||||
font-weight: 600; |
|
||||
opacity: 0.4; |
|
||||
} |
|
||||
|
|
||||
.components-nav-header { |
|
||||
font-size: 13px; |
|
||||
color: var(--ink); |
|
||||
text-transform: uppercase; |
|
||||
margin-top: 20px; |
|
||||
font-weight: 600; |
|
||||
opacity: 0.4; |
|
||||
} |
|
||||
|
|
||||
.nav-header { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
margin-top: 20px; |
|
||||
} |
|
||||
|
|
||||
.nav-items-container { |
|
||||
padding: 1rem 0rem 0rem 0rem; |
|
||||
} |
|
||||
|
|
||||
.nav-group-header { |
|
||||
display: flex; |
|
||||
padding: 0px 20px 0px 20px; |
|
||||
font-size: 0.9rem; |
|
||||
font-weight: bold; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.nav-group-header > div:nth-child(1) { |
|
||||
padding: 0rem 0.5rem 0rem 0rem; |
|
||||
vertical-align: bottom; |
|
||||
grid-column-start: icon; |
|
||||
margin-right: 5px; |
|
||||
} |
|
||||
|
|
||||
.nav-group-header > span:nth-child(3) { |
|
||||
margin-left: 5px; |
|
||||
vertical-align: bottom; |
|
||||
grid-column-start: title; |
|
||||
margin-top: auto; |
|
||||
} |
|
||||
|
|
||||
.nav-group-header > div:nth-child(3) { |
|
||||
vertical-align: bottom; |
|
||||
grid-column-start: button; |
|
||||
cursor: pointer; |
|
||||
color: var(--blue); |
|
||||
} |
|
||||
|
|
||||
.nav-group-header > div:nth-child(3):hover { |
|
||||
color: var(--blue); |
|
||||
} |
|
||||
|
|
||||
.navigator-title { |
|
||||
font-size: 14px; |
|
||||
color: var(--ink); |
|
||||
font-weight: 600; |
|
||||
text-transform: uppercase; |
|
||||
padding: 0 20px 20px 20px; |
|
||||
line-height: 1rem !important; |
|
||||
} |
|
||||
|
|
||||
.components-list-container { |
|
||||
padding: 10px 0px 0 0; |
|
||||
} |
|
||||
</style> |
|
||||
File diff suppressed because it is too large
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue