Fix prettier and fix crash when using certain views as data sources

This commit is contained in:
Andrew Kingston 2021-05-04 11:04:42 +01:00
parent d465fd8893
commit c010eeb314
229 changed files with 1752 additions and 1204 deletions

View File

@ -4,5 +4,5 @@
"singleQuote": false, "singleQuote": false,
"trailingComma": "es5", "trailingComma": "es5",
"plugins": ["prettier-plugin-svelte"], "plugins": ["prettier-plugin-svelte"],
"svelteSortOrder" : "scripts-markup-styles" "svelteSortOrder" : "options-scripts-markup-styles"
} }

View File

@ -14,7 +14,7 @@
"prettier-plugin-svelte": "^2.2.0", "prettier-plugin-svelte": "^2.2.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rollup-plugin-replace": "^2.2.0", "rollup-plugin-replace": "^2.2.0",
"svelte": "^3.30.0" "svelte": "^3.37.0"
}, },
"scripts": { "scripts": {
"bootstrap": "lerna link && lerna bootstrap", "bootstrap": "lerna link && lerna bootstrap",

View File

@ -42,12 +42,14 @@
class="spectrum-ActionButton spectrum-ActionButton--size{size}" class="spectrum-ActionButton spectrum-ActionButton--size{size}"
{disabled} {disabled}
on:longPress on:longPress
on:click|preventDefault> on:click|preventDefault
>
{#if longPressable} {#if longPressable}
<svg <svg
class="spectrum-Icon spectrum-UIIcon-CornerTriangle100 spectrum-ActionButton-hold" class="spectrum-Icon spectrum-UIIcon-CornerTriangle100 spectrum-ActionButton-hold"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-CornerTriangle100" /> <use xlink:href="#spectrum-css-icon-CornerTriangle100" />
</svg> </svg>
{/if} {/if}
@ -56,7 +58,8 @@
class="spectrum-Icon spectrum-Icon--size{size}" class="spectrum-Icon spectrum-Icon--size{size}"
focusable="false" focusable="false"
aria-hidden="true" aria-hidden="true"
aria-label={icon}> aria-label={icon}
>
<use xlink:href="#spectrum-icon-18-{icon}" /> <use xlink:href="#spectrum-icon-18-{icon}" />
</svg> </svg>
{/if} {/if}

View File

@ -23,13 +23,15 @@
class:active class:active
class="spectrum-Button spectrum-Button--size{size.toUpperCase()}" class="spectrum-Button spectrum-Button--size{size.toUpperCase()}"
{disabled} {disabled}
on:click|preventDefault> on:click|preventDefault
>
{#if icon} {#if icon}
<svg <svg
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}" class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
focusable="false" focusable="false"
aria-hidden="true" aria-hidden="true"
aria-label={icon}> aria-label={icon}
>
<use xlink:href="#spectrum-icon-18-{icon}" /> <use xlink:href="#spectrum-icon-18-{icon}" />
</svg> </svg>
{/if} {/if}

View File

@ -1,15 +1,19 @@
<script> <script>
import "@spectrum-css/buttongroup/dist/index-vars.css" import "@spectrum-css/buttongroup/dist/index-vars.css"
export let vertical = false export let vertical = false
function group(element) { function group(element) {
const buttons = Array.from(element.getElementsByTagName('button')) const buttons = Array.from(element.getElementsByTagName("button"))
buttons.forEach(button => { buttons.forEach((button) => {
button.classList.add('spectrum-ButtonGroup-item') button.classList.add("spectrum-ButtonGroup-item")
}) })
} }
</script> </script>
<div use:group class="spectrum-ButtonGroup" class:spectrum-ButtonGroup--vertical={vertical}> <div
<slot /> use:group
class="spectrum-ButtonGroup"
class:spectrum-ButtonGroup--vertical={vertical}
>
<slot />
</div> </div>

View File

@ -11,7 +11,7 @@
export let error = null export let error = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }

View File

@ -10,11 +10,11 @@
export let error = null export let error = null
export let placeholder = "Choose an option" export let placeholder = "Choose an option"
export let options = [] export let options = []
export let getOptionLabel = option => extractProperty(option, "label") export let getOptionLabel = (option) => extractProperty(option, "label")
export let getOptionValue = option => extractProperty(option, "value") export let getOptionValue = (option) => extractProperty(option, "value")
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -35,5 +35,6 @@
{placeholder} {placeholder}
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
on:change={onChange} /> on:change={onChange}
/>
</Field> </Field>

View File

@ -10,34 +10,38 @@
export let disabled = false export let disabled = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = event => { const onChange = (event) => {
dispatch("change", event.target.checked) dispatch("change", event.target.checked)
} }
</script> </script>
<label <label
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized" class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"
class:is-invalid={!!error}> class:is-invalid={!!error}
>
<input <input
checked={value} checked={value}
{disabled} {disabled}
on:change={onChange} on:change={onChange}
type="checkbox" type="checkbox"
class="spectrum-Checkbox-input" class="spectrum-Checkbox-input"
{id} /> {id}
/>
<span class="spectrum-Checkbox-box"> <span class="spectrum-Checkbox-box">
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark" class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Checkmark100" /> <use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg> </svg>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark" class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Dash100" /> <use xlink:href="#spectrum-css-icon-Dash100" />
</svg> </svg>
</span> </span>
<span class="spectrum-Checkbox-label">{text || ''}</span> <span class="spectrum-Checkbox-label">{text || ""}</span>
</label> </label>

View File

@ -11,8 +11,8 @@
export let disabled = false export let disabled = false
export let error = null export let error = null
export let options = [] export let options = []
export let getOptionLabel = option => option export let getOptionLabel = (option) => option
export let getOptionValue = option => option export let getOptionValue = (option) => option
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let open = false let open = false
@ -31,16 +31,16 @@
} }
// Render the label if the selected option is found, otherwise raw value // Render the label if the selected option is found, otherwise raw value
const selected = options.find(option => getOptionValue(option) === value) const selected = options.find((option) => getOptionValue(option) === value)
return selected ? getOptionLabel(selected) : value return selected ? getOptionLabel(selected) : value
} }
const selectOption = value => { const selectOption = (value) => {
dispatch("change", value) dispatch("change", value)
open = false open = false
} }
const onChange = e => { const onChange = (e) => {
selectOption(e.target.value) selectOption(e.target.value)
} }
</script> </script>
@ -49,7 +49,8 @@
<div <div
class="spectrum-Textfield spectrum-InputGroup-textfield" class="spectrum-Textfield spectrum-InputGroup-textfield"
class:is-disabled={!!error} class:is-disabled={!!error}
class:is-focused={open || focus}> class:is-focused={open || focus}
>
<input <input
type="text" type="text"
on:focus={() => (focus = true)} on:focus={() => (focus = true)}
@ -57,18 +58,21 @@
on:change={onChange} on:change={onChange}
{value} {value}
{placeholder} {placeholder}
class="spectrum-Textfield-input spectrum-InputGroup-input" /> class="spectrum-Textfield-input spectrum-InputGroup-input"
/>
</div> </div>
<button <button
class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button" class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
tabindex="-1" tabindex="-1"
aria-haspopup="true" aria-haspopup="true"
disabled={!!error} disabled={!!error}
on:click={() => (open = true)}> on:click={() => (open = true)}
>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon spectrum-InputGroup-icon" class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon spectrum-InputGroup-icon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Chevron100" /> <use xlink:href="#spectrum-css-icon-Chevron100" />
</svg> </svg>
</button> </button>
@ -76,7 +80,8 @@
<div class="overlay" on:mousedown|self={() => (open = false)} /> <div class="overlay" on:mousedown|self={() => (open = false)} />
<div <div
transition:fly={{ y: -20, duration: 200 }} transition:fly={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom is-open"> class="spectrum-Popover spectrum-Popover--bottom is-open"
>
<ul class="spectrum-Menu" role="listbox"> <ul class="spectrum-Menu" role="listbox">
{#if options && Array.isArray(options)} {#if options && Array.isArray(options)}
{#each options as option} {#each options as option}
@ -86,13 +91,16 @@
role="option" role="option"
aria-selected="true" aria-selected="true"
tabindex="0" tabindex="0"
on:click={() => selectOption(getOptionValue(option))}> on:click={() => selectOption(getOptionValue(option))}
<span >
class="spectrum-Menu-itemLabel">{getOptionLabel(option)}</span> <span class="spectrum-Menu-itemLabel"
>{getOptionLabel(option)}</span
>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon" class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Checkmark100" /> <use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg> </svg>
</li> </li>

View File

@ -27,12 +27,12 @@
wrap: true, wrap: true,
} }
const handleChange = event => { const handleChange = (event) => {
const [dates] = event.detail const [dates] = event.detail
dispatch("change", dates[0]) dispatch("change", dates[0])
} }
const clearDateOnBackspace = event => { const clearDateOnBackspace = (event) => {
if (["Backspace", "Clear", "Delete"].includes(event.key)) { if (["Backspace", "Clear", "Delete"].includes(event.key)) {
dispatch("change", null) dispatch("change", null)
flatpickr.close() flatpickr.close()
@ -53,7 +53,7 @@
// We need to blur both because the focus styling does not get properly // We need to blur both because the focus styling does not get properly
// applied. // applied.
const els = document.querySelectorAll(`#${flatpickrId} input`) const els = document.querySelectorAll(`#${flatpickrId} input`)
els.forEach(el => el.blur()) els.forEach((el) => el.blur())
} }
</script> </script>
@ -64,7 +64,8 @@
on:close={onClose} on:close={onClose}
options={flatpickrOptions} options={flatpickrOptions}
on:change={handleChange} on:change={handleChange}
element={`#${flatpickrId}`}> element={`#${flatpickrId}`}
>
<div <div
id={flatpickrId} id={flatpickrId}
class:is-disabled={disabled} class:is-disabled={disabled}
@ -73,17 +74,20 @@
class:is-focused={open} class:is-focused={open}
aria-readonly="false" aria-readonly="false"
aria-required="false" aria-required="false"
aria-haspopup="true"> aria-haspopup="true"
>
<div <div
on:click={flatpickr?.open} on:click={flatpickr?.open}
class="spectrum-Textfield spectrum-InputGroup-textfield" class="spectrum-Textfield spectrum-InputGroup-textfield"
class:is-disabled={disabled} class:is-disabled={disabled}
class:is-invalid={!!error}> class:is-invalid={!!error}
>
{#if !!error} {#if !!error}
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon" class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-Alert" /> <use xlink:href="#spectrum-icon-18-Alert" />
</svg> </svg>
{/if} {/if}
@ -94,7 +98,8 @@
class="spectrum-Textfield-input spectrum-InputGroup-input" class="spectrum-Textfield-input spectrum-InputGroup-input"
{placeholder} {placeholder}
{id} {id}
{value} /> {value}
/>
</div> </div>
<button <button
type="button" type="button"
@ -102,12 +107,14 @@
tabindex="-1" tabindex="-1"
{disabled} {disabled}
class:is-invalid={!!error} class:is-invalid={!!error}
on:click={flatpickr?.open}> on:click={flatpickr?.open}
>
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM" class="spectrum-Icon spectrum-Icon--sizeM"
focusable="false" focusable="false"
aria-hidden="true" aria-hidden="true"
aria-label="Calendar"> aria-label="Calendar"
>
<use xlink:href="#spectrum-icon-18-Calendar" /> <use xlink:href="#spectrum-icon-18-Calendar" />
</svg> </svg>
</button> </button>

View File

@ -28,7 +28,7 @@
"bmp", "bmp",
"jfif", "jfif",
] ]
const onChange = event => { const onChange = (event) => {
dispatch("change", event.target.checked) dispatch("change", event.target.checked)
} }
@ -42,7 +42,7 @@
async function processFileList(fileList) { async function processFileList(fileList) {
if ( if (
handleFileTooLarge && handleFileTooLarge &&
Array.from(fileList).some(file => file.size >= fileSizeLimit) Array.from(fileList).some((file) => file.size >= fileSizeLimit)
) { ) {
handleFileTooLarge(fileSizeLimit, value) handleFileTooLarge(fileSizeLimit, value)
return return
@ -119,13 +119,15 @@
<div <div
class="nav left" class="nav left"
class:visible={selectedImageIdx > 0} class:visible={selectedImageIdx > 0}
on:click={navigateLeft}> on:click={navigateLeft}
>
<Icon name="ChevronLeft" /> <Icon name="ChevronLeft" />
</div> </div>
<div <div
class="nav right" class="nav right"
class:visible={selectedImageIdx < fileCount - 1} class:visible={selectedImageIdx < fileCount - 1}
on:click={navigateRight}> on:click={navigateRight}
>
<Icon name="ChevronRight" /> <Icon name="ChevronRight" />
</div> </div>
<div class="footer">File {selectedImageIdx + 1} of {fileCount}</div> <div class="footer">File {selectedImageIdx + 1} of {fileCount}</div>
@ -140,19 +142,22 @@
on:dragleave={handleDragLeave} on:dragleave={handleDragLeave}
on:dragenter={handleDragOver} on:dragenter={handleDragOver}
on:drop={handleDrop} on:drop={handleDrop}
class:is-dragged={fileDragged}> class:is-dragged={fileDragged}
>
<div class="spectrum-IllustratedMessage spectrum-IllustratedMessage--cta"> <div class="spectrum-IllustratedMessage spectrum-IllustratedMessage--cta">
<input <input
id={fieldId} id={fieldId}
{disabled} {disabled}
type="file" type="file"
multiple multiple
on:change={handleFile} /> on:change={handleFile}
/>
<svg <svg
class="spectrum-IllustratedMessage-illustration" class="spectrum-IllustratedMessage-illustration"
width="125" width="125"
height="60" height="60"
viewBox="0 0 199 97.7"><defs> viewBox="0 0 199 97.7"
><defs>
<style> <style>
.cls-1, .cls-1,
.cls-2 { .cls-2 {
@ -170,25 +175,31 @@
</defs> </defs>
<path <path
class="cls-1" class="cls-1"
d="M110.53,85.66,100.26,95.89a1.09,1.09,0,0,1-1.52,0L88.47,85.66" /> d="M110.53,85.66,100.26,95.89a1.09,1.09,0,0,1-1.52,0L88.47,85.66"
/>
<line class="cls-1" x1="99.5" y1="95.5" x2="99.5" y2="58.5" /> <line class="cls-1" x1="99.5" y1="95.5" x2="99.5" y2="58.5" />
<path class="cls-1" d="M105.5,73.5h19a2,2,0,0,0,2-2v-43" /> <path class="cls-1" d="M105.5,73.5h19a2,2,0,0,0,2-2v-43" />
<path <path
class="cls-1" class="cls-1"
d="M126.5,22.5h-19a2,2,0,0,1-2-2V1.5h-31a2,2,0,0,0-2,2v68a2,2,0,0,0,2,2h19" /> d="M126.5,22.5h-19a2,2,0,0,1-2-2V1.5h-31a2,2,0,0,0-2,2v68a2,2,0,0,0,2,2h19"
/>
<line class="cls-1" x1="105.5" y1="1.5" x2="126.5" y2="22.5" /> <line class="cls-1" x1="105.5" y1="1.5" x2="126.5" y2="22.5" />
<path <path
class="cls-2" class="cls-2"
d="M47.93,50.49a5,5,0,1,0-4.83-5A4.93,4.93,0,0,0,47.93,50.49Z" /> d="M47.93,50.49a5,5,0,1,0-4.83-5A4.93,4.93,0,0,0,47.93,50.49Z"
/>
<path <path
class="cls-2" class="cls-2"
d="M36.6,65.93,42.05,60A2.06,2.06,0,0,1,45,60l12.68,13.2" /> d="M36.6,65.93,42.05,60A2.06,2.06,0,0,1,45,60l12.68,13.2"
/>
<path <path
class="cls-2" class="cls-2"
d="M3.14,73.23,22.42,53.76a1.65,1.65,0,0,1,2.38,0l19.05,19.7" /> d="M3.14,73.23,22.42,53.76a1.65,1.65,0,0,1,2.38,0l19.05,19.7"
/>
<path <path
class="cls-1" class="cls-1"
d="M139.5,36.5H196A1.49,1.49,0,0,1,197.5,38V72A1.49,1.49,0,0,1,196,73.5H141A1.49,1.49,0,0,1,139.5,72V32A1.49,1.49,0,0,1,141,30.5H154a2.43,2.43,0,0,1,1.67.66l6,5.66" /> d="M139.5,36.5H196A1.49,1.49,0,0,1,197.5,38V72A1.49,1.49,0,0,1,196,73.5H141A1.49,1.49,0,0,1,139.5,72V32A1.49,1.49,0,0,1,141,30.5H154a2.43,2.43,0,0,1,1.67.66l6,5.66"
/>
<rect <rect
class="cls-1" class="cls-1"
x="1.5" x="1.5"
@ -196,16 +207,21 @@
width="58" width="58"
height="39" height="39"
rx="2" rx="2"
ry="2" /> ry="2"
/>
</svg> </svg>
<h2 <h2
class="spectrum-Heading spectrum-Heading--sizeL spectrum-Heading--light spectrum-IllustratedMessage-heading"> class="spectrum-Heading spectrum-Heading--sizeL spectrum-Heading--light spectrum-IllustratedMessage-heading"
>
Drag and drop your file Drag and drop your file
</h2> </h2>
{#if !disabled} {#if !disabled}
<p <p
class="spectrum-Body spectrum-Body--sizeS spectrum-IllustratedMessage-description"> class="spectrum-Body spectrum-Body--sizeS spectrum-IllustratedMessage-description"
<label for={fieldId} class="spectrum-Link">Select a file to upload</label> >
<label for={fieldId} class="spectrum-Link"
>Select a file to upload</label
>
<br /> <br />
from your computer from your computer
</p> </p>

View File

@ -8,14 +8,14 @@
export let disabled = false export let disabled = false
export let error = null export let error = null
export let options = [] export let options = []
export let getOptionLabel = option => option export let getOptionLabel = (option) => option
export let getOptionValue = option => option export let getOptionValue = (option) => option
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
$: selectedLookupMap = getSelectedLookupMap(value) $: selectedLookupMap = getSelectedLookupMap(value)
$: optionLookupMap = getOptionLookupMap(options) $: optionLookupMap = getOptionLookupMap(options)
$: fieldText = getFieldText(value, optionLookupMap, placeholder) $: fieldText = getFieldText(value, optionLookupMap, placeholder)
$: isOptionSelected = optionValue => selectedLookupMap[optionValue] === true $: isOptionSelected = (optionValue) => selectedLookupMap[optionValue] === true
$: toggleOption = makeToggleOption(selectedLookupMap, value) $: toggleOption = makeToggleOption(selectedLookupMap, value)
const getFieldText = (value, map, placeholder) => { const getFieldText = (value, map, placeholder) => {
@ -23,17 +23,17 @@
if (!map) { if (!map) {
return "" return ""
} }
const vals = value.map(option => map[option] || option).join(", ") const vals = value.map((option) => map[option] || option).join(", ")
return `(${value.length}) ${vals}` return `(${value.length}) ${vals}`
} else { } else {
return placeholder || "Choose some options" return placeholder || "Choose some options"
} }
} }
const getSelectedLookupMap = value => { const getSelectedLookupMap = (value) => {
let map = {} let map = {}
if (value?.length) { if (value?.length) {
value.forEach(option => { value.forEach((option) => {
if (option) { if (option) {
map[option] = true map[option] = true
} }
@ -42,7 +42,7 @@
return map return map
} }
const getOptionLookupMap = options => { const getOptionLookupMap = (options) => {
let map = null let map = null
if (options?.length) { if (options?.length) {
map = {} map = {}
@ -57,9 +57,9 @@
} }
const makeToggleOption = (map, value) => { const makeToggleOption = (map, value) => {
return optionValue => { return (optionValue) => {
if (map[optionValue]) { if (map[optionValue]) {
const filtered = value.filter(option => option !== optionValue) const filtered = value.filter((option) => option !== optionValue)
dispatch("change", filtered) dispatch("change", filtered)
} else { } else {
dispatch("change", [...value, optionValue]) dispatch("change", [...value, optionValue])
@ -78,4 +78,5 @@
{isOptionSelected} {isOptionSelected}
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
onSelectOption={toggleOption} /> onSelectOption={toggleOption}
/>

View File

@ -15,13 +15,13 @@
export let options = [] export let options = []
export let isOptionSelected = () => false export let isOptionSelected = () => false
export let onSelectOption = () => {} export let onSelectOption = () => {}
export let getOptionLabel = option => option export let getOptionLabel = (option) => option
export let getOptionValue = option => option export let getOptionValue = (option) => option
export let open = false export let open = false
export let readonly = false export let readonly = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onClick = e => { const onClick = (e) => {
dispatch("click") dispatch("click")
if (readonly) { if (readonly) {
return return
@ -37,7 +37,8 @@
class:is-invalid={!!error} class:is-invalid={!!error}
class:is-open={open} class:is-open={open}
aria-haspopup="listbox" aria-haspopup="listbox"
on:mousedown={onClick}> on:mousedown={onClick}
>
<span class="spectrum-Picker-label" class:is-placeholder={isPlaceholder}> <span class="spectrum-Picker-label" class:is-placeholder={isPlaceholder}>
{fieldText} {fieldText}
</span> </span>
@ -46,14 +47,16 @@
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon" class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon"
focusable="false" focusable="false"
aria-hidden="true" aria-hidden="true"
aria-label="Folder"> aria-label="Folder"
>
<use xlink:href="#spectrum-icon-18-Alert" /> <use xlink:href="#spectrum-icon-18-Alert" />
</svg> </svg>
{/if} {/if}
<svg <svg
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon" class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Chevron100" /> <use xlink:href="#spectrum-css-icon-Chevron100" />
</svg> </svg>
</button> </button>
@ -61,7 +64,8 @@
<div <div
use:clickOutside={() => (open = false)} use:clickOutside={() => (open = false)}
transition:fly={{ y: -20, duration: 200 }} transition:fly={{ y: -20, duration: 200 }}
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"> class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
>
<ul class="spectrum-Menu" role="listbox"> <ul class="spectrum-Menu" role="listbox">
{#if placeholderOption} {#if placeholderOption}
<li <li
@ -70,12 +74,14 @@
role="option" role="option"
aria-selected="true" aria-selected="true"
tabindex="0" tabindex="0"
on:click={() => onSelectOption(null)}> on:click={() => onSelectOption(null)}
>
<span class="spectrum-Menu-itemLabel">{placeholderOption}</span> <span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon" class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Checkmark100" /> <use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg> </svg>
</li> </li>
@ -88,13 +94,16 @@
role="option" role="option"
aria-selected="true" aria-selected="true"
tabindex="0" tabindex="0"
on:click={() => onSelectOption(getOptionValue(option, idx))}> on:click={() => onSelectOption(getOptionValue(option, idx))}
<span >
class="spectrum-Menu-itemLabel">{getOptionLabel(option, idx)}</span> <span class="spectrum-Menu-itemLabel"
>{getOptionLabel(option, idx)}</span
>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon" class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Checkmark100" /> <use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg> </svg>
</li> </li>

View File

@ -8,11 +8,11 @@
export let options = [] export let options = []
export let error = null export let error = null
export let disabled = false export let disabled = false
export let getOptionLabel = option => option export let getOptionLabel = (option) => option
export let getOptionValue = option => option export let getOptionValue = (option) => option
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => dispatch("change", e.target.value) const onChange = (e) => dispatch("change", e.target.value)
</script> </script>
<div class={`spectrum-FieldGroup spectrum-FieldGroup--${direction}`}> <div class={`spectrum-FieldGroup spectrum-FieldGroup--${direction}`}>
@ -21,14 +21,16 @@
<div <div
title={getOptionLabel(option)} title={getOptionLabel(option)}
class="spectrum-Radio spectrum-FieldGroup-item spectrum-Radio--emphasized" class="spectrum-Radio spectrum-FieldGroup-item spectrum-Radio--emphasized"
class:is-invalid={!!error}> class:is-invalid={!!error}
>
<input <input
on:change={onChange} on:change={onChange}
bind:group={value} bind:group={value}
value={getOptionValue(option)} value={getOptionValue(option)}
type="radio" type="radio"
class="spectrum-Radio-input" class="spectrum-Radio-input"
{disabled} /> {disabled}
/>
<span class="spectrum-Radio-button" /> <span class="spectrum-Radio-button" />
<label class="spectrum-Radio-label">{getOptionLabel(option)}</label> <label class="spectrum-Radio-label">{getOptionLabel(option)}</label>
</div> </div>

View File

@ -10,7 +10,7 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let focus = false let focus = false
const updateValue = value => { const updateValue = (value) => {
dispatch("change", value) dispatch("change", value)
} }
@ -18,12 +18,12 @@
focus = true focus = true
} }
const onBlur = event => { const onBlur = (event) => {
focus = false focus = false
updateValue(event.target.value) updateValue(event.target.value)
} }
const updateValueOnEnter = event => { const updateValueOnEnter = (event) => {
if (event.key === "Enter") { if (event.key === "Enter") {
updateValue(event.target.value) updateValue(event.target.value)
} }
@ -34,11 +34,13 @@
<div <div
class="spectrum-Textfield" class="spectrum-Textfield"
class:is-focused={focus} class:is-focused={focus}
class:is-disabled={disabled}> class:is-disabled={disabled}
>
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-icon" class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-icon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-Magnify" /> <use xlink:href="#spectrum-icon-18-Magnify" />
</svg> </svg>
<input <input
@ -46,23 +48,26 @@
on:keyup={updateValueOnEnter} on:keyup={updateValueOnEnter}
{disabled} {disabled}
{id} {id}
value={value || ''} value={value || ""}
placeholder={placeholder || ''} placeholder={placeholder || ""}
on:blur={onBlur} on:blur={onBlur}
on:focus={onFocus} on:focus={onFocus}
on:input on:input
type="search" type="search"
class="spectrum-Textfield-input spectrum-Search-input" class="spectrum-Textfield-input spectrum-Search-input"
autocomplete="off" /> autocomplete="off"
/>
</div> </div>
<button <button
on:click={() => updateValue('')} on:click={() => updateValue("")}
type="reset" type="reset"
class="spectrum-ClearButton spectrum-Search-clearButton"> class="spectrum-ClearButton spectrum-Search-clearButton"
>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Cross75" class="spectrum-Icon spectrum-UIIcon-Cross75"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Cross75" /> <use xlink:href="#spectrum-css-icon-Cross75" />
</svg> </svg>
</button> </button>

View File

@ -8,8 +8,8 @@
export let disabled = false export let disabled = false
export let error = null export let error = null
export let options = [] export let options = []
export let getOptionLabel = option => option export let getOptionLabel = (option) => option
export let getOptionValue = option => option export let getOptionValue = (option) => option
export let readonly = false export let readonly = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -34,7 +34,7 @@
return index !== -1 ? getOptionLabel(options[index], index) : value return index !== -1 ? getOptionLabel(options[index], index) : value
} }
const selectOption = value => { const selectOption = (value) => {
dispatch("change", value) dispatch("change", value)
open = false open = false
} }
@ -51,7 +51,8 @@
{options} {options}
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
isPlaceholder={value == null || value === ''} isPlaceholder={value == null || value === ""}
placeholderOption={placeholder} placeholderOption={placeholder}
isOptionSelected={option => option === value} isOptionSelected={(option) => option === value}
onSelectOption={selectOption} /> onSelectOption={selectOption}
/>

View File

@ -9,7 +9,7 @@
export let disabled = false export let disabled = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = event => { const onChange = (event) => {
dispatch("change", event.target.checked) dispatch("change", event.target.checked)
} }
</script> </script>
@ -21,7 +21,8 @@
on:change={onChange} on:change={onChange}
{id} {id}
type="checkbox" type="checkbox"
class="spectrum-Switch-input" /> class="spectrum-Switch-input"
/>
<span class="spectrum-Switch-switch" /> <span class="spectrum-Switch-switch" />
<label class="spectrum-Switch-label" for={id}>{text}</label> <label class="spectrum-Switch-label" for={id}>{text}</label>
</div> </div>

View File

@ -15,7 +15,7 @@
let focus = false let focus = false
let textarea let textarea
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = event => { const onChange = (event) => {
dispatch("change", event.target.value) dispatch("change", event.target.value)
focus = false focus = false
} }
@ -25,23 +25,28 @@
class="spectrum-Textfield spectrum-Textfield--multiline" class="spectrum-Textfield spectrum-Textfield--multiline"
class:is-invalid={!!error} class:is-invalid={!!error}
class:is-disabled={disabled} class:is-disabled={disabled}
class:is-focused={focus}> class:is-focused={focus}
>
{#if error} {#if error}
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon" class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-Alert" /> <use xlink:href="#spectrum-icon-18-Alert" />
</svg> </svg>
{/if} {/if}
<textarea <textarea
bind:this={textarea} bind:this={textarea}
placeholder={placeholder || ''} placeholder={placeholder || ""}
class="spectrum-Textfield-input" class="spectrum-Textfield-input"
{disabled} {disabled}
{id} {id}
on:focus={() => (focus = true)} on:focus={() => (focus = true)}
on:blur={onChange}>{value || ''}</textarea> on:blur={onChange}
>
{value || ""}
</textarea>
</div> </div>
<style> <style>

View File

@ -13,7 +13,7 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let focus = false let focus = false
const updateValue = value => { const updateValue = (value) => {
if (readonly) { if (readonly) {
return return
} }
@ -31,7 +31,7 @@
focus = true focus = true
} }
const onBlur = event => { const onBlur = (event) => {
if (readonly) { if (readonly) {
return return
} }
@ -39,7 +39,7 @@
updateValue(event.target.value) updateValue(event.target.value)
} }
const updateValueOnEnter = event => { const updateValueOnEnter = (event) => {
if (readonly) { if (readonly) {
return return
} }
@ -53,12 +53,14 @@
class="spectrum-Textfield" class="spectrum-Textfield"
class:is-invalid={!!error} class:is-invalid={!!error}
class:is-disabled={disabled} class:is-disabled={disabled}
class:is-focused={focus}> class:is-focused={focus}
>
{#if error} {#if error}
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon" class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-Alert" /> <use xlink:href="#spectrum-icon-18-Alert" />
</svg> </svg>
{/if} {/if}
@ -68,13 +70,14 @@
{disabled} {disabled}
{readonly} {readonly}
{id} {id}
value={value || ''} value={value || ""}
placeholder={placeholder || ''} placeholder={placeholder || ""}
on:blur={onBlur} on:blur={onBlur}
on:focus={onFocus} on:focus={onFocus}
on:input on:input
{type} {type}
class="spectrum-Textfield-input" /> class="spectrum-Textfield-input"
/>
</div> </div>
<style> <style>

View File

@ -12,7 +12,7 @@
export let placeholder = null export let placeholder = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -25,5 +25,6 @@
{value} {value}
{placeholder} {placeholder}
{enableTime} {enableTime}
on:change={onChange} /> on:change={onChange}
/>
</Field> </Field>

View File

@ -13,7 +13,7 @@
export let handleFileTooLarge = undefined export let handleFileTooLarge = undefined
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -27,5 +27,6 @@
{fileSizeLimit} {fileSizeLimit}
{processFiles} {processFiles}
{handleFileTooLarge} {handleFileTooLarge}
on:change={onChange} /> on:change={onChange}
/>
</Field> </Field>

View File

@ -9,7 +9,7 @@
export let error = null export let error = null
</script> </script>
<div class="spectrum-Form-item" class:above={labelPosition === 'above'}> <div class="spectrum-Form-item" class:above={labelPosition === "above"}>
{#if label} {#if label}
<FieldLabel forId={id} {label} position={labelPosition} /> <FieldLabel forId={id} {label} position={labelPosition} />
{/if} {/if}

View File

@ -10,8 +10,9 @@
<label <label
for={forId} for={forId}
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${className}`}> class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${className}`}
{label || ''} >
{label || ""}
</label> </label>
<style> <style>

View File

@ -13,7 +13,7 @@
export let error = null export let error = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -29,5 +29,6 @@
{type} {type}
on:change={onChange} on:change={onChange}
on:click on:click
on:input /> on:input
/>
</Field> </Field>

View File

@ -11,11 +11,11 @@
export let error = null export let error = null
export let placeholder = null export let placeholder = null
export let options = [] export let options = []
export let getOptionLabel = option => option export let getOptionLabel = (option) => option
export let getOptionValue = option => option export let getOptionValue = (option) => option
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -31,5 +31,6 @@
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
on:change={onChange} on:change={onChange}
on:click /> on:click
/>
</Field> </Field>

View File

@ -9,11 +9,11 @@
export let labelPosition = "above" export let labelPosition = "above"
export let error = null export let error = null
export let options = [] export let options = []
export let getOptionLabel = option => extractProperty(option, "label") export let getOptionLabel = (option) => extractProperty(option, "label")
export let getOptionValue = option => extractProperty(option, "value") export let getOptionValue = (option) => extractProperty(option, "value")
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -33,5 +33,6 @@
{options} {options}
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
on:change={onChange} /> on:change={onChange}
/>
</Field> </Field>

View File

@ -10,7 +10,7 @@
export let disabled = false export let disabled = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -23,5 +23,6 @@
{placeholder} {placeholder}
on:change={onChange} on:change={onChange}
on:click on:click
on:input /> on:input
/>
</Field> </Field>

View File

@ -11,11 +11,11 @@
export let error = null export let error = null
export let placeholder = "Choose an option" export let placeholder = "Choose an option"
export let options = [] export let options = []
export let getOptionLabel = option => extractProperty(option, "label") export let getOptionLabel = (option) => extractProperty(option, "label")
export let getOptionValue = option => extractProperty(option, "value") export let getOptionValue = (option) => extractProperty(option, "value")
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -38,5 +38,6 @@
{getOptionLabel} {getOptionLabel}
{getOptionValue} {getOptionValue}
on:change={onChange} on:change={onChange}
on:click /> on:click
/>
</Field> </Field>

View File

@ -12,7 +12,7 @@
export let getCaretPosition = null export let getCaretPosition = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }
@ -25,5 +25,6 @@
{disabled} {disabled}
{value} {value}
{placeholder} {placeholder}
on:change={onChange} /> on:change={onChange}
/>
</Field> </Field>

View File

@ -11,7 +11,7 @@
export let error = null export let error = null
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const onChange = e => { const onChange = (e) => {
value = e.detail value = e.detail
dispatch("change", e.detail) dispatch("change", e.detail)
} }

View File

@ -17,4 +17,5 @@
class:spectrum-Link--secondary={secondary} class:spectrum-Link--secondary={secondary}
class:spectrum-Link--overBackground={overBackground} class:spectrum-Link--overBackground={overBackground}
class:spectrum-Link--quiet={quiet} class:spectrum-Link--quiet={quiet}
class="spectrum-Link spectrum-Link--size{size}"><slot /></a> class="spectrum-Link spectrum-Link--size{size}"><slot /></a
>

View File

@ -1,7 +1,7 @@
<script> <script>
import "@spectrum-css/menu/dist/index-vars.css" import "@spectrum-css/menu/dist/index-vars.css"
</script> </script>
<ul class="spectrum-Menu" role="menu"> <ul class="spectrum-Menu" role="menu">
<slot /> <slot />
</ul> </ul>

View File

@ -1,9 +1,10 @@
<script> <script>
export let heading export let heading
</script> </script>
<li role="presentation"> <li role="presentation">
<span class="spectrum-Menu-sectionHeading">{heading}</span> <span class="spectrum-Menu-sectionHeading">{heading}</span>
<ul class="spectrum-Menu" role="group"> <ul class="spectrum-Menu" role="group">
<slot /> <slot />
</ul> </ul>
</li> </li>

View File

@ -1 +1 @@
<li class="spectrum-Menu-divider" role="separator"></li> <li class="spectrum-Menu-divider" role="separator" />

View File

@ -17,7 +17,7 @@
<div on:click={increment}> <div on:click={increment}>
Click me Click me
{remaining} {remaining}
more time{remaining === 1 ? '' : 's'} more time{remaining === 1 ? "" : "s"}
to close this modal! to close this modal!
</div> </div>

View File

@ -50,13 +50,15 @@
<div <div
class="spectrum-Underlay is-open" class="spectrum-Underlay is-open"
transition:fade={{ duration: 200 }} transition:fade={{ duration: 200 }}
on:mousedown|self={hide}> on:mousedown|self={hide}
>
<div class="modal-wrapper" on:mousedown|self={hide}> <div class="modal-wrapper" on:mousedown|self={hide}>
<div class="modal-inner-wrapper" on:mousedown|self={hide}> <div class="modal-inner-wrapper" on:mousedown|self={hide}>
<div <div
use:focusFirstInput use:focusFirstInput
class="spectrum-Modal is-open" class="spectrum-Modal is-open"
transition:fly={{ y: 30, duration: 200 }}> transition:fly={{ y: 30, duration: 200 }}
>
<slot /> <slot />
</div> </div>
</div> </div>

View File

@ -34,7 +34,8 @@
style="position: relative;" style="position: relative;"
role="dialog" role="dialog"
tabindex="-1" tabindex="-1"
aria-modal="true"> aria-modal="true"
>
<div class="spectrum-Dialog-grid"> <div class="spectrum-Dialog-grid">
<h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader"> <h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader">
{title} {title}
@ -47,7 +48,8 @@
</section> </section>
{#if showCancelButton || showConfirmButton} {#if showCancelButton || showConfirmButton}
<div <div
class="spectrum-ButtonGroup spectrum-Dialog-buttonGroup spectrum-Dialog-buttonGroup--noFooter"> class="spectrum-ButtonGroup spectrum-Dialog-buttonGroup spectrum-Dialog-buttonGroup--noFooter"
>
<slot name="footer" /> <slot name="footer" />
{#if showCancelButton} {#if showCancelButton}
<Button group secondary on:click={hide}>{cancelText}</Button> <Button group secondary on:click={hide}>{cancelText}</Button>
@ -58,7 +60,8 @@
cta cta
{...$$restProps} {...$$restProps}
disabled={confirmDisabled} disabled={confirmDisabled}
on:click={confirm}> on:click={confirm}
>
{confirmText} {confirmText}
</Button> </Button>
{/if} {/if}
@ -73,6 +76,9 @@
</div> </div>
<style> <style>
.spectrum-Dialog--XL {
width: 1200px;
}
.content-grid { .content-grid {
display: grid; display: grid;
position: relative; position: relative;

View File

@ -31,7 +31,8 @@
bind:this={modal} bind:this={modal}
confirmText="Submit" confirmText="Submit"
onConfirm={answerQuiz} onConfirm={answerQuiz}
on:show={resetState}> on:show={resetState}
>
{#if error} {#if error}
<p class="error">Wrong answer! Try again.</p> <p class="error">Wrong answer! Try again.</p>
{/if} {/if}

View File

@ -1,17 +1,25 @@
<script> <script>
import "@spectrum-css/toast/dist/index-vars.css" import "@spectrum-css/toast/dist/index-vars.css"
import Portal from "svelte-portal" import Portal from "svelte-portal"
import { flip } from "svelte/animate" import { flip } from "svelte/animate"
import { fly } from "svelte/transition" import { fly } from "svelte/transition"
import { notifications } from '../Stores/notifications' import { notifications } from "../Stores/notifications"
</script> </script>
<Portal target=".modal-container"> <Portal target=".modal-container">
<div class="notifications"> <div class="notifications">
{#each $notifications as {type, icon, message, id} (id)} {#each $notifications as { type, icon, message, id } (id)}
<div animate:flip transition:fly={{ y: -30 }} class="spectrum-Toast spectrum-Toast--{type} notification-offset"> <div
animate:flip
transition:fly={{ y: -30 }}
class="spectrum-Toast spectrum-Toast--{type} notification-offset"
>
{#if icon} {#if icon}
<svg class="spectrum-Icon spectrum-Icon--sizeM spectrum-Toast-typeIcon" focusable="false" aria-hidden="true"> <svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Toast-typeIcon"
focusable="false"
aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-{icon}" /> <use xlink:href="#spectrum-icon-18-{icon}" />
</svg> </svg>
{/if} {/if}
@ -21,24 +29,24 @@
</div> </div>
{/each} {/each}
</div> </div>
</Portal> </Portal>
<style>
.notifications {
position: fixed;
top: 10px;
left: 0;
right: 0;
margin: 0 auto;
padding: 0;
z-index: 9999;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
pointer-events: none;
}
.notification-offset {
margin-bottom: 10px;
}
</style>
<style>
.notifications {
position: fixed;
top: 10px;
left: 0;
right: 0;
margin: 0 auto;
padding: 0;
z-index: 9999;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
pointer-events: none;
}
.notification-offset {
margin-bottom: 10px;
}
</style>

View File

@ -37,7 +37,8 @@
use:clickOutside={hide} use:clickOutside={hide}
on:keydown={handleEscape} on:keydown={handleEscape}
class="spectrum-Popover is-open" class="spectrum-Popover is-open"
role="presentation"> role="presentation"
>
<slot /> <slot />
</div> </div>
</Portal> </Portal>

View File

@ -1,29 +1,33 @@
<script> <script>
// WIP! Does not yet work. // WIP! Does not yet work.
import "@spectrum-css/progresscircle/dist/index-vars.css" import "@spectrum-css/progresscircle/dist/index-vars.css"
import { tweened } from 'svelte/motion'; import { tweened } from "svelte/motion"
import { cubicOut } from 'svelte/easing'; import { cubicOut } from "svelte/easing"
export let value = false export let value = false
export let small; export let small
export let large; export let large
export let overBackground; export let overBackground
</script> </script>
<div class:spectrum-ProgressBar--indeterminate={!value} class:spectrum-ProgressCircle--small={small} class:spectrum-ProgressCircle--large={large} class="spectrum-ProgressCircle"> <div
<div class="spectrum-ProgressCircle-track"></div> class:spectrum-ProgressBar--indeterminate={!value}
<div class="spectrum-ProgressCircle-fills"> class:spectrum-ProgressCircle--small={small}
<div class="spectrum-ProgressCircle-fillMask1"> class:spectrum-ProgressCircle--large={large}
<div class="spectrum-ProgressCircle-fillSubMask1"> class="spectrum-ProgressCircle"
<div class="spectrum-ProgressCircle-fill"></div> >
</div> <div class="spectrum-ProgressCircle-track" />
<div class="spectrum-ProgressCircle-fills">
<div class="spectrum-ProgressCircle-fillMask1">
<div class="spectrum-ProgressCircle-fillSubMask1">
<div class="spectrum-ProgressCircle-fill" />
</div> </div>
<div class="spectrum-ProgressCircle-fillMask2"> </div>
<div class="spectrum-ProgressCircle-fillSubMask2"> <div class="spectrum-ProgressCircle-fillMask2">
<div class="spectrum-ProgressCircle-fill"></div> <div class="spectrum-ProgressCircle-fillSubMask2">
</div> <div class="spectrum-ProgressCircle-fill" />
</div> </div>
</div> </div>
</div> </div>
</div>

View File

@ -1,30 +1,44 @@
<script> <script>
import { getContext } from 'svelte' import { getContext } from "svelte"
const multilevel = getContext('sidenav-type'); const multilevel = getContext("sidenav-type")
export let href = ""; export let href = ""
export let external = false; export let external = false
export let heading = "" export let heading = ""
export let icon = ""; export let icon = ""
export let selected = false; export let selected = false
export let disabled = false; export let disabled = false
</script> </script>
<li class="spectrum-SideNav-item" class:is-selected={selected} class:is-disabled={disabled}> <li
{#if heading} class="spectrum-SideNav-item"
<h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">{heading}</h2> class:is-selected={selected}
{/if} class:is-disabled={disabled}
<a target={external ? '_blank' : '_self'} {href} class="spectrum-SideNav-itemLink" aria-current="page"> >
{#if icon} {#if heading}
<svg class="spectrum-Icon spectrum-Icon--sizeM spectrum-SideNav-itemIcon" focusable="false" aria-hidden="true"> <h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">
<use xlink:href="#spectrum-icon-18-{icon}" /> {heading}
</svg> </h2>
{/if} {/if}
<slot /> <a
</a> target={external ? "_blank" : "_self"}
{#if multilevel && $$slots.subnav} {href}
<ul class="spectrum-SideNav"> class="spectrum-SideNav-itemLink"
<slot name="subnav" /> aria-current="page"
</ul> >
{#if icon}
<svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-SideNav-itemIcon"
focusable="false"
aria-hidden="true"
>
<use xlink:href="#spectrum-icon-18-{icon}" />
</svg>
{/if} {/if}
<slot />
</a>
{#if multilevel && $$slots.subnav}
<ul class="spectrum-SideNav">
<slot name="subnav" />
</ul>
{/if}
</li> </li>

View File

@ -1,8 +1,8 @@
<script> <script>
import { setContext } from 'svelte' import { setContext } from "svelte"
import "@spectrum-css/sidenav/dist/index-vars.css" import "@spectrum-css/sidenav/dist/index-vars.css"
export let multilevel = false; export let multilevel = false
setContext('sidenav-type', multilevel) setContext("sidenav-type", multilevel)
</script> </script>
<nav> <nav>

View File

@ -6,7 +6,7 @@
$: leftover = (value?.length ?? 0) - attachments.length $: leftover = (value?.length ?? 0) - attachments.length
const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"] const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
const isImage = extension => { const isImage = (extension) => {
return imageExtensions.includes(extension?.toLowerCase()) return imageExtensions.includes(extension?.toLowerCase())
} }
</script> </script>

View File

@ -5,24 +5,28 @@
</script> </script>
<label <label
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"> class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"
>
<input <input
type="checkbox" type="checkbox"
class="spectrum-Checkbox-input" class="spectrum-Checkbox-input"
id="checkbox-1" id="checkbox-1"
disabled disabled
checked={!!value} /> checked={!!value}
/>
<span class="spectrum-Checkbox-box"> <span class="spectrum-Checkbox-box">
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark" class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Checkmark100" /> <use xlink:href="#spectrum-css-icon-Checkmark100" />
</svg> </svg>
<svg <svg
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark" class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Dash100" /> <use xlink:href="#spectrum-css-icon-Dash100" />
</svg> </svg>
</span> </span>

View File

@ -22,11 +22,11 @@
longform: StringRenderer, longform: StringRenderer,
} }
$: type = schema?.type ?? "string" $: type = schema?.type ?? "string"
$: customRenderer = customRenderers?.find(x => x.column === schema?.name) $: customRenderer = customRenderers?.find((x) => x.column === schema?.name)
$: renderer = customRenderer?.component ?? typeMap[type] $: renderer = customRenderer?.component ?? typeMap[type]
</script> </script>
{#if renderer && (customRenderer || (value != null && value !== ''))} {#if renderer && (customRenderer || (value != null && value !== ""))}
<svelte:component this={renderer} {row} {schema} {value} on:clickrelationship> <svelte:component this={renderer} {row} {schema} {value} on:clickrelationship>
<slot /> <slot />
</svelte:component> </svelte:component>

View File

@ -4,7 +4,7 @@
export let value export let value
</script> </script>
<div>{dayjs(value).format('MMMM D YYYY, HH:mm')}</div> <div>{dayjs(value).format("MMMM D YYYY, HH:mm")}</div>
<style> <style>
div { div {

View File

@ -12,7 +12,7 @@
$: relationships = value?.slice(0, displayLimit) ?? [] $: relationships = value?.slice(0, displayLimit) ?? []
$: leftover = (value?.length ?? 0) - relationships.length $: leftover = (value?.length ?? 0) - relationships.length
const onClick = e => { const onClick = (e) => {
e.stopPropagation() e.stopPropagation()
dispatch("clickrelationship", { dispatch("clickrelationship", {
tableId: row.tableId, tableId: row.tableId,

View File

@ -31,6 +31,7 @@
// Table state // Table state
let height = 0 let height = 0
let loaded = false let loaded = false
$: schema = fixSchema(schema)
$: if (!loading) loaded = true $: if (!loading) loaded = true
$: rows = data ?? [] $: rows = data ?? []
$: visibleRowCount = getVisibleRowCount(loaded, height, rows.length, rowCount) $: visibleRowCount = getVisibleRowCount(loaded, height, rows.length, rowCount)
@ -50,7 +51,7 @@
rows.length rows.length
) )
// Reset state when data chanegs // Reset state when data changes
$: data.length, reset() $: data.length, reset()
const reset = () => { const reset = () => {
nextScrollTop = 0 nextScrollTop = 0
@ -59,6 +60,24 @@
timeout = null timeout = null
} }
const fixSchema = (schema) => {
let fixedSchema = {}
Object.entries(schema || {}).forEach(([fieldName, fieldSchema]) => {
if (typeof fieldSchema === "string") {
fixedSchema[fieldName] = {
type: fieldSchema,
name: fieldName,
}
} else {
fixedSchema[fieldName] = {
...fieldSchema,
name: fieldName,
}
}
})
return fixedSchema
}
const getVisibleRowCount = (loaded, height, allRows, rowCount) => { const getVisibleRowCount = (loaded, height, allRows, rowCount) => {
if (!loaded) { if (!loaded) {
return rowCount || 0 return rowCount || 0
@ -91,7 +110,7 @@
}) })
} }
const sortBy = fieldSchema => { const sortBy = (fieldSchema) => {
if (fieldSchema.sortable === false) { if (fieldSchema.sortable === false) {
return return
} }
@ -103,7 +122,7 @@
} }
} }
const getDisplayName = schema => { const getDisplayName = (schema) => {
let name = schema?.displayName let name = schema?.displayName
if (schema && name === undefined) { if (schema && name === undefined) {
name = schema.name name = schema.name
@ -118,7 +137,6 @@
if (!field || !fieldSchema) { if (!field || !fieldSchema) {
return return
} }
schema[field].name = field
if (!fieldSchema?.autocolumn) { if (!fieldSchema?.autocolumn) {
columns.push(fieldSchema) columns.push(fieldSchema)
} else if (showAutoColumns) { } else if (showAutoColumns) {
@ -137,10 +155,10 @@
return nameA < nameB ? a : b return nameA < nameB ? a : b
}) })
.concat(autoColumns) .concat(autoColumns)
.map(column => column.name) .map((column) => column.name)
} }
const onScroll = event => { const onScroll = (event) => {
nextScrollTop = event.target.scrollTop nextScrollTop = event.target.scrollTop
if (timeout) { if (timeout) {
return return
@ -151,7 +169,7 @@
}, 50) }, 50)
} }
const calculateFirstVisibleRow = scrollTop => { const calculateFirstVisibleRow = (scrollTop) => {
return Math.max(Math.floor(scrollTop / (rowHeight + 1)) - rowPreload, 0) return Math.max(Math.floor(scrollTop / (rowHeight + 1)) - rowPreload, 0)
} }
@ -172,12 +190,12 @@
dispatch("editrow", row) dispatch("editrow", row)
} }
const toggleSelectRow = row => { const toggleSelectRow = (row) => {
if (!allowSelectRows) { if (!allowSelectRows) {
return return
} }
if (selectedRows.includes(row)) { if (selectedRows.includes(row)) {
selectedRows = selectedRows.filter(selectedRow => selectedRow !== row) selectedRows = selectedRows.filter((selectedRow) => selectedRow !== row)
} else { } else {
selectedRows = [...selectedRows, row] selectedRows = [...selectedRows, row]
} }
@ -192,7 +210,8 @@
on:scroll={onScroll} on:scroll={onScroll}
class:quiet class:quiet
style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`} style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`}
class="container"> class="container"
>
<div style={contentStyle}> <div style={contentStyle}>
<table class="spectrum-Table" class:spectrum-Table--quiet={quiet}> <table class="spectrum-Table" class:spectrum-Table--quiet={quiet}>
{#if sortedRows?.length} {#if sortedRows?.length}
@ -201,7 +220,7 @@
{#if showEditColumn} {#if showEditColumn}
<th class="spectrum-Table-headCell"> <th class="spectrum-Table-headCell">
<div class="spectrum-Table-headCell-content"> <div class="spectrum-Table-headCell-content">
{editColumnTitle || ''} {editColumnTitle || ""}
</div> </div>
</th> </th>
{/if} {/if}
@ -209,15 +228,19 @@
<th <th
class="spectrum-Table-headCell" class="spectrum-Table-headCell"
class:is-sortable={schema[field].sortable !== false} class:is-sortable={schema[field].sortable !== false}
class:is-sorted-desc={sortColumn === field && sortOrder === 'Descending'} class:is-sorted-desc={sortColumn === field &&
class:is-sorted-asc={sortColumn === field && sortOrder === 'Ascending'} sortOrder === "Descending"}
on:click={() => sortBy(schema[field])}> class:is-sorted-asc={sortColumn === field &&
sortOrder === "Ascending"}
on:click={() => sortBy(schema[field])}
>
<div class="spectrum-Table-headCell-content"> <div class="spectrum-Table-headCell-content">
<div class="title">{getDisplayName(schema[field])}</div> <div class="title">{getDisplayName(schema[field])}</div>
{#if schema[field]?.autocolumn} {#if schema[field]?.autocolumn}
<svg <svg
class="spectrum-Icon spectrum-Table-autoIcon" class="spectrum-Icon spectrum-Table-autoIcon"
focusable="false"> focusable="false"
>
<use xlink:href="#spectrum-icon-18-MagicWand" /> <use xlink:href="#spectrum-icon-18-MagicWand" />
</svg> </svg>
{/if} {/if}
@ -225,7 +248,8 @@
<svg <svg
class="spectrum-Icon spectrum-UIIcon-ArrowDown100 spectrum-Table-sortedIcon" class="spectrum-Icon spectrum-UIIcon-ArrowDown100 spectrum-Table-sortedIcon"
focusable="false" focusable="false"
aria-hidden="true"> aria-hidden="true"
>
<use xlink:href="#spectrum-css-icon-Arrow100" /> <use xlink:href="#spectrum-css-icon-Arrow100" />
</svg> </svg>
{/if} {/if}
@ -233,7 +257,8 @@
<svg <svg
class="spectrum-Icon spectrum-Table-editIcon" class="spectrum-Icon spectrum-Table-editIcon"
focusable="false" focusable="false"
on:click={e => editColumn(e, field)}> on:click={(e) => editColumn(e, field)}
>
<use xlink:href="#spectrum-icon-18-Edit" /> <use xlink:href="#spectrum-icon-18-Edit" />
</svg> </svg>
{/if} {/if}
@ -249,33 +274,39 @@
<tr <tr
on:click={() => toggleSelectRow(row)} on:click={() => toggleSelectRow(row)}
class="spectrum-Table-row" class="spectrum-Table-row"
class:hidden={idx < firstVisibleRow || idx > lastVisibleRow}> class:hidden={idx < firstVisibleRow || idx > lastVisibleRow}
>
{#if idx >= firstVisibleRow && idx <= lastVisibleRow} {#if idx >= firstVisibleRow && idx <= lastVisibleRow}
{#if showEditColumn} {#if showEditColumn}
<td <td
class="spectrum-Table-cell spectrum-Table-cell--divider"> class="spectrum-Table-cell spectrum-Table-cell--divider"
>
<div class="spectrum-Table-cell-content"> <div class="spectrum-Table-cell-content">
<SelectEditRenderer <SelectEditRenderer
data={row} data={row}
selected={selectedRows.includes(row)} selected={selectedRows.includes(row)}
onToggleSelection={() => toggleSelectRow(row)} onToggleSelection={() => toggleSelectRow(row)}
onEdit={e => editRow(e, row)} onEdit={(e) => editRow(e, row)}
{allowSelectRows} {allowSelectRows}
{allowEditRows} /> {allowEditRows}
/>
</div> </div>
</td> </td>
{/if} {/if}
{#each fields as field} {#each fields as field}
<td <td
class="spectrum-Table-cell" class="spectrum-Table-cell"
class:spectrum-Table-cell--divider={!!schema[field].divider}> class:spectrum-Table-cell--divider={!!schema[field]
.divider}
>
<div class="spectrum-Table-cell-content"> <div class="spectrum-Table-cell-content">
<CellRenderer <CellRenderer
{customRenderers} {customRenderers}
{row} {row}
schema={schema[field]} schema={schema[field]}
value={row[field]} value={row[field]}
on:clickrelationship> on:clickrelationship
>
<slot /> <slot />
</CellRenderer> </CellRenderer>
</div> </div>
@ -288,7 +319,8 @@
<div class="placeholder"> <div class="placeholder">
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeXXL" class="spectrum-Icon spectrum-Icon--sizeXXL"
focusable="false"> focusable="false"
>
<use xlink:href="#spectrum-icon-18-Table" /> <use xlink:href="#spectrum-icon-18-Table" />
</svg> </svg>
<div>No rows found</div> <div>No rows found</div>

View File

@ -30,13 +30,15 @@
on:click={onClick} on:click={onClick}
class:is-selected={$selected.title === title} class:is-selected={$selected.title === title}
class="spectrum-Tabs-item" class="spectrum-Tabs-item"
tabindex="0"> tabindex="0"
>
{#if icon} {#if icon}
<svg <svg
class="spectrum-Icon spectrum-Icon--sizeM" class="spectrum-Icon spectrum-Icon--sizeM"
focusable="false" focusable="false"
aria-hidden="true" aria-hidden="true"
aria-label="Folder"> aria-label="Folder"
>
<use xlink:href="#spectrum-icon-18-{icon}" /> <use xlink:href="#spectrum-icon-18-{icon}" />
</svg> </svg>
{/if} {/if}

View File

@ -44,23 +44,22 @@
}) })
function id() { function id() {
return ( return "_" + Math.random().toString(36).substr(2, 9)
"_" +
Math.random()
.toString(36)
.substr(2, 9)
)
} }
</script> </script>
<div <div
bind:this={container} bind:this={container}
class="selected-border spectrum-Tabs spectrum-Tabs--{vertical ? 'vertical' : 'horizontal'}"> class="selected-border spectrum-Tabs spectrum-Tabs--{vertical
? 'vertical'
: 'horizontal'}"
>
<slot /> <slot />
{#if $tab.info} {#if $tab.info}
<div <div
class="spectrum-Tabs-selectionIndicator indicator-transition" class="spectrum-Tabs-selectionIndicator indicator-transition"
style="width: {width}; height: {height}; left: {left}; top: {top};" /> style="width: {width}; height: {height}; left: {left}; top: {top};"
/>
{/if} {/if}
</div> </div>

View File

@ -1,24 +1,34 @@
<script> <script>
import Avatar from '../Avatar/Avatar.svelte' import Avatar from "../Avatar/Avatar.svelte"
import ClearButton from '../ClearButton/ClearButton.svelte' import ClearButton from "../ClearButton/ClearButton.svelte"
export let icon = ""; export let icon = ""
export let avatar = ""; export let avatar = ""
export let invalid = false; export let invalid = false
export let disabled = false; export let disabled = false
export let closable = false; export let closable = false
</script> </script>
<div class:is-invalid={invalid} class:is-disabled={disabled} class="spectrum-Tags-item" role="listitem"> <div
class:is-invalid={invalid}
class:is-disabled={disabled}
class="spectrum-Tags-item"
role="listitem"
>
{#if avatar} {#if avatar}
<Avatar url={avatar} /> <Avatar url={avatar} />
{/if} {/if}
{#if icon} {#if icon}
<svg class="spectrum-Icon spectrum-Icon--sizeS" focusable="false" aria-hidden="true" aria-label="Tag"> <svg
class="spectrum-Icon spectrum-Icon--sizeS"
focusable="false"
aria-hidden="true"
aria-label="Tag"
>
<use xlink:href="#spectrum-icon-24-{icon}" /> <use xlink:href="#spectrum-icon-24-{icon}" />
</svg> </svg>
{/if} {/if}
<span class="spectrum-Tags-itemLabel"><slot /></span> <span class="spectrum-Tags-itemLabel"><slot /></span>
{#if closable} {#if closable}
<ClearButton on:click /> <ClearButton on:click />
{/if} {/if}
</div> </div>

View File

@ -1,7 +1,7 @@
<script> <script>
import "@spectrum-css/tags/dist/index-vars.css" import "@spectrum-css/tags/dist/index-vars.css"
</script> </script>
<div class="spectrum-Tags" role="list" aria-label="list"> <div class="spectrum-Tags" role="list" aria-label="list">
<slot /> <slot />
</div> </div>

View File

@ -1,28 +1,40 @@
<script> <script>
export let selected = false; export let selected = false
export let open = false; export let open = false
export let title; export let title
export let icon; export let icon
</script> </script>
<li <li
class:is-selected={selected} class:is-open={open} class="spectrum-TreeView-item"> class:is-selected={selected}
<a on:click class="spectrum-TreeView-itemLink" href="#"> class:is-open={open}
{#if $$slots.default} class="spectrum-TreeView-item"
<svg class="spectrum-Icon spectrum-UIIcon-ChevronRight100 spectrum-TreeView-itemIndicator" focusable="false" aria-hidden="true"> >
<use xlink:href="#spectrum-css-icon-Chevron100" /> <a on:click class="spectrum-TreeView-itemLink" href="#">
</svg> {#if $$slots.default}
{/if} <svg
{#if icon} class="spectrum-Icon spectrum-UIIcon-ChevronRight100 spectrum-TreeView-itemIndicator"
<svg class="spectrum-TreeView-itemIcon spectrum-Icon spectrum-Icon--sizeM" focusable="false" aria-hidden="true" aria-label="Layers"> focusable="false"
<use xlink:href="#spectrum-icon-18-{icon}" /> aria-hidden="true"
</svg> >
{/if} <use xlink:href="#spectrum-css-icon-Chevron100" />
<span class="spectrum-TreeView-itemLabel">{title}</span> </svg>
</a> {/if}
{#if $$slots.default} {#if icon}
<ul class="spectrum-TreeView"> <svg
<slot /> class="spectrum-TreeView-itemIcon spectrum-Icon spectrum-Icon--sizeM"
</ul> focusable="false"
{/if} aria-hidden="true"
aria-label="Layers"
>
<use xlink:href="#spectrum-icon-18-{icon}" />
</svg>
{/if}
<span class="spectrum-TreeView-itemLabel">{title}</span>
</a>
{#if $$slots.default}
<ul class="spectrum-TreeView">
<slot />
</ul>
{/if}
</li> </li>

View File

@ -1,11 +1,16 @@
<script> <script>
import "@spectrum-css/treeview/dist/index-vars.css" import "@spectrum-css/treeview/dist/index-vars.css"
export let quiet = false export let quiet = false
export let standalone = true export let standalone = true
export let width = '250px'; export let width = "250px"
</script> </script>
<ul class:spectrum-TreeView--standalone={standalone} class:spectrum-TreeView--quiet={quiet} class="spectrum-TreeView" style="width: {width}"> <ul
<slot /> class:spectrum-TreeView--standalone={standalone}
class:spectrum-TreeView--quiet={quiet}
class="spectrum-TreeView"
style="width: {width}"
>
<slot />
</ul> </ul>

View File

@ -106,7 +106,7 @@
"rollup": "^2.44.0", "rollup": "^2.44.0",
"rollup-plugin-copy": "^3.4.0", "rollup-plugin-copy": "^3.4.0",
"start-server-and-test": "^1.12.1", "start-server-and-test": "^1.12.1",
"svelte": "^3.36.0", "svelte": "^3.37.0",
"svelte-jester": "^1.3.2", "svelte-jester": "^1.3.2",
"vite": "^2.1.5" "vite": "^2.1.5"
}, },

View File

@ -277,14 +277,23 @@ export const getSchemaForDatasource = (datasource, isForm = false) => {
schema["_rev"] = { type: "string" } schema["_rev"] = { type: "string" }
} }
// Ensure there are "name" properties for all fields // Ensure there are "name" properties for all fields and that field schema
if (schema) { // are objects
Object.keys(schema).forEach((field) => { let fixedSchema = {}
if (!schema[field].name) { Object.entries(schema || {}).forEach(([fieldName, fieldSchema]) => {
schema[field].name = field if (typeof fieldSchema === "string") {
fixedSchema[fieldName] = {
type: fieldSchema,
name: fieldName,
} }
}) } else {
} fixedSchema[fieldName] = {
...fieldSchema,
name: fieldName,
}
}
})
schema = fixedSchema
} }
return { schema, table } return { schema, table }
} }

View File

@ -6,7 +6,7 @@
$: automation = $automationStore.selectedAutomation?.automation $: automation = $automationStore.selectedAutomation?.automation
function onSelect(block) { function onSelect(block) {
automationStore.update(state => { automationStore.update((state) => {
state.selectedBlock = block state.selectedBlock = block
return state return state
}) })

View File

@ -33,7 +33,7 @@
let webhookModal let webhookModal
$: selectedTab = selectedIndex == null ? null : tabs[selectedIndex].value $: selectedTab = selectedIndex == null ? null : tabs[selectedIndex].value
$: anchor = selectedIndex === -1 ? null : anchors[selectedIndex] $: anchor = selectedIndex === -1 ? null : anchors[selectedIndex]
$: blocks = sortBy(entry => entry[1].name)( $: blocks = sortBy((entry) => entry[1].name)(
Object.entries($automationStore.blockDefinitions[selectedTab] ?? {}) Object.entries($automationStore.blockDefinitions[selectedTab] ?? {})
) )
@ -63,13 +63,14 @@
<div class="tab-container"> <div class="tab-container">
{#each tabs as tab, idx} {#each tabs as tab, idx}
<div bind:this={anchors[idx]}> <div bind:this={anchors[idx]}>
<ActionButton <ActionButton
quiet quiet
size="S" size="S"
icon={tab.icon} icon={tab.icon}
disabled={tab.disabled} disabled={tab.disabled}
on:click={tab.disabled ? null : () => onChangeTab(idx)}> on:click={tab.disabled ? null : () => onChangeTab(idx)}
>
{tab.label} {tab.label}
</ActionButton> </ActionButton>
</div> </div>
@ -79,14 +80,16 @@
on:close={() => (selectedIndex = null)} on:close={() => (selectedIndex = null)}
bind:this={popover} bind:this={popover}
{anchor} {anchor}
align="left"> align="left"
>
<DropdownContainer> <DropdownContainer>
{#each blocks as [stepId, blockDefinition]} {#each blocks as [stepId, blockDefinition]}
<DropdownItem <DropdownItem
icon={blockDefinition.icon} icon={blockDefinition.icon}
title={blockDefinition.name} title={blockDefinition.name}
subtitle={blockDefinition.description} subtitle={blockDefinition.description}
on:click={() => addBlockToAutomation(stepId, blockDefinition)} /> on:click={() => addBlockToAutomation(stepId, blockDefinition)}
/>
{/each} {/each}
</DropdownContainer> </DropdownContainer>
</Popover> </Popover>

View File

@ -3,10 +3,12 @@
height="75" height="75"
viewBox="0 0 9 75" viewBox="0 0 9 75"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M5.0625 70H9L4.5 75L0 70H3.9375V65H5.0625V70Z" d="M5.0625 70H9L4.5 75L0 70H3.9375V65H5.0625V70Z"
fill="var(--grey-5)" /> fill="var(--grey-5)"
/>
<rect x="4" width="1" height="65" fill="var(--grey-5)" /> <rect x="4" width="1" height="65" fill="var(--grey-5)" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 326 B

View File

@ -16,7 +16,7 @@
const tableId = inputs.tableId || inputs.row?.tableId const tableId = inputs.tableId || inputs.row?.tableId
if (tableId) { if (tableId) {
enrichedInputs.enriched.table = $tables.list.find( enrichedInputs.enriched.table = $tables.list.find(
table => table._id === tableId (table) => table._id === tableId
) )
} }
return enrichedInputs return enrichedInputs
@ -30,8 +30,8 @@
// Extract schema paths for any input bindings // Extract schema paths for any input bindings
let inputPaths = formattedTagline.match(/{{\s*\S+\s*}}/g) || [] let inputPaths = formattedTagline.match(/{{\s*\S+\s*}}/g) || []
inputPaths = inputPaths.map(path => path.replace(/[{}]/g, "").trim()) inputPaths = inputPaths.map((path) => path.replace(/[{}]/g, "").trim())
const schemaPaths = inputPaths.map(path => const schemaPaths = inputPaths.map((path) =>
path.replace(/\./g, ".properties.") path.replace(/\./g, ".properties.")
) )

View File

@ -26,7 +26,8 @@
class="block" class="block"
animate:flip={{ duration: 600 }} animate:flip={{ duration: 600 }}
in:fade|local in:fade|local
out:fly|local={{ x: 100 }}> out:fly|local={{ x: 100 }}
>
<FlowItem {onSelect} {block} /> <FlowItem {onSelect} {block} />
{#if idx !== blocks.length - 1} {#if idx !== blocks.length - 1}
<Arrow /> <Arrow />

View File

@ -10,11 +10,11 @@
$: selected = $automationStore.selectedBlock?.id === block.id $: selected = $automationStore.selectedBlock?.id === block.id
$: steps = $: steps =
$automationStore.selectedAutomation?.automation?.definition?.steps ?? [] $automationStore.selectedAutomation?.automation?.definition?.steps ?? []
$: blockIdx = steps.findIndex(step => step.id === block.id) $: blockIdx = steps.findIndex((step) => step.id === block.id)
$: allowDeleteTrigger = !steps.length $: allowDeleteTrigger = !steps.length
function deleteStep() { function deleteStep() {
console.log('Running') console.log("Running")
automationStore.actions.deleteAutomationBlock(block) automationStore.actions.deleteAutomationBlock(block)
} }
</script> </script>
@ -22,23 +22,24 @@
<div <div
class={`block ${block.type} hoverable`} class={`block ${block.type} hoverable`}
class:selected class:selected
on:click={() => onSelect(block)}> on:click={() => onSelect(block)}
>
<header> <header>
{#if block.type === 'TRIGGER'} {#if block.type === "TRIGGER"}
<Icon name="Light" /> <Icon name="Light" />
<span>When this happens...</span> <span>When this happens...</span>
{:else if block.type === 'ACTION'} {:else if block.type === "ACTION"}
<Icon name="FlashOn" /> <Icon name="FlashOn" />
<span>Do this...</span> <span>Do this...</span>
{:else if block.type === 'LOGIC'} {:else if block.type === "LOGIC"}
<Icon name="Branch2" /> <Icon name="Branch2" />
<span>Only continue if...</span> <span>Only continue if...</span>
{/if} {/if}
<div class="label"> <div class="label">
{#if block.type === 'TRIGGER'}Trigger{:else}Step {blockIdx + 1}{/if} {#if block.type === "TRIGGER"}Trigger{:else}Step {blockIdx + 1}{/if}
</div> </div>
{#if block.type !== 'TRIGGER' || allowDeleteTrigger} {#if block.type !== "TRIGGER" || allowDeleteTrigger}
<div on:click|stopPropagation={deleteStep}><Icon name="Close"/></div> <div on:click|stopPropagation={deleteStep}><Icon name="Close" /></div>
{/if} {/if}
</header> </header>
<hr /> <hr />

View File

@ -27,12 +27,14 @@
confirmText="Create" confirmText="Create"
size="L" size="L"
onConfirm={createAutomation} onConfirm={createAutomation}
disabled={!valid}> disabled={!valid}
>
<Input bind:value={name} label="Name" /> <Input bind:value={name} label="Name" />
<a <a
slot="footer" slot="footer"
target="_blank" target="_blank"
href="https://docs.budibase.com/automate/introduction-to-automate"> href="https://docs.budibase.com/automate/introduction-to-automate"
>
<Icon name="InfoOutline" /> <Icon name="InfoOutline" />
<span>Learn about automations</span> <span>Learn about automations</span>
</a> </a>

View File

@ -27,7 +27,7 @@
if (automation.trigger) { if (automation.trigger) {
allSteps = [automation.trigger, ...allSteps] allSteps = [automation.trigger, ...allSteps]
} }
const blockIdx = allSteps.findIndex(step => step.id === block.id) const blockIdx = allSteps.findIndex((step) => step.id === block.id)
// Extract all outputs from all previous steps as available bindings // Extract all outputs from all previous steps as available bindings
let bindings = [] let bindings = []
@ -54,40 +54,43 @@
{#each inputs as [key, value]} {#each inputs as [key, value]}
<div class="block-field"> <div class="block-field">
<Label>{value.title}</Label> <Label>{value.title}</Label>
{#if value.type === 'string' && value.enum} {#if value.type === "string" && value.enum}
<Select <Select
bind:value={block.inputs[key]} bind:value={block.inputs[key]}
options={value.enum} options={value.enum}
getOptionLabel={(x, idx) => (value.pretty ? value.pretty[idx] : x)} /> getOptionLabel={(x, idx) => (value.pretty ? value.pretty[idx] : x)}
{:else if value.customType === 'password'} />
{:else if value.customType === "password"}
<Input type="password" bind:value={block.inputs[key]} /> <Input type="password" bind:value={block.inputs[key]} />
{:else if value.customType === 'email'} {:else if value.customType === "email"}
<DrawerBindableInput <DrawerBindableInput
panel={AutomationBindingPanel} panel={AutomationBindingPanel}
type={'email'} type={"email"}
value={block.inputs[key]} value={block.inputs[key]}
on:change={e => (block.inputs[key] = e.detail)} on:change={(e) => (block.inputs[key] = e.detail)}
{bindings} /> {bindings}
{:else if value.customType === 'table'} />
{:else if value.customType === "table"}
<TableSelector bind:value={block.inputs[key]} /> <TableSelector bind:value={block.inputs[key]} />
{:else if value.customType === 'row'} {:else if value.customType === "row"}
<RowSelector bind:value={block.inputs[key]} {bindings} /> <RowSelector bind:value={block.inputs[key]} {bindings} />
{:else if value.customType === 'webhookUrl'} {:else if value.customType === "webhookUrl"}
<WebhookDisplay value={block.inputs[key]} /> <WebhookDisplay value={block.inputs[key]} />
{:else if value.customType === 'triggerSchema'} {:else if value.customType === "triggerSchema"}
<SchemaSetup bind:value={block.inputs[key]} /> <SchemaSetup bind:value={block.inputs[key]} />
{:else if value.type === 'string' || value.type === 'number'} {:else if value.type === "string" || value.type === "number"}
<DrawerBindableInput <DrawerBindableInput
panel={AutomationBindingPanel} panel={AutomationBindingPanel}
type={value.customType} type={value.customType}
value={block.inputs[key]} value={block.inputs[key]}
on:change={e => (block.inputs[key] = e.detail)} on:change={(e) => (block.inputs[key] = e.detail)}
{bindings} /> {bindings}
/>
{/if} {/if}
</div> </div>
{/each} {/each}
</div> </div>
{#if stepId === 'WEBHOOK'} {#if stepId === "WEBHOOK"}
<Button secondary on:click={() => webhookModal.show()}>Set Up Webhook</Button> <Button secondary on:click={() => webhookModal.show()}>Set Up Webhook</Button>
{/if} {/if}

View File

@ -7,7 +7,7 @@
export let value export let value
export let bindings export let bindings
$: table = $tables.list.find(table => table._id === value?.tableId) $: table = $tables.list.find((table) => table._id === value?.tableId)
$: schemaFields = Object.entries(table?.schema ?? {}) $: schemaFields = Object.entries(table?.schema ?? {})
// Ensure any nullish tableId values get set to empty string so // Ensure any nullish tableId values get set to empty string so
@ -22,8 +22,9 @@
<Select <Select
bind:value={value.tableId} bind:value={value.tableId}
options={$tables.list} options={$tables.list}
getOptionLabel={table => table.name} getOptionLabel={(table) => table.name}
getOptionValue={table => table._id} /> getOptionValue={(table) => table._id}
/>
{#if schemaFields.length} {#if schemaFields.length}
<div class="schema-fields"> <div class="schema-fields">
@ -33,15 +34,17 @@
<Select <Select
label={field} label={field}
bind:value={value[field]} bind:value={value[field]}
options={schema.constraints.inclusion} /> options={schema.constraints.inclusion}
{:else if schema.type === 'string' || schema.type === 'number'} />
{:else if schema.type === "string" || schema.type === "number"}
<DrawerBindableInput <DrawerBindableInput
panel={AutomationBindingPanel} panel={AutomationBindingPanel}
value={value[field]} value={value[field]}
on:change={e => (value[field] = e.detail)} on:change={(e) => (value[field] = e.detail)}
label={field} label={field}
type="string" type="string"
{bindings} /> {bindings}
/>
{/if} {/if}
{/if} {/if}
{/each} {/each}

View File

@ -37,14 +37,14 @@
value = newValues value = newValues
} }
const fieldNameChanged = originalName => e => { const fieldNameChanged = (originalName) => (e) => {
// reconstruct using fieldsArray, so field order is preserved // reconstruct using fieldsArray, so field order is preserved
let entries = [...fieldsArray] let entries = [...fieldsArray]
const newName = e.detail const newName = e.detail
if (newName) { if (newName) {
entries.find(f => f.name === originalName).name = newName entries.find((f) => f.name === originalName).name = newName
} else { } else {
entries = entries.filter(f => f.name !== originalName) entries = entries.filter((f) => f.name !== originalName)
} }
value = entries.reduce((newVals, current) => { value = entries.reduce((newVals, current) => {
newVals[current.name] = current.type newVals[current.name] = current.type
@ -62,14 +62,17 @@
value={field.name} value={field.name}
secondary secondary
placeholder="Enter field name" placeholder="Enter field name"
on:change={fieldNameChanged(field.name)} /> on:change={fieldNameChanged(field.name)}
/>
<Select <Select
value={field.type} value={field.type}
on:change={e => (value[field.name] = e.target.value)} on:change={(e) => (value[field.name] = e.target.value)}
options={typeOptions} /> options={typeOptions}
/>
<i <i
class="remove-field ri-delete-bin-line" class="remove-field ri-delete-bin-line"
on:click={() => removeField(field.name)} /> on:click={() => removeField(field.name)}
/>
</div> </div>
{/each} {/each}
</div> </div>

View File

@ -8,5 +8,6 @@
<Select <Select
bind:value bind:value
options={$tables.list} options={$tables.list}
getOptionLabel={table => table.name} getOptionLabel={(table) => table.name}
getOptionValue={table => table._id} /> getOptionValue={(table) => table._id}
/>

View File

@ -30,7 +30,7 @@
if ($views.selected?.name?.startsWith("all_")) { if ($views.selected?.name?.startsWith("all_")) {
loading = true loading = true
const loadingTableId = $tables.selected?._id const loadingTableId = $tables.selected?._id
api.fetchDataForView($views.selected).then(rows => { api.fetchDataForView($views.selected).then((rows) => {
loading = false loading = false
// If we started a slow request then quickly change table, sometimes // If we started a slow request then quickly change table, sometimes
@ -53,12 +53,14 @@
{data} {data}
allowEditing={true} allowEditing={true}
bind:hideAutocolumns bind:hideAutocolumns
{loading}> {loading}
>
<CreateColumnButton /> <CreateColumnButton />
{#if schema && Object.keys(schema).length > 0} {#if schema && Object.keys(schema).length > 0}
<CreateRowButton <CreateRowButton
title={isUsersTable ? 'Create user' : 'Create row'} title={isUsersTable ? "Create user" : "Create row"}
modalContentComponent={isUsersTable ? CreateEditUser : CreateEditRow} /> modalContentComponent={isUsersTable ? CreateEditUser : CreateEditRow}
/>
<CreateViewButton /> <CreateViewButton />
<ManageAccessButton resourceId={$tables.selected?._id} /> <ManageAccessButton resourceId={$tables.selected?._id} />
{#if isUsersTable} {#if isUsersTable}

View File

@ -12,9 +12,9 @@
$: data = row?.[fieldName] ?? [] $: data = row?.[fieldName] ?? []
$: linkedTableId = data?.length ? data[0].tableId : null $: linkedTableId = data?.length ? data[0].tableId : null
$: linkedTable = $tables.list.find(table => table._id === linkedTableId) $: linkedTable = $tables.list.find((table) => table._id === linkedTableId)
$: schema = linkedTable?.schema $: schema = linkedTable?.schema
$: table = $tables.list.find(table => table._id === tableId) $: table = $tables.list.find((table) => table._id === tableId)
$: fetchData(tableId, rowId) $: fetchData(tableId, rowId)
$: { $: {
let rowLabel = row?.[table?.primaryDisplay] let rowLabel = row?.[table?.primaryDisplay]

View File

@ -13,21 +13,22 @@
$: label = capitalise(meta.name) $: label = capitalise(meta.name)
</script> </script>
{#if type === 'options'} {#if type === "options"}
<Select <Select
{label} {label}
data-cy="{meta.name}-select" data-cy="{meta.name}-select"
bind:value bind:value
options={meta.constraints.inclusion} /> options={meta.constraints.inclusion}
{:else if type === 'datetime'} />
{:else if type === "datetime"}
<DatePicker {label} bind:value /> <DatePicker {label} bind:value />
{:else if type === 'attachment'} {:else if type === "attachment"}
<Dropzone {label} bind:value /> <Dropzone {label} bind:value />
{:else if type === 'boolean'} {:else if type === "boolean"}
<Toggle text={label} bind:checked={value} data-cy="{meta.name}-input" /> <Toggle text={label} bind:checked={value} data-cy="{meta.name}-input" />
{:else if type === 'link'} {:else if type === "link"}
<LinkedRowSelector bind:linkedRows={value} schema={meta} /> <LinkedRowSelector bind:linkedRows={value} schema={meta} />
{:else if type === 'longform'} {:else if type === "longform"}
<TextArea {label} bind:value /> <TextArea {label} bind:value />
{:else} {:else}
<Input <Input
@ -35,5 +36,6 @@
data-cy="{meta.name}-input" data-cy="{meta.name}-input"
{type} {type}
bind:value bind:value
disabled={readonly} /> disabled={readonly}
/>
{/if} {/if}

View File

@ -28,9 +28,9 @@
async function fetchViewData(name, field, groupBy, calculation) { async function fetchViewData(name, field, groupBy, calculation) {
const _tables = $tables.list const _tables = $tables.list
const allTableViews = _tables.map(table => table.views) const allTableViews = _tables.map((table) => table.views)
const thisView = allTableViews.filter( const thisView = allTableViews.filter(
views => views != null && views[name] != null (views) => views != null && views[name] != null
)[0] )[0]
// don't fetch view data if the view no longer exists // don't fetch view data if the view no longer exists
if (!thisView) { if (!thisView) {
@ -58,7 +58,8 @@
{data} {data}
{loading} {loading}
allowEditing={!view?.calculation} allowEditing={!view?.calculation}
bind:hideAutocolumns> bind:hideAutocolumns
>
<FilterButton {view} /> <FilterButton {view} />
<CalculateButton {view} /> <CalculateButton {view} />
{#if view.calculation} {#if view.calculation}

View File

@ -12,7 +12,8 @@
size="S" size="S"
quiet quiet
on:click={modal.show} on:click={modal.show}
active={view.field && view.calculation}> active={view.field && view.calculation}
>
Calculate Calculate
</ActionButton> </ActionButton>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View File

@ -22,8 +22,9 @@
bind:this={modal} bind:this={modal}
okText="Delete" okText="Delete"
onOk={confirmDeletion} onOk={confirmDeletion}
title="Confirm Deletion"> title="Confirm Deletion"
>
Are you sure you want to delete Are you sure you want to delete
{selectedRows.length} {selectedRows.length}
row{selectedRows.length > 1 ? 's' : ''}? row{selectedRows.length > 1 ? "s" : ""}?
</ConfirmDialog> </ConfirmDialog>

View File

@ -12,7 +12,8 @@
size="S" size="S"
quiet quiet
on:click={modal.show} on:click={modal.show}
active={view.filters?.length}> active={view.filters?.length}
>
Filter Filter
</ActionButton> </ActionButton>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View File

@ -13,7 +13,8 @@
size="S" size="S"
quiet quiet
active={!!view.groupBy} active={!!view.groupBy}
on:click={modal.show}> on:click={modal.show}
>
Group By Group By
</Button> </Button>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View File

@ -21,5 +21,6 @@
<ManageAccessModal <ManageAccessModal
{resourceId} {resourceId}
levels={$permissions} levels={$permissions}
permissions={resourcePermissions} /> permissions={resourcePermissions}
/>
</Modal> </Modal>

View File

@ -3,7 +3,7 @@
export let value export let value
$: role = $roles.find(role => role._id === value) $: role = $roles.find((role) => role._id === value)
$: roleName = role?.name ?? "Unknown role" $: roleName = role?.name ?? "Unknown role"
</script> </script>

View File

@ -25,7 +25,7 @@
$: fields = $: fields =
viewTable && viewTable &&
Object.keys(viewTable.schema).filter( Object.keys(viewTable.schema).filter(
field => (field) =>
view.calculation === "count" || view.calculation === "count" ||
// don't want to perform calculations based on auto ID // don't want to perform calculations based on auto ID
(viewTable.schema[field].type === "number" && (viewTable.schema[field].type === "number" &&
@ -43,14 +43,16 @@
title="Calculate" title="Calculate"
confirmText="Save" confirmText="Save"
onConfirm={saveView} onConfirm={saveView}
disabled={!view.field}> disabled={!view.field}
>
<div class="input-group-row"> <div class="input-group-row">
<Label>The</Label> <Label>The</Label>
<Select <Select
bind:value={view.calculation} bind:value={view.calculation}
options={CALCULATIONS} options={CALCULATIONS}
getOptionLabel={x => x.name} getOptionLabel={(x) => x.name}
getOptionValue={x => x.key} /> getOptionValue={(x) => x.key}
/>
{#if view.calculation} {#if view.calculation}
<Label>Of</Label> <Label>Of</Label>
<Select bind:value={view.field} options={fields} /> <Select bind:value={view.field} options={fields} />

View File

@ -49,7 +49,7 @@
let deletion let deletion
$: tableOptions = $tables.list.filter( $: tableOptions = $tables.list.filter(
table => table._id !== $tables.draft._id (table) => table._id !== $tables.draft._id
) )
$: required = !!field?.constraints?.presence || primaryDisplay $: required = !!field?.constraints?.presence || primaryDisplay
$: uneditable = $: uneditable =
@ -60,7 +60,7 @@
!field.name || !field.name ||
(field.type === LINK_TYPE && !field.tableId) || (field.type === LINK_TYPE && !field.tableId) ||
Object.keys($tables.draft?.schema ?? {}).some( Object.keys($tables.draft?.schema ?? {}).some(
key => key !== originalName && key === field.name (key) => key !== originalName && key === field.name
) )
// used to select what different options can be displayed for column type // used to select what different options can be displayed for column type
@ -154,7 +154,7 @@
if (!field || !field.tableId) { if (!field || !field.tableId) {
return null return null
} }
const linkTable = tableOptions.find(table => table._id === field.tableId) const linkTable = tableOptions.find((table) => table._id === field.tableId)
if (!linkTable) { if (!linkTable) {
return null return null
} }
@ -181,10 +181,11 @@
</script> </script>
<ModalContent <ModalContent
title={originalName ? 'Edit Column' : 'Create Column'} title={originalName ? "Edit Column" : "Create Column"}
confirmText="Save Column" confirmText="Save Column"
onConfirm={saveColumn} onConfirm={saveColumn}
disabled={invalid}> disabled={invalid}
>
<Input label="Name" bind:value={field.name} disabled={uneditable} /> <Input label="Name" bind:value={field.name} disabled={uneditable} />
<Select <Select
@ -192,9 +193,13 @@
label="Type" label="Type"
bind:value={field.type} bind:value={field.type}
on:change={handleTypeChange} on:change={handleTypeChange}
options={[...Object.values(fieldDefinitions), { name: 'Auto Column', type: AUTO_COL }]} options={[
getOptionLabel={field => field.name} ...Object.values(fieldDefinitions),
getOptionValue={field => field.type} /> { name: "Auto Column", type: AUTO_COL },
]}
getOptionLabel={(field) => field.name}
getOptionValue={(field) => field.type}
/>
{#if canBeRequired || canBeDisplay} {#if canBeRequired || canBeDisplay}
<div> <div>
@ -204,14 +209,16 @@
on:change={onChangeRequired} on:change={onChangeRequired}
disabled={primaryDisplay} disabled={primaryDisplay}
thin thin
text="Required" /> text="Required"
/>
{/if} {/if}
{#if canBeDisplay} {#if canBeDisplay}
<Toggle <Toggle
bind:value={primaryDisplay} bind:value={primaryDisplay}
on:change={onChangePrimaryDisplay} on:change={onChangePrimaryDisplay}
thin thin
text="Use as table display column" /> text="Use as table display column"
/>
{/if} {/if}
</div> </div>
{/if} {/if}
@ -223,63 +230,73 @@
value={indexes[0] === field.name} value={indexes[0] === field.name}
disabled={indexes[1] === field.name} disabled={indexes[1] === field.name}
on:change={onChangePrimaryIndex} on:change={onChangePrimaryIndex}
text="Primary" /> text="Primary"
/>
<Toggle <Toggle
value={indexes[1] === field.name} value={indexes[1] === field.name}
disabled={!indexes[0] || indexes[0] === field.name} disabled={!indexes[0] || indexes[0] === field.name}
on:change={onChangeSecondaryIndex} on:change={onChangeSecondaryIndex}
text="Secondary" /> text="Secondary"
/>
</div> </div>
{/if} {/if}
{#if field.type === 'string'} {#if field.type === "string"}
<Input <Input
type="number" type="number"
label="Max Length" label="Max Length"
bind:value={field.constraints.length.maximum} /> bind:value={field.constraints.length.maximum}
{:else if field.type === 'options'} />
{:else if field.type === "options"}
<ValuesList <ValuesList
label="Options (one per line)" label="Options (one per line)"
bind:values={field.constraints.inclusion} /> bind:values={field.constraints.inclusion}
{:else if field.type === 'datetime'} />
{:else if field.type === "datetime"}
<DatePicker <DatePicker
label="Earliest" label="Earliest"
bind:value={field.constraints.datetime.earliest} /> bind:value={field.constraints.datetime.earliest}
/>
<DatePicker label="Latest" bind:value={field.constraints.datetime.latest} /> <DatePicker label="Latest" bind:value={field.constraints.datetime.latest} />
{:else if field.type === 'number'} {:else if field.type === "number"}
<Input <Input
type="number" type="number"
label="Min Value" label="Min Value"
bind:value={field.constraints.numericality.greaterThanOrEqualTo} /> bind:value={field.constraints.numericality.greaterThanOrEqualTo}
/>
<Input <Input
type="number" type="number"
label="Max Value" label="Max Value"
bind:value={field.constraints.numericality.lessThanOrEqualTo} /> bind:value={field.constraints.numericality.lessThanOrEqualTo}
{:else if field.type === 'link'} />
{:else if field.type === "link"}
<Select <Select
label="Table" label="Table"
bind:value={field.tableId} bind:value={field.tableId}
options={tableOptions} options={tableOptions}
getOptionLabel={table => table.name} getOptionLabel={(table) => table.name}
getOptionValue={table => table._id} /> getOptionValue={(table) => table._id}
/>
{#if relationshipOptions && relationshipOptions.length > 0} {#if relationshipOptions && relationshipOptions.length > 0}
<RadioGroup <RadioGroup
disabled={originalName} disabled={originalName}
label="Define the relationship" label="Define the relationship"
bind:value={field.relationshipType} bind:value={field.relationshipType}
options={relationshipOptions} options={relationshipOptions}
getOptionLabel={option => option.name} getOptionLabel={(option) => option.name}
getOptionValue={option => option.value} /> getOptionValue={(option) => option.value}
/>
{/if} {/if}
<Input label={`Column name in other table`} bind:value={field.fieldName} /> <Input label={`Column name in other table`} bind:value={field.fieldName} />
{:else if field.type === AUTO_COL} {:else if field.type === AUTO_COL}
<Select <Select
label="Auto Column Type" label="Auto Column Type"
value={field.subtype} value={field.subtype}
on:change={e => (field.subtype = e.detail)} on:change={(e) => (field.subtype = e.detail)}
options={Object.entries(getAutoColumnInformation())} options={Object.entries(getAutoColumnInformation())}
getOptionLabel={option => option[1].name} getOptionLabel={(option) => option[1].name}
getOptionValue={option => option[0]} /> getOptionValue={(option) => option[0]}
/>
{/if} {/if}
<div slot="footer"> <div slot="footer">
@ -294,4 +311,5 @@
okText="Delete Column" okText="Delete Column"
onOk={deleteColumn} onOk={deleteColumn}
onCancel={hideDeleteDialog} onCancel={hideDeleteDialog}
title="Confirm Deletion" /> title="Confirm Deletion"
/>

View File

@ -12,7 +12,7 @@
$: creating = row?._id == null $: creating = row?._id == null
$: table = row.tableId $: table = row.tableId
? $tables.list.find(table => table._id === row?.tableId) ? $tables.list.find((table) => table._id === row?.tableId)
: $tables.selected : $tables.selected
$: tableSchema = Object.entries(table?.schema ?? {}) $: tableSchema = Object.entries(table?.schema ?? {})
@ -39,9 +39,10 @@
</script> </script>
<ModalContent <ModalContent
title={creating ? 'Create Row' : 'Edit Row'} title={creating ? "Create Row" : "Edit Row"}
confirmText={creating ? 'Create Row' : 'Save Row'} confirmText={creating ? "Create Row" : "Save Row"}
onConfirm={saveRow}> onConfirm={saveRow}
>
<ErrorsBox {errors} /> <ErrorsBox {errors} />
{#each tableSchema as [key, meta]} {#each tableSchema as [key, meta]}
{#if !meta.autocolumn} {#if !meta.autocolumn}

View File

@ -13,13 +13,13 @@
$: creating = row?._id == null $: creating = row?._id == null
$: table = row.tableId $: table = row.tableId
? $tables.list.find(table => table._id === row?.tableId) ? $tables.list.find((table) => table._id === row?.tableId)
: $tables.selected : $tables.selected
$: tableSchema = getUserSchema(table) $: tableSchema = getUserSchema(table)
$: customSchemaKeys = getCustomSchemaKeys(tableSchema) $: customSchemaKeys = getCustomSchemaKeys(tableSchema)
$: if (!row.status) row.status = "active" $: if (!row.status) row.status = "active"
const getUserSchema = table => { const getUserSchema = (table) => {
let schema = table?.schema ?? {} let schema = table?.schema ?? {}
if (schema.username) { if (schema.username) {
schema.username.name = "Username" schema.username.name = "Username"
@ -27,7 +27,7 @@
return schema return schema
} }
const getCustomSchemaKeys = schema => { const getCustomSchemaKeys = (schema) => {
let customSchema = { ...schema } let customSchema = { ...schema }
delete customSchema["email"] delete customSchema["email"]
delete customSchema["roleId"] delete customSchema["roleId"]
@ -55,7 +55,7 @@
) )
if (rowResponse.errors) { if (rowResponse.errors) {
if (Array.isArray(rowResponse.errors)) { if (Array.isArray(rowResponse.errors)) {
errors = rowResponse.errors.map(error => ({ message: error })) errors = rowResponse.errors.map((error) => ({ message: error }))
} else { } else {
errors = Object.entries(rowResponse.errors) errors = Object.entries(rowResponse.errors)
.map(([key, error]) => ({ dataPath: key, message: error })) .map(([key, error]) => ({ dataPath: key, message: error }))
@ -73,17 +73,20 @@
</script> </script>
<ModalContent <ModalContent
title={creating ? 'Create User' : 'Edit User'} title={creating ? "Create User" : "Edit User"}
confirmText={creating ? 'Create User' : 'Save User'} confirmText={creating ? "Create User" : "Save User"}
onConfirm={saveRow}> onConfirm={saveRow}
>
<ErrorsBox {errors} /> <ErrorsBox {errors} />
<RowFieldControl <RowFieldControl
meta={{ ...tableSchema.email, name: 'Email' }} meta={{ ...tableSchema.email, name: "Email" }}
bind:value={row.email} bind:value={row.email}
readonly={!creating} /> readonly={!creating}
/>
<RowFieldControl <RowFieldControl
meta={{ name: 'password', type: 'password' }} meta={{ name: "password", type: "password" }}
bind:value={row.password} /> bind:value={row.password}
/>
<!-- Defer rendering this select until roles load, otherwise the initial <!-- Defer rendering this select until roles load, otherwise the initial
selection is always undefined --> selection is always undefined -->
<Select <Select
@ -91,14 +94,19 @@
data-cy="roleId-select" data-cy="roleId-select"
bind:value={row.roleId} bind:value={row.roleId}
options={$roles} options={$roles}
getOptionLabel={role => role.name} getOptionLabel={(role) => role.name}
getOptionValue={role => role._id} /> getOptionValue={(role) => role._id}
/>
<Select <Select
label="Status" label="Status"
bind:value={row.status} bind:value={row.status}
options={[{ label: 'Active', value: 'active' }, { label: 'Inactive', value: 'inactive' }]} options={[
getOptionLabel={status => status.label} { label: "Active", value: "active" },
getOptionValue={status => status.value} /> { label: "Inactive", value: "inactive" },
]}
getOptionLabel={(status) => status.label}
getOptionValue={(status) => status.value}
/>
{#each customSchemaKeys as [key, meta]} {#each customSchemaKeys as [key, meta]}
{#if !meta.autocolumn} {#if !meta.autocolumn}
<RowFieldControl {meta} bind:value={row[key]} {creating} /> <RowFieldControl {meta} bind:value={row[key]} {creating} />

View File

@ -10,7 +10,7 @@
let name let name
let field let field
$: views = $tables.list.flatMap(table => Object.keys(table.views || {})) $: views = $tables.list.flatMap((table) => Object.keys(table.views || {}))
function saveView() { function saveView() {
if (views.includes(name)) { if (views.includes(name)) {
@ -31,6 +31,7 @@
<ModalContent <ModalContent
title="Create View" title="Create View"
confirmText="Create View" confirmText="Create View"
onConfirm={saveView}> onConfirm={saveView}
>
<Input label="View Name" thin bind:value={name} /> <Input label="View Name" thin bind:value={name} />
</ModalContent> </ModalContent>

View File

@ -11,7 +11,7 @@
let errors = [] let errors = []
let builtInRoles = ["Admin", "Power", "Basic", "Public"] let builtInRoles = ["Admin", "Power", "Basic", "Public"]
$: selectedRoleId = selectedRole._id $: selectedRoleId = selectedRole._id
$: otherRoles = $roles.filter(role => role._id !== selectedRoleId) $: otherRoles = $roles.filter((role) => role._id !== selectedRoleId)
$: isCreating = selectedRoleId == null || selectedRoleId === "" $: isCreating = selectedRoleId == null || selectedRoleId === ""
const fetchBasePermissions = async () => { const fetchBasePermissions = async () => {
@ -20,9 +20,9 @@
} }
// Changes the selected role // Changes the selected role
const changeRole = event => { const changeRole = (event) => {
const id = event?.detail const id = event?.detail
const role = $roles.find(role => role._id === id) const role = $roles.find((role) => role._id === id)
if (role) { if (role) {
selectedRole = { selectedRole = {
...role, ...role,
@ -41,7 +41,7 @@
// Clean up empty strings // Clean up empty strings
const keys = ["_id", "inherits", "permissionId"] const keys = ["_id", "inherits", "permissionId"]
keys.forEach(key => { keys.forEach((key) => {
if (selectedRole[key] === "") { if (selectedRole[key] === "") {
delete selectedRole[key] delete selectedRole[key]
} }
@ -84,8 +84,9 @@
<ModalContent <ModalContent
title="Edit Roles" title="Edit Roles"
confirmText={isCreating ? 'Create' : 'Save'} confirmText={isCreating ? "Create" : "Save"}
onConfirm={saveRole}> onConfirm={saveRole}
>
{#if errors.length} {#if errors.length}
<ErrorsBox {errors} /> <ErrorsBox {errors} />
{/if} {/if}
@ -97,27 +98,31 @@
on:change={changeRole} on:change={changeRole}
options={$roles} options={$roles}
placeholder="Create new role" placeholder="Create new role"
getOptionValue={role => role._id} getOptionValue={(role) => role._id}
getOptionLabel={role => role.name} /> getOptionLabel={(role) => role.name}
/>
{#if selectedRole} {#if selectedRole}
<Input <Input
label="Name" label="Name"
bind:value={selectedRole.name} bind:value={selectedRole.name}
disabled={builtInRoles.includes(selectedRole.name)} /> disabled={builtInRoles.includes(selectedRole.name)}
/>
<Select <Select
label="Inherits Role" label="Inherits Role"
bind:value={selectedRole.inherits} bind:value={selectedRole.inherits}
options={otherRoles} options={otherRoles}
getOptionValue={role => role._id} getOptionValue={(role) => role._id}
getOptionLabel={role => role.name} getOptionLabel={(role) => role.name}
placeholder="None" /> placeholder="None"
/>
<Select <Select
label="Base Permissions" label="Base Permissions"
bind:value={selectedRole.permissionId} bind:value={selectedRole.permissionId}
options={basePermissions} options={basePermissions}
getOptionValue={x => x._id} getOptionValue={(x) => x._id}
getOptionLabel={x => x.name} getOptionLabel={(x) => x.name}
placeholder="Choose permissions" /> placeholder="Choose permissions"
/>
{/if} {/if}
<div slot="footer"> <div slot="footer">
{#if !isCreating} {#if !isCreating}

View File

@ -32,6 +32,7 @@
bind:value={exportFormat} bind:value={exportFormat}
options={FORMATS} options={FORMATS}
placeholder={null} placeholder={null}
getOptionLabel={x => x.name} getOptionLabel={(x) => x.name}
getOptionValue={x => x.key} /> getOptionValue={(x) => x.key}
/>
</ModalContent> </ModalContent>

View File

@ -10,7 +10,7 @@
$: fields = $: fields =
viewTable && viewTable &&
Object.entries(viewTable.schema) Object.entries(viewTable.schema)
.filter(entry => entry[1].type !== FIELDS.LINK.type) .filter((entry) => entry[1].type !== FIELDS.LINK.type)
.map(([key]) => key) .map(([key]) => key)
function saveView() { function saveView() {

View File

@ -8,14 +8,16 @@
{height} {height}
viewBox="0 0 256 215" viewBox="0 0 256 215"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0)"> <g clip-path="url(#clip0)">
<path <path
d="M114.259 2.701L18.86 42.176C13.555 44.371 13.61 51.906 18.949 d="M114.259 2.701L18.86 42.176C13.555 44.371 13.61 51.906 18.949
54.023L114.746 92.012C123.163 95.3503 132.537 95.3503 140.954 54.023L114.746 92.012C123.163 95.3503 132.537 95.3503 140.954
92.012L236.753 54.022C242.09 51.907 242.146 44.372 236.839 42.176L141.442 92.012L236.753 54.022C242.09 51.907 242.146 44.372 236.839 42.176L141.442
2.7C132.739 -0.901099 122.962 -0.901099 114.259 2.7" 2.7C132.739 -0.901099 122.962 -0.901099 114.259 2.7"
fill="#FFBF00" /> fill="#FFBF00"
/>
<path <path
d="M136.35 112.757V207.659C136.35 212.173 140.9 215.264 145.096 d="M136.35 112.757V207.659C136.35 212.173 140.9 215.264 145.096
213.601L251.844 172.166C253.034 171.694 254.056 170.875 254.775 213.601L251.844 172.166C253.034 171.694 254.056 170.875 254.775
@ -23,20 +25,23 @@
66.808 251.328 63.718 247.132 65.381L140.384 106.815C139.194 107.287 66.808 251.328 63.718 247.132 65.381L140.384 106.815C139.194 107.287
138.172 108.106 137.453 109.166C136.734 110.225 136.349 111.476 136.349 138.172 108.106 137.453 109.166C136.734 110.225 136.349 111.476 136.349
112.757" 112.757"
fill="#26B5F8" /> fill="#26B5F8"
/>
<path <path
d="M111.423 117.654L79.743 132.95L76.526 134.505L9.65 166.548C5.411 d="M111.423 117.654L79.743 132.95L76.526 134.505L9.65 166.548C5.411
168.593 0 165.504 0 160.795V71.72C0 70.016 0.874 68.545 2.046 168.593 0 165.504 0 160.795V71.72C0 70.016 0.874 68.545 2.046
67.437C2.52616 66.9592 3.07076 66.5509 3.664 66.224C5.262 65.265 7.542 67.437C2.52616 66.9592 3.07076 66.5509 3.664 66.224C5.262 65.265 7.542
65.009 9.48 65.776L110.89 105.956C116.045 108.001 116.45 115.224 111.423 65.009 9.48 65.776L110.89 105.956C116.045 108.001 116.45 115.224 111.423
117.653" 117.653"
fill="#ED3049" /> fill="#ED3049"
/>
<path <path
d="M111.423 117.654L79.743 132.95L2.045 67.438C2.52516 66.9602 3.06976 d="M111.423 117.654L79.743 132.95L2.045 67.438C2.52516 66.9602 3.06976
66.5519 3.663 66.225C5.261 65.266 7.541 65.01 9.479 65.777L110.889 66.5519 3.663 66.225C5.261 65.266 7.541 65.01 9.479 65.777L110.889
105.957C116.044 108.002 116.449 115.225 111.422 117.654" 105.957C116.044 108.002 116.449 115.225 111.422 117.654"
fill="black" fill="black"
fill-opacity="0.25" /> fill-opacity="0.25"
/>
</g> </g>
<defs> <defs>
<clipPath id="clip0"> <clipPath id="clip0">

View File

@ -11,31 +11,38 @@
y="0px" y="0px"
{width} {width}
{height} {height}
viewBox="0 0 2900 2000"> viewBox="0 0 2900 2000"
>
<g id="layer101"> <g id="layer101">
<path <path
fill="#5b350f" fill="#5b350f"
d="M735 1983 c-137 -19 -322 -95 -431 -175 -138 -103 -250 -315 -284 -542 -24 -161 22 -298 129 -382 123 -97 318 -180 577 -243 l130 -32 29 -67 c41 -94 135 -231 199 -289 292 -267 732 -319 1094 -128 148 79 224 151 418 400 137 176 173 242 228 414 41 130 70 301 70 416 0 236 -146 421 -382 484 -206 56 -392 19 -733 -144 -96 -47 -181 -85 -189 -85 -7 0 -61 46 -119 103 -163 159 -283 231 -433 261 -71 15 -229 19 -303 9z" /> d="M735 1983 c-137 -19 -322 -95 -431 -175 -138 -103 -250 -315 -284 -542 -24 -161 22 -298 129 -382 123 -97 318 -180 577 -243 l130 -32 29 -67 c41 -94 135 -231 199 -289 292 -267 732 -319 1094 -128 148 79 224 151 418 400 137 176 173 242 228 414 41 130 70 301 70 416 0 236 -146 421 -382 484 -206 56 -392 19 -733 -144 -96 -47 -181 -85 -189 -85 -7 0 -61 46 -119 103 -163 159 -283 231 -433 261 -71 15 -229 19 -303 9z"
/>
</g> </g>
<g id="layer102"> <g id="layer102">
<path <path
fill="#406f23" fill="#406f23"
d="M735 1983 c-137 -19 -322 -95 -431 -175 -138 -103 -250 -315 -284 -542 -24 -161 22 -298 129 -382 123 -97 318 -180 577 -243 l130 -32 29 -67 c41 -94 135 -231 199 -289 292 -267 732 -319 1094 -128 148 79 224 151 418 400 137 176 173 242 228 414 41 130 70 301 70 416 0 236 -146 421 -382 484 -206 56 -392 19 -733 -144 -96 -47 -181 -85 -189 -85 -7 0 -61 46 -119 103 -163 159 -283 231 -433 261 -71 15 -229 19 -303 9z m460 -643 c163 -51 296 -150 329 -246 23 -69 20 -93 -20 -174 -51 -100 -126 -173 -238 -230 l-89 -45 -131 0 c-151 0 -222 18 -323 84 -138 89 -243 264 -243 406 0 62 12 76 120 134 160 85 229 102 405 96 87 -2 139 -9 190 -25z" /> d="M735 1983 c-137 -19 -322 -95 -431 -175 -138 -103 -250 -315 -284 -542 -24 -161 22 -298 129 -382 123 -97 318 -180 577 -243 l130 -32 29 -67 c41 -94 135 -231 199 -289 292 -267 732 -319 1094 -128 148 79 224 151 418 400 137 176 173 242 228 414 41 130 70 301 70 416 0 236 -146 421 -382 484 -206 56 -392 19 -733 -144 -96 -47 -181 -85 -189 -85 -7 0 -61 46 -119 103 -163 159 -283 231 -433 261 -71 15 -229 19 -303 9z m460 -643 c163 -51 296 -150 329 -246 23 -69 20 -93 -20 -174 -51 -100 -126 -173 -238 -230 l-89 -45 -131 0 c-151 0 -222 18 -323 84 -138 89 -243 264 -243 406 0 62 12 76 120 134 160 85 229 102 405 96 87 -2 139 -9 190 -25z"
/>
</g> </g>
<g id="layer103"> <g id="layer103">
<path <path
fill="#c6d821" fill="#c6d821"
d="M2215 1789 c-27 -4 -68 -15 -90 -23 -42 -15 -264 -116 -397 -180 l-77 -38 78 -102 c102 -134 144 -208 175 -305 37 -116 49 -200 44 -309 -7 -157 -46 -218 -175 -278 -94 -44 -178 -56 -313 -43 -108 10 -401 53 -479 70 -24 5 -45 8 -47 6 -2 -2 20 -44 49 -92 67 -115 176 -225 281 -284 87 -49 235 -103 335 -121 91 -16 253 -14 346 5 175 37 269 95 419 264 307 347 422 563 457 859 18 148 9 247 -29 325 -88 179 -340 286 -577 246z" /> d="M2215 1789 c-27 -4 -68 -15 -90 -23 -42 -15 -264 -116 -397 -180 l-77 -38 78 -102 c102 -134 144 -208 175 -305 37 -116 49 -200 44 -309 -7 -157 -46 -218 -175 -278 -94 -44 -178 -56 -313 -43 -108 10 -401 53 -479 70 -24 5 -45 8 -47 6 -2 -2 20 -44 49 -92 67 -115 176 -225 281 -284 87 -49 235 -103 335 -121 91 -16 253 -14 346 5 175 37 269 95 419 264 307 347 422 563 457 859 18 148 9 247 -29 325 -88 179 -340 286 -577 246z"
/>
<path <path
fill="#c6d821" fill="#c6d821"
d="M549 1680 c-272 -34 -426 -142 -495 -346 -22 -68 -26 -91 -22 -164 6 -115 32 -173 112 -248 70 -65 236 -153 370 -196 241 -79 722 -172 985 -192 180 -14 343 55 404 170 34 64 30 168 -11 271 -88 223 -245 373 -568 542 -222 116 -379 161 -584 168 -69 2 -155 0 -191 -5z m646 -340 c163 -51 296 -150 329 -246 23 -69 20 -93 -20 -174 -50 -100 -126 -173 -235 -229 -84 -42 -90 -44 -200 -48 -190 -8 -312 37 -434 161 -98 99 -155 221 -155 331 0 62 12 76 120 134 160 85 229 102 405 96 87 -2 139 -9 190 -25z" /> d="M549 1680 c-272 -34 -426 -142 -495 -346 -22 -68 -26 -91 -22 -164 6 -115 32 -173 112 -248 70 -65 236 -153 370 -196 241 -79 722 -172 985 -192 180 -14 343 55 404 170 34 64 30 168 -11 271 -88 223 -245 373 -568 542 -222 116 -379 161 -584 168 -69 2 -155 0 -191 -5z m646 -340 c163 -51 296 -150 329 -246 23 -69 20 -93 -20 -174 -50 -100 -126 -173 -235 -229 -84 -42 -90 -44 -200 -48 -190 -8 -312 37 -434 161 -98 99 -155 221 -155 331 0 62 12 76 120 134 160 85 229 102 405 96 87 -2 139 -9 190 -25z"
/>
</g> </g>
<g id="layer104"> <g id="layer104">
<path <path
fill="#f6f654" fill="#f6f654"
d="M2190 1721 c-57 -19 -469 -184 -494 -198 -12 -7 -5 -21 34 -72 28 -35 71 -96 97 -137 l46 -74 69 0 c38 0 83 -6 102 -14 52 -22 105 -75 139 -140 28 -55 32 -70 32 -147 0 -84 -2 -90 -48 -183 -96 -187 -234 -296 -376 -296 -44 0 -80 7 -110 20 -28 13 -65 20 -105 20 -72 0 -264 22 -426 49 -63 10 -117 17 -118 15 -10 -8 59 -113 110 -169 106 -115 238 -183 448 -231 155 -35 313 -29 447 17 78 27 210 117 279 191 82 89 277 353 336 456 92 159 137 344 125 513 -9 117 -37 189 -101 258 -109 116 -332 172 -486 122z" /> d="M2190 1721 c-57 -19 -469 -184 -494 -198 -12 -7 -5 -21 34 -72 28 -35 71 -96 97 -137 l46 -74 69 0 c38 0 83 -6 102 -14 52 -22 105 -75 139 -140 28 -55 32 -70 32 -147 0 -84 -2 -90 -48 -183 -96 -187 -234 -296 -376 -296 -44 0 -80 7 -110 20 -28 13 -65 20 -105 20 -72 0 -264 22 -426 49 -63 10 -117 17 -118 15 -10 -8 59 -113 110 -169 106 -115 238 -183 448 -231 155 -35 313 -29 447 17 78 27 210 117 279 191 82 89 277 353 336 456 92 159 137 344 125 513 -9 117 -37 189 -101 258 -109 116 -332 172 -486 122z"
/>
<path <path
fill="#f6f654" fill="#f6f654"
d="M490 1624 c-153 -33 -275 -125 -339 -257 -54 -109 -59 -201 -17 -301 32 -76 164 -189 288 -245 51 -23 260 -91 281 -91 3 0 -21 25 -54 56 -94 91 -150 193 -170 313 -14 90 1 111 123 172 161 81 195 91 343 96 111 5 143 2 215 -16 221 -55 380 -192 380 -327 0 -52 -46 -143 -106 -212 -75 -85 -233 -170 -323 -173 -25 -1 -25 -1 4 -10 140 -43 411 -62 527 -38 142 30 238 125 238 234 0 88 -58 230 -139 337 -105 139 -431 343 -676 423 -161 52 -429 71 -575 39z" /> d="M490 1624 c-153 -33 -275 -125 -339 -257 -54 -109 -59 -201 -17 -301 32 -76 164 -189 288 -245 51 -23 260 -91 281 -91 3 0 -21 25 -54 56 -94 91 -150 193 -170 313 -14 90 1 111 123 172 161 81 195 91 343 96 111 5 143 2 215 -16 221 -55 380 -192 380 -327 0 -52 -46 -143 -106 -212 -75 -85 -233 -170 -323 -173 -25 -1 -25 -1 4 -10 140 -43 411 -62 527 -38 142 30 238 125 238 234 0 88 -58 230 -139 337 -105 139 -431 343 -676 423 -161 52 -429 71 -575 39z"
/>
</g> </g>
</svg> </svg>

View File

@ -8,7 +8,8 @@
{height} {height}
viewBox="0 0 175 115" viewBox="0 0 175 115"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M142.187 76.6667C142.187 83.9288 138.367 87.4876 131.249 d="M142.187 76.6667C142.187 83.9288 138.367 87.4876 131.249
87.6136V87.6184H43.7507V87.6136C36.6331 87.4876 32.8132 83.9288 32.8132 87.6136V87.6184H43.7507V87.6136C36.6331 87.4876 32.8132 83.9288 32.8132
@ -31,5 +32,6 @@
54.703 38.5444 60.0403 49.2194 60.2292V60.2381H125.782V60.2299C136.456 54.703 38.5444 60.0403 49.2194 60.2292V60.2381H125.782V60.2299C136.456
60.0416 142.187 54.7037 142.187 43.8109C142.187 32.9174 147.918 27.5795 60.0416 142.187 54.7037 142.187 43.8109C142.187 32.9174 147.918 27.5795
158.593 27.3912V27.381H158.594Z" 158.593 27.3912V27.381H158.594Z"
fill="#E42528" /> fill="#E42528"
/>
</svg> </svg>

View File

@ -8,16 +8,19 @@
{height} {height}
viewBox="0 0 256 289" viewBox="0 0 256 289"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0)"> <g clip-path="url(#clip0)">
<path <path
d="M165.258 288.501H168.766L226.027 259.867L226.98 258.52V29.964L226.027 d="M165.258 288.501H168.766L226.027 259.867L226.98 258.52V29.964L226.027
28.61L168.766 0H165.215L165.258 288.501Z" 28.61L168.766 0H165.215L165.258 288.501Z"
fill="#5294CF" /> fill="#5294CF"
/>
<path <path
d="M90.741 288.501H87.184L29.972 259.867L28.811 257.87L28.222 d="M90.741 288.501H87.184L29.972 259.867L28.811 257.87L28.222
31.128L29.972 28.61L87.184 0H90.785L90.741 288.501Z" 31.128L29.972 28.61L87.184 0H90.785L90.741 288.501Z"
fill="#1F5B98" /> fill="#1F5B98"
/>
<path d="M87.285 0H168.711V288.501H87.285V0Z" fill="#2D72B8" /> <path d="M87.285 0H168.711V288.501H87.285V0Z" fill="#2D72B8" />
<path <path
d="M256 137.769L254.065 137.34L226.437 134.764L226.027 134.968L168.715 d="M256 137.769L254.065 137.34L226.437 134.764L226.027 134.968L168.715
@ -33,22 +36,27 @@
210.584V210.6H87.285V210.584L29.972 197.325V153.461L87.285 210.584V210.6H87.285V210.584L29.972 197.325V153.461L87.285
155.745V155.801H168.715L226.027 153.461L227.332 154.061L254.111 155.745V155.801H168.715L226.027 153.461L227.332 154.061L254.111
151.755L256 150.832L247.096 150.704V137.897L256 137.769" 151.755L256 150.832L247.096 150.704V137.897L256 137.769"
fill="#1A476F" /> fill="#1A476F"
/>
<path <path
d="M226.027 215.966V259.867L256 224.749V194.288L226.2 215.914L226.027 d="M226.027 215.966V259.867L256 224.749V194.288L226.2 215.914L226.027
215.966Z" 215.966Z"
fill="#2D72B8" /> fill="#2D72B8"
/>
<path <path
d="M226.027 197.421L226.2 197.381L256 181.353V150.704L226.027 d="M226.027 197.421L226.2 197.381L256 181.353V150.704L226.027
153.461V197.421" 153.461V197.421"
fill="#2D72B8" /> fill="#2D72B8"
/>
<path <path
d="M226.2 91.208L226.027 91.168V134.968L256 137.769V107.135L226.2 91.208Z" d="M226.2 91.208L226.027 91.168V134.968L256 137.769V107.135L226.2 91.208Z"
fill="#2D72B8" /> fill="#2D72B8"
/>
<path <path
d="M226.2 72.687L256 94.193V63.731L226.027 28.61V72.515L226.2 d="M226.2 72.687L256 94.193V63.731L226.027 28.61V72.515L226.2
72.575V72.687Z" 72.575V72.687Z"
fill="#2D72B8" /> fill="#2D72B8"
/>
</g> </g>
<defs> <defs>
<clipPath id="clip0"> <clipPath id="clip0">

View File

@ -8,36 +8,43 @@
{height} {height}
viewBox="0 0 128 143" viewBox="0 0 128 143"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0)"> <g clip-path="url(#clip0)">
<path <path
d="M7.172 40.0865H101.775C112.201 40.0865 121.51 35.3065 127.757 d="M7.172 40.0865H101.775C112.201 40.0865 121.51 35.3065 127.757
27.843C114.727 10.918 94.2765 0 71.265 0C43.089 0 18.738 16.3555 7.172 27.843C114.727 10.918 94.2765 0 71.265 0C43.089 0 18.738 16.3555 7.172
40.0865Z" 40.0865Z"
fill="#F0BF1A" /> fill="#F0BF1A"
/>
<path <path
d="M93.7575 51.222H2.8775C0.969102 57.732 0.000154178 64.4811 0 71.265C0 d="M93.7575 51.222H2.8775C0.969102 57.732 0.000154178 64.4811 0 71.265C0
78.227 1.0165 84.9485 2.8775 91.3085H93.7575C104.67 91.3085 113.801 78.227 1.0165 84.9485 2.8775 91.3085H93.7575C104.67 91.3085 113.801
82.4005 113.801 71.265C113.801 60.13 104.893 51.222 93.7575 51.222" 82.4005 113.801 71.265C113.801 60.13 104.893 51.222 93.7575 51.222"
fill="#07A5DE" /> fill="#07A5DE"
/>
<path <path
d="M128 114.378C121.793 107.082 112.559 102.443 102.22 d="M128 114.378C121.793 107.082 112.559 102.443 102.22
102.443H7.173C18.7385 126.175 43.0895 142.53 71.265 142.53C94.418 142.53 102.443H7.173C18.7385 126.175 43.0895 142.53 71.265 142.53C94.418 142.53
114.983 131.482 128 114.378Z" 114.983 131.482 128 114.378Z"
fill="#3EBEB0" /> fill="#3EBEB0"
/>
<path <path
d="M2.87749 51.222C-0.959651 64.3087 -0.959651 78.2218 2.87749 d="M2.87749 51.222C-0.959651 64.3087 -0.959651 78.2218 2.87749
91.3085H62.357C63.916 85.2955 64.8065 78.6145 64.8065 71.265C64.8065 91.3085H62.357C63.916 85.2955 64.8065 78.6145 64.8065 71.265C64.8065
63.916 63.916 57.235 62.3565 51.222H2.87849H2.87749Z" 63.916 63.916 57.235 62.3565 51.222H2.87849H2.87749Z"
fill="#231F20" /> fill="#231F20"
/>
<path <path
d="M35.41 9.5765C23.3835 16.703 13.362 27.3925 7.1265 d="M35.41 9.5765C23.3835 16.703 13.362 27.3925 7.1265
40.0865H59.6845C54.3395 27.838 45.877 17.594 35.4095 9.5765" 40.0865H59.6845C54.3395 27.838 45.877 17.594 35.4095 9.5765"
fill="#D7A229" /> fill="#D7A229"
/>
<path <path
d="M37.637 134.068C47.881 125.828 56.121 114.915 61.2435 d="M37.637 134.068C47.881 125.828 56.121 114.915 61.2435
102.443H7.1265C13.8075 115.806 24.4975 126.941 37.637 134.068Z" 102.443H7.1265C13.8075 115.806 24.4975 126.941 37.637 134.068Z"
fill="#019B8F" /> fill="#019B8F"
/>
</g> </g>
<defs> <defs>
<clipPath id="clip0"> <clipPath id="clip0">

View File

@ -8,31 +8,36 @@
{height} {height}
viewBox="0 0 179 179" viewBox="0 0 179 179"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M153.828 30.7656H101.806L90.0594 d="M153.828 30.7656H101.806L90.0594
54.2594H24.6125V148.234H165.575V30.7656H153.828ZM153.828 54.2594H24.6125V148.234H165.575V30.7656H153.828ZM153.828
54.2594H107.959L114.112 42.5125H153.828V54.2594Z" 54.2594H107.959L114.112 42.5125H153.828V54.2594Z"
fill="#458248" /> fill="#458248"
/>
<path <path
d="M149.773 173.406L146.623 172.36C146.623 172.36 147.026 156.412 141.276 d="M149.773 173.406L146.623 172.36C146.623 172.36 147.026 156.412 141.276
155.299C137.483 150.903 141.835 -32.4046 155.635 154.673C153.015 156 151.011 155.299C137.483 150.903 141.835 -32.4046 155.635 154.673C153.015 156 151.011
158.289 150.041 161.061C149.521 165.155 149.431 169.293 149.773 158.289 150.041 161.061C149.521 165.155 149.431 169.293 149.773
173.406V173.406Z" 173.406V173.406Z"
fill="url(#paint0_linear)" /> fill="url(#paint0_linear)"
/>
<path <path
d="M151.473 158.007C159.86 151.69 166.283 143.124 169.994 133.302C173.705 d="M151.473 158.007C159.86 151.69 166.283 143.124 169.994 133.302C173.705
123.48 174.553 112.807 172.439 102.522C166.285 75.3142 151.68 66.3698 123.48 174.553 112.807 172.439 102.522C166.285 75.3142 151.68 66.3698
150.108 62.9577C148.75 60.8316 147.591 58.5845 146.646 56.2452L147.809 150.108 62.9577C148.75 60.8316 147.591 58.5845 146.646 56.2452L147.809
132.052C147.809 132.052 145.398 155.215 151.473 158.007Z" 132.052C147.809 132.052 145.398 155.215 151.473 158.007Z"
fill="url(#paint1_linear)" /> fill="url(#paint1_linear)"
/>
<path <path
d="M145.018 159.014C145.018 159.014 119.337 141.522 120.825 110.583C120.964 d="M145.018 159.014C145.018 159.014 119.337 141.522 120.825 110.583C120.964
101.255 123.102 92.0662 127.096 83.636C131.091 75.2058 136.847 67.7308 101.255 123.102 92.0662 127.096 83.636C131.091 75.2058 136.847 67.7308
143.978 61.7158C144.809 61.0059 145.469 60.1177 145.91 59.1173C146.351 143.978 61.7158C144.809 61.0059 145.469 60.1177 145.91 59.1173C146.351
58.1169 146.56 57.03 146.523 55.9375C148.123 59.3777 147.86 107.299 148.027 58.1169 146.56 57.03 146.523 55.9375C148.123 59.3777 147.86 107.299 148.027
112.904C148.682 134.709 146.819 154.897 145.018 159.014V159.014Z" 112.904C148.682 134.709 146.819 154.897 145.018 159.014V159.014Z"
fill="url(#paint2_linear)" /> fill="url(#paint2_linear)"
/>
<defs> <defs>
<linearGradient <linearGradient
id="paint0_linear" id="paint0_linear"
@ -40,7 +45,8 @@
y1="115.729" y1="115.729"
x2="164.805" x2="164.805"
y2="128.016" y2="128.016"
gradientUnits="userSpaceOnUse"> gradientUnits="userSpaceOnUse"
>
<stop offset="0.231" stop-color="#999875" /> <stop offset="0.231" stop-color="#999875" />
<stop offset="0.563" stop-color="#9B9977" /> <stop offset="0.563" stop-color="#9B9977" />
<stop offset="0.683" stop-color="#A09F7E" /> <stop offset="0.683" stop-color="#A09F7E" />
@ -57,7 +63,8 @@
y1="55.7038" y1="55.7038"
x2="157.883" x2="157.883"
y2="155.673" y2="155.673"
gradientUnits="userSpaceOnUse"> gradientUnits="userSpaceOnUse"
>
<stop stop-color="#48A547" /> <stop stop-color="#48A547" />
<stop offset="1" stop-color="#3F9143" /> <stop offset="1" stop-color="#3F9143" />
</linearGradient> </linearGradient>
@ -67,7 +74,8 @@
y1="113.645" y1="113.645"
x2="161.577" x2="161.577"
y2="99.2572" y2="99.2572"
gradientUnits="userSpaceOnUse"> gradientUnits="userSpaceOnUse"
>
<stop stop-color="#41A247" /> <stop stop-color="#41A247" />
<stop offset="0.352" stop-color="#4BA74B" /> <stop offset="0.352" stop-color="#4BA74B" />
<stop offset="0.956" stop-color="#67B554" /> <stop offset="0.956" stop-color="#67B554" />

View File

@ -8,12 +8,14 @@
{height} {height}
viewBox="0 0 147 147" viewBox="0 0 147 147"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M128.244 27.5625H83.3444L74.1569 d="M128.244 27.5625H83.3444L74.1569
45.9375H22.9688V124.031H137.812V27.5625H128.244ZM128.625 45.9375H22.9688V124.031H137.812V27.5625H128.244ZM128.625
45.9375H92.7478L97.5621 36.75H128.625V45.9375Z" 45.9375H92.7478L97.5621 36.75H128.625V45.9375Z"
fill="#2A4B59" /> fill="#2A4B59"
/>
<path <path
fill-rule="evenodd" fill-rule="evenodd"
clip-rule="evenodd" clip-rule="evenodd"
@ -23,7 +25,8 @@
73.4258 75.6415 72.917 75.8825 72.3379C76.1234 71.7589 76.2141 71.1283 73.4258 75.6415 72.917 75.8825 72.3379C76.1234 71.7589 76.2141 71.1283
76.146 70.5048C75.8564 70.0602 75.5911 69.6001 75.3513 69.1267C74.9562 76.146 70.5048C75.8564 70.0602 75.5911 69.6001 75.3513 69.1267C74.9562
68.4652 74.0926 68.1345 73.5597 67.6062" 68.4652 74.0926 68.1345 73.5597 67.6062"
fill="white" /> fill="white"
/>
<path <path
fill-rule="evenodd" fill-rule="evenodd"
clip-rule="evenodd" clip-rule="evenodd"
@ -79,5 +82,6 @@
114.951 109.408 116.856 112.175C117.848 113.553 121.822 114.293 123.609 114.951 109.408 116.856 112.175C117.848 113.553 121.822 114.293 123.609
115.023C125.17 115.557 126.703 116.17 128.202 116.86C130.453 118.239 132.7 115.023C125.17 115.557 126.703 116.17 128.202 116.86C130.453 118.239 132.7
119.842 134.822 121.367C135.879 122.162 139.191 123.815 139.388 125.143" 119.842 134.822 121.367C135.879 122.162 139.191 123.815 139.388 125.143"
fill="#F3FDFF" /> fill="#F3FDFF"
/>
</svg> </svg>

View File

@ -8,7 +8,8 @@
{height} {height}
viewBox="0 0 170 175" viewBox="0 0 170 175"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M169.341 104.792C168.322 101.71 165.652 99.5637 162.199 99.0487C160.57 d="M169.341 104.792C168.322 101.71 165.652 99.5637 162.199 99.0487C160.57
98.8061 158.706 98.9095 156.499 99.3635C152.653 100.156 149.799 100.457 98.8061 158.706 98.9095 156.499 99.3635C152.653 100.156 149.799 100.457
@ -32,7 +33,8 @@
134.335 126.893 134.386 126.453L134.492 125.551L135.685 125.655L135.993 134.335 126.893 134.386 126.453L134.492 125.551L135.685 125.655L135.993
125.676C142.635 125.978 150.756 124.572 155.744 122.259C159.685 120.434 125.676C142.635 125.978 150.756 124.572 155.744 122.259C159.685 120.434
172.315 113.778 169.341 104.792" 172.315 113.778 169.341 104.792"
fill="black" /> fill="black"
/>
<path <path
d="M157.984 106.539C138.235 110.606 136.877 103.931 136.877 103.931C157.729 d="M157.984 106.539C138.235 110.606 136.877 103.931 136.877 103.931C157.729
73.046 166.446 33.8413 158.924 24.2462C138.402 -1.92761 102.878 10.451 73.046 166.446 33.8413 158.924 24.2462C138.402 -1.92761 102.878 10.451
@ -50,21 +52,24 @@
130.43C128.417 120.001 127.363 116.636 134.573 118.201L136.326 130.43C128.417 120.001 127.363 116.636 134.573 118.201L136.326
118.355C141.632 118.596 148.578 117.503 152.655 115.611C161.432 111.545 118.355C141.632 118.596 148.578 117.503 152.655 115.611C161.432 111.545
166.639 104.755 157.983 106.539H157.984" 166.639 104.755 157.983 106.539H157.984"
fill="#336791" /> fill="#336791"
/>
<path <path
d="M71.7692 54.0412C69.9895 53.7939 68.3778 54.0226 67.5623 54.6391C67.1041 d="M71.7692 54.0412C69.9895 53.7939 68.3778 54.0226 67.5623 54.6391C67.1041
54.9858 66.962 55.3875 66.9235 55.6639C66.8212 56.3964 67.3352 57.2064 54.9858 66.962 55.3875 66.9235 55.6639C66.8212 56.3964 67.3352 57.2064
67.6513 57.624C68.5452 58.8066 69.8507 59.6193 71.143 59.7983C71.3302 67.6513 57.624C68.5452 58.8066 69.8507 59.6193 71.143 59.7983C71.3302
59.8248 71.5168 59.8367 71.7021 59.8367C73.857 59.8367 75.8167 58.1616 59.8248 71.5168 59.8367 71.7021 59.8367C73.857 59.8367 75.8167 58.1616
75.9893 56.9254C76.2051 55.3769 73.9533 54.3448 71.7692 54.0418" 75.9893 56.9254C76.2051 55.3769 73.9533 54.3448 71.7692 54.0418"
fill="white" /> fill="white"
/>
<path <path
d="M130.727 54.0902C130.557 52.8765 128.394 52.5305 126.341 52.8155C124.29 d="M130.727 54.0902C130.557 52.8765 128.394 52.5305 126.341 52.8155C124.29
53.1006 122.302 54.0246 122.468 55.241C122.601 56.1869 124.312 57.8017 53.1006 122.302 54.0246 122.468 55.241C122.601 56.1869 124.312 57.8017
126.337 57.8017C126.509 57.8017 126.681 57.7904 126.855 57.7659C128.207 126.337 57.8017C126.509 57.8017 126.681 57.7904 126.855 57.7659C128.207
57.579 129.199 56.7219 129.671 56.228C130.388 55.475 130.804 54.6358 130.727 57.579 129.199 56.7219 129.671 56.228C130.388 55.475 130.804 54.6358 130.727
54.0902" 54.0902"
fill="white" /> fill="white"
/>
<path <path
d="M164.556 106.077C163.803 103.804 161.379 103.073 157.352 103.903C145.396 d="M164.556 106.077C163.803 103.804 161.379 103.073 157.352 103.903C145.396
106.366 141.114 104.66 139.708 103.627C149.002 89.494 156.647 72.4103 106.366 141.114 104.66 139.708 103.627C149.002 89.494 156.647 72.4103
@ -145,5 +150,6 @@
136.156 107.46 136.491 107.343C136.699 107.512 136.926 107.68 137.176 136.156 107.46 136.491 107.343C136.699 107.512 136.926 107.68 137.176
107.844C141.168 110.475 148.289 110.758 158.342 108.687L158.453 107.844C141.168 110.475 148.289 110.758 158.342 108.687L158.453
108.665C157.097 109.931 154.776 111.629 151.487 113.154Z" 108.665C157.097 109.931 154.776 111.629 151.487 113.154Z"
fill="white" /> fill="white"
/>
</svg> </svg>

View File

@ -8,12 +8,14 @@
{height} {height}
viewBox="0 0 120 120" viewBox="0 0 120 120"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M103.125 20.625H68.25L60.375 d="M103.125 20.625H68.25L60.375
36.375H16.5V99.375H111V20.625H103.125ZM103.125 36.375H72.375L76.5 36.375H16.5V99.375H111V20.625H103.125ZM103.125 36.375H72.375L76.5
28.5H103.125V36.375Z" 28.5H103.125V36.375Z"
fill="#FFBA58" /> fill="#FFBA58"
/>
<path <path
d="M75 46.875V52.5H60C58.0127 52.5059 56.1085 53.298 54.7033 54.7033C53.298 d="M75 46.875V52.5H60C58.0127 52.5059 56.1085 53.298 54.7033 54.7033C53.298
56.1085 52.5059 58.0127 52.5 60V75H46.875C44.3886 75 42.004 75.9877 40.2459 56.1085 52.5059 58.0127 52.5 60V75H46.875C44.3886 75 42.004 75.9877 40.2459
@ -32,5 +34,6 @@
44.3886 92.7623 42.004 91.0041 40.2459C89.246 38.4877 86.8614 37.5 84.375 44.3886 92.7623 42.004 91.0041 40.2459C89.246 38.4877 86.8614 37.5 84.375
37.5C81.8886 37.5 79.504 38.4877 77.7459 40.2459C75.9877 42.004 75 44.3886 37.5C81.8886 37.5 79.504 38.4877 77.7459 40.2459C75.9877 42.004 75 44.3886
75 46.875Z" 75 46.875Z"
fill="#E76A00" /> fill="#E76A00"
/>
</svg> </svg>

View File

@ -8,48 +8,61 @@
{height} {height}
viewBox="0 0 128 155" viewBox="0 0 128 155"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M10.312 26.843L0 32V122.51L10.312 127.637L10.374 127.562V26.914L10.312 d="M10.312 26.843L0 32V122.51L10.312 127.637L10.374 127.562V26.914L10.312
26.843Z" 26.843Z"
fill="#8C3123" /> fill="#8C3123"
/>
<path <path
d="M65.5 114.5L10.312 127.637V26.843L65.5 39.6935V114.5Z" d="M65.5 114.5L10.312 127.637V26.843L65.5 39.6935V114.5Z"
fill="#E05243" /> fill="#E05243"
/>
<path <path
d="M40.589 93.933L63.998 96.913L64.145 96.574L64.2765 58.189L63.998 d="M40.589 93.933L63.998 96.913L64.145 96.574L64.2765 58.189L63.998
57.889L40.589 60.826V93.933" 57.889L40.589 60.826V93.933"
fill="#8C3123" /> fill="#8C3123"
/>
<path <path
d="M63.998 114.647L117.683 127.665L117.768 127.53L117.766 26.933L117.681 d="M63.998 114.647L117.683 127.665L117.768 127.53L117.766 26.933L117.681
26.843L63.998 39.841V114.647" 26.843L63.998 39.841V114.647"
fill="#8C3123" /> fill="#8C3123"
/>
<path <path
d="M87.4135 93.933L63.998 96.913V57.889L87.4135 60.826V93.933Z" d="M87.4135 93.933L63.998 96.913V57.889L87.4135 60.826V93.933Z"
fill="#E05243" /> fill="#E05243"
/>
<path <path
d="M87.4135 44.8155L63.998 49.083L40.589 44.8155L63.9685 38.6875L87.4135 d="M87.4135 44.8155L63.998 49.083L40.589 44.8155L63.9685 38.6875L87.4135
44.8155Z" 44.8155Z"
fill="#5E1F18" /> fill="#5E1F18"
/>
<path <path
d="M87.4135 109.901L63.998 105.605L40.589 109.901L63.9695 116.427L87.4135 d="M87.4135 109.901L63.998 105.605L40.589 109.901L63.9695 116.427L87.4135
109.901Z" 109.901Z"
fill="#F2B0A9" /> fill="#F2B0A9"
/>
<path <path
d="M40.589 44.8155L63.998 39.0225L64.1875 38.964V0.1565L63.998 0L40.589 d="M40.589 44.8155L63.998 39.0225L64.1875 38.964V0.1565L63.998 0L40.589
11.7065V44.8155Z" 11.7065V44.8155Z"
fill="#8C3123" /> fill="#8C3123"
/>
<path <path
d="M87.4135 44.8155L63.998 39.0225V0L87.4135 11.7065V44.8155Z" d="M87.4135 44.8155L63.998 39.0225V0L87.4135 11.7065V44.8155Z"
fill="#E05243" /> fill="#E05243"
/>
<path <path
d="M63.998 154.714L40.5865 143.012V109.903L63.998 115.694L64.3425 d="M63.998 154.714L40.5865 143.012V109.903L63.998 115.694L64.3425
116.086L64.249 154.039L63.998 154.714Z" 116.086L64.249 154.039L63.998 154.714Z"
fill="#8C3123" /> fill="#8C3123"
/>
<path <path
d="M63.998 154.714L87.4115 143.012V109.903L63.998 115.694V154.714" d="M63.998 154.714L87.4115 143.012V109.903L63.998 115.694V154.714"
fill="#E05243" /> fill="#E05243"
/>
<path <path
d="M117.684 26.843L128 32V122.51L117.684 127.665V26.843Z" d="M117.684 26.843L128 32V122.51L117.684 127.665V26.843Z"
fill="#E05243" /> fill="#E05243"
/>
</svg> </svg>

View File

@ -7,7 +7,8 @@
{width} {width}
{height} {height}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1478.201 1195.111"> viewBox="0 0 1478.201 1195.111"
>
<g transform="matrix(.569 0 0 .569 199.451 -82.735)"> <g transform="matrix(.569 0 0 .569 199.451 -82.735)">
<linearGradient <linearGradient
id="a" id="a"
@ -16,7 +17,8 @@
y1="923.573" y1="923.573"
x2="-2061.249" x2="-2061.249"
y2="1420.331" y2="1420.331"
gradientTransform="matrix(.1234 0 0 -.1234 1158.33 1550.273)"> gradientTransform="matrix(.1234 0 0 -.1234 1158.33 1550.273)"
>
<stop offset="0" stop-color="#909ca9" /> <stop offset="0" stop-color="#909ca9" />
<stop offset="1" stop-color="#ededee" /> <stop offset="1" stop-color="#ededee" />
</linearGradient> </linearGradient>
@ -107,7 +109,8 @@
99.755-47.06 130.547-2.815 6.939-3.896 8.677-5.417 99.755-47.06 130.547-2.815 6.939-3.896 8.677-5.417
8.456-3.687-.213-54.646-7.37-85.66-11.925-53.994-8.24-144.641-24.073-167.409-29.275l-5.204-1.083 8.456-3.687-.213-54.646-7.37-85.66-11.925-53.994-8.24-144.641-24.073-167.409-29.275l-5.204-1.083
32.307-7.378c69.396-15.613 102.791-24.069 136.619-34.478 42.722-13.011 32.307-7.378c69.396-15.613 102.791-24.069 136.619-34.478 42.722-13.011
85.011-29.276 127.729-49.225 6.722-3.037 12.361-5.422 13.879-5.639z" /> 85.011-29.276 127.729-49.225 6.722-3.037 12.361-5.422 13.879-5.639z"
/>
<linearGradient <linearGradient
id="b" id="b"
gradientUnits="userSpaceOnUse" gradientUnits="userSpaceOnUse"
@ -115,7 +118,8 @@
y1="10288.81" y1="10288.81"
x2="-2206.249" x2="-2206.249"
y2="10288.81" y2="10288.81"
gradientTransform="matrix(.1234 0 0 -.1234 1158.33 1550.273)"> gradientTransform="matrix(.1234 0 0 -.1234 1158.33 1550.273)"
>
<stop offset="0" stop-color="#939fab" /> <stop offset="0" stop-color="#939fab" />
<stop offset="1" stop-color="#dcdee1" /> <stop offset="1" stop-color="#dcdee1" />
</linearGradient> </linearGradient>
@ -142,14 +146,16 @@
4.552 7.806 7.373 16.263 30.364 60.07 35.997 68.526 1.74 2.822 4.771 4.552 7.806 7.373 16.263 30.364 60.07 35.997 68.526 1.74 2.822 4.771
3.038-25.802-1.95-73.512-11.93-97.152-15.829-97.152-16.263 0-.216 3.038-25.802-1.95-73.512-11.93-97.152-15.829-97.152-16.263 0-.216
2.169-1.735 4.988-3.254 22.771-12.575 45.756-28.624 66.142-45.756 2.169-1.735 4.988-3.254 22.771-12.575 45.756-28.624 66.142-45.756
4.988-4.121 9.542-8.024 10.407-8.676.216-.433.652-.649.868-.433z" /> 4.988-4.121 9.542-8.024 10.407-8.676.216-.433.652-.649.868-.433z"
/>
<radialGradient <radialGradient
id="c" id="c"
cx="-14217.448" cx="-14217.448"
cy="7277.705" cy="7277.705"
r="898.12" r="898.12"
gradientTransform="matrix(-.1185 -.0178 -.036 .237 -198.955 -1314.415)" gradientTransform="matrix(-.1185 -.0178 -.036 .237 -198.955 -1314.415)"
gradientUnits="userSpaceOnUse"> gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#ee352c" /> <stop offset="0" stop-color="#ee352c" />
<stop offset="1" stop-color="#a91d22" /> <stop offset="1" stop-color="#a91d22" />
</radialGradient> </radialGradient>
@ -241,7 +247,8 @@
45.971-41.853 42.723-83.273 76.12-134.669 108.649-6.505 4.119-12.359 45.971-41.853 42.723-83.273 76.12-134.669 108.649-6.505 4.119-12.359
7.804-13.011 8.24-1.519.867.432-1.303 22.986-25.808 14.314-15.397 7.804-13.011 8.24-1.519.867.432-1.303 22.986-25.808 14.314-15.397
25.155-28.408 37.516-44.453 8.24-10.624 9.759-12.143 21.688-20.604 25.155-28.408 37.516-44.453 8.24-10.624 9.759-12.143 21.688-20.604
31.878-22.987 105.39-72.864 106.258-71.995z" /> 31.878-22.987 105.39-72.864 106.258-71.995z"
/>
</g> </g>
<path <path
fill="#231F1F" fill="#231F1F"
@ -387,5 +394,6 @@
18.172h1.301l8.152-18.347c.219-.563.393-1.301.76-2.275-.174 1.887-.174 18.172h1.301l8.152-18.347c.219-.563.393-1.301.76-2.275-.174 1.887-.174
3.401-.174 4.553v16.048h2.82V792.52h-3.406l-7.371 16.438c-.174.587-.762 3.401-.174 4.553v16.048h2.82V792.52h-3.406l-7.371 16.438c-.174.587-.762
1.734-1.129 1.734-1.129
3.037h-.217c-.152-.761-.541-1.519-1.084-2.818l-7.373-16.655h-3.816v23.854h2.666v-15.917l.152-.023z" /> 3.037h-.217c-.152-.761-.541-1.519-1.084-2.818l-7.373-16.655h-3.816v23.854h2.666v-15.917l.152-.023z"
/>
</svg> </svg>

View File

@ -14,7 +14,9 @@
function checkValid(evt) { function checkValid(evt) {
const datasourceName = evt.target.value const datasourceName = evt.target.value
if ( if (
$datasources?.list.some(datasource => datasource.name === datasourceName) $datasources?.list.some(
(datasource) => datasource.name === datasourceName
)
) { ) {
error = `Datasource with name ${datasourceName} already exists. Please choose another name.` error = `Datasource with name ${datasourceName} already exists. Please choose another name.`
return return
@ -44,13 +46,15 @@
size="large" size="large"
confirmText="Create" confirmText="Create"
onConfirm={saveDatasource} onConfirm={saveDatasource}
disabled={error || !name}> disabled={error || !name}
>
<Input <Input
data-cy="datasource-name-input" data-cy="datasource-name-input"
label="Datasource Name" label="Datasource Name"
on:input={checkValid} on:input={checkValid}
bind:value={name} bind:value={name}
{error} /> {error}
/>
<Label>Datasource Type</Label> <Label>Datasource Type</Label>
<TableIntegrationMenu bind:integration /> <TableIntegrationMenu bind:integration />
</ModalContent> </ModalContent>

View File

@ -11,7 +11,8 @@
class:indented class:indented
class:selected class:selected
on:click on:click
class={className}> class={className}
>
<i class={icon} /> <i class={icon} />
<span>{title}</span> <span>{title}</span>
<slot /> <slot />

View File

@ -18,7 +18,7 @@
let schema = {} let schema = {}
let fields = [] let fields = []
$: valid = !schema || fields.every(column => schema[column].success) $: valid = !schema || fields.every((column) => schema[column].success)
$: dataImport = { $: dataImport = {
valid, valid,
schema: buildTableSchema(schema), schema: buildTableSchema(schema),
@ -51,7 +51,7 @@
const parseResult = await response.json() const parseResult = await response.json()
schema = parseResult && parseResult.schema schema = parseResult && parseResult.schema
fields = Object.keys(schema || {}).filter( fields = Object.keys(schema || {}).filter(
key => schema[key].type !== "omit" (key) => schema[key].type !== "omit"
) )
// Check primary display is valid // Check primary display is valid
@ -67,17 +67,18 @@
async function handleFile(evt) { async function handleFile(evt) {
const fileArray = Array.from(evt.target.files) const fileArray = Array.from(evt.target.files)
if (fileArray.some(file => file.size >= FILE_SIZE_LIMIT)) { if (fileArray.some((file) => file.size >= FILE_SIZE_LIMIT)) {
notifications.error( notifications.error(
`Files cannot exceed ${FILE_SIZE_LIMIT / `Files cannot exceed ${
BYTES_IN_MB}MB. Please try again with smaller files.` FILE_SIZE_LIMIT / BYTES_IN_MB
}MB. Please try again with smaller files.`
) )
return return
} }
// Read CSV as plain text to upload alongside schema // Read CSV as plain text to upload alongside schema
let reader = new FileReader() let reader = new FileReader()
reader.addEventListener("load", function(e) { reader.addEventListener("load", function (e) {
csvString = e.target.result csvString = e.target.result
files = fileArray files = fileArray
validateCSV() validateCSV()
@ -90,7 +91,7 @@
await validateCSV() await validateCSV()
} }
const handleTypeChange = column => evt => { const handleTypeChange = (column) => (evt) => {
schema[column].type = evt.detail schema[column].type = evt.detail
validateCSV() validateCSV()
} }
@ -127,14 +128,16 @@
on:change={handleTypeChange(columnName)} on:change={handleTypeChange(columnName)}
options={typeOptions} options={typeOptions}
placeholder={null} placeholder={null}
getOptionLabel={option => option.label} getOptionLabel={(option) => option.label}
getOptionValue={option => option.value} /> getOptionValue={(option) => option.value}
/>
<span class="field-status" class:error={!schema[columnName].success}> <span class="field-status" class:error={!schema[columnName].success}>
{schema[columnName].success ? 'Success' : 'Failure'} {schema[columnName].success ? "Success" : "Failure"}
</span> </span>
<i <i
class="omit-button ri-close-circle-fill" class="omit-button ri-close-circle-fill"
on:click={() => omitColumn(columnName)} /> on:click={() => omitColumn(columnName)}
/>
</div> </div>
{/each} {/each}
</div> </div>
@ -145,7 +148,8 @@
<Select <Select
label="Display Column" label="Display Column"
bind:value={primaryDisplay} bind:value={primaryDisplay}
options={fields} /> options={fields}
/>
</div> </div>
{/if} {/if}

Some files were not shown because too many files have changed in this diff Show More