From 10fe99346fe491a897fd5dc3c7a366d67d7fdd46 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 11:50:56 +0100 Subject: [PATCH 01/61] Improve modal layout, improve modal button spacing, use rollup for building to expose multple BBUI entrypoints --- packages/bbui/package.json | 29 +- packages/bbui/rollup.config.js | 154 +- packages/bbui/src/Button/Button.svelte | 18 +- packages/bbui/src/Form/Field.svelte | 40 + packages/bbui/src/Form/FieldLabel.svelte | 26 + packages/bbui/src/Form/Input.svelte | 201 +- packages/bbui/src/Form/Multiselect.svelte | 341 +- packages/bbui/src/Form/Select.svelte | 116 +- .../bbui/src/Form/internal/Multiselect.svelte | 61 + packages/bbui/src/Form/internal/Picker.svelte | 109 + packages/bbui/src/Form/internal/Select.svelte | 42 + .../bbui/src/Form/internal/TextField.svelte | 60 + packages/bbui/src/Form/internal/index.js | 2 + packages/bbui/src/Modal/Modal.svelte | 54 +- packages/bbui/src/Modal/ModalContent.svelte | 77 +- packages/bbui/src/Table/Table.svelte | 10 +- packages/bbui/vite.config.js | 22 - packages/bbui/yarn.lock | 4284 +---------------- 18 files changed, 646 insertions(+), 5000 deletions(-) create mode 100644 packages/bbui/src/Form/Field.svelte create mode 100644 packages/bbui/src/Form/FieldLabel.svelte create mode 100644 packages/bbui/src/Form/internal/Multiselect.svelte create mode 100644 packages/bbui/src/Form/internal/Picker.svelte create mode 100644 packages/bbui/src/Form/internal/Select.svelte create mode 100644 packages/bbui/src/Form/internal/TextField.svelte create mode 100644 packages/bbui/src/Form/internal/index.js delete mode 100644 packages/bbui/vite.config.js diff --git a/packages/bbui/package.json b/packages/bbui/package.json index da42b72fcd..bd553a1ce6 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -2,38 +2,35 @@ "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", "version": "1.58.13", + "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", "exports": { ".": { "import": "./dist/bbui.es.js" }, + "./internal": { + "import": "./dist/internal.es.js" + }, "./package.json": "./package.json", "./dist/style.css": "./dist/style.css" }, "scripts": { - "dev:builder": "vite build", - "build": "vite build" + "dev:builder": "rollup -cw", + "build": "rollup -c" }, "devDependencies": { "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^11.0.0", - "@sveltejs/vite-plugin-svelte": "^1.0.0-next.5", + "@rollup/plugin-node-resolve": "^11.2.1", "cross-env": "^7.0.2", "nollup": "^0.14.1", "postcss": "^8.2.9", - "rollup": "^2.34.0", - "rollup-plugin-copy": "^3.3.0", - "rollup-plugin-delete": "^1.2.0", - "rollup-plugin-hot": "^0.1.1", - "rollup-plugin-node-builtins": "^2.1.2", + "rollup": "^2.45.2", "rollup-plugin-postcss": "^4.0.0", - "rollup-plugin-svelte-hot": "^0.11.0", - "semantic-release": "^17.0.8", - "svelte": "^3.37.0", - "svench": "^0.0.10-7", - "vite": "^2.1.5" + "rollup-plugin-svelte": "^7.1.0", + "rollup-plugin-terser": "^7.0.2", + "svelte": "^3.37.0" }, "keywords": [ "svelte" @@ -50,20 +47,22 @@ "@spectrum-css/checkbox": "^3.0.1", "@spectrum-css/dialog": "^3.0.1", "@spectrum-css/divider": "^1.0.1", + "@spectrum-css/fieldlabel": "^3.0.1", "@spectrum-css/icon": "^3.0.1", "@spectrum-css/label": "^2.0.9", "@spectrum-css/link": "^3.1.1", "@spectrum-css/menu": "^3.0.1", "@spectrum-css/modal": "^3.0.1", + "@spectrum-css/picker": "^1.0.1", "@spectrum-css/popover": "^3.0.1", "@spectrum-css/table": "^3.0.1", + "@spectrum-css/textfield": "^3.0.1", "@spectrum-css/toast": "^3.0.1", "@spectrum-css/underlay": "^2.0.9", "@spectrum-css/vars": "^3.0.1", "dayjs": "^1.10.4", "markdown-it": "^12.0.4", "quill": "^1.3.7", - "sirv-cli": "^0.4.6", "svelte-flatpickr": "^2.4.0", "svelte-portal": "^1.0.0", "turndown": "^7.0.0" diff --git a/packages/bbui/rollup.config.js b/packages/bbui/rollup.config.js index 92b316cbe1..617df856b4 100644 --- a/packages/bbui/rollup.config.js +++ b/packages/bbui/rollup.config.js @@ -1,140 +1,30 @@ -import * as path from "path" -import svelte from "rollup-plugin-svelte-hot" +import svelte from "rollup-plugin-svelte" import resolve from "@rollup/plugin-node-resolve" import commonjs from "@rollup/plugin-commonjs" import json from "@rollup/plugin-json" -import copy from "rollup-plugin-copy" -import hmr from "rollup-plugin-hot" -import del from "rollup-plugin-delete" +import { terser } from "rollup-plugin-terser" import postcss from "rollup-plugin-postcss" -import { plugin as Svench } from "svench/rollup" -import builtins from "rollup-plugin-node-builtins" -const WATCH = !!process.env.ROLLUP_WATCH -const SVENCH = !!process.env.SVENCH -const HOT = WATCH -const PRODUCTION = !WATCH - -const svench = Svench({ - // The root dir that Svench will parse and watch. - // - // NOTE Watching the root of the project, to let Svench render *.md for us. - // - // NOTE By default, `node_modules` and `.git` dirs are ignored. This can be - // customized by passing a function to `ignore` option. Default ignore is: - // - // ignore: path => /(?:^|\/)(?:node_modules|\.git)\//.test(path), - // - dir: ".", - - // Make `src` dir a section (that is, it will always be "expanded" in the - // menu). - autoSections: ["src"], - - // Use custom index.html - index: { - source: "public/index.html", - }, - - extensions: [".svench", ".svench.svelte", ".svench.svx", ".md"], - - serve: WATCH && { - host: "0.0.0.0", - port: 4242, - public: "public", - nollup: "0.0.0.0:42421", +const makeConfig = ({ input, name }) => ({ + input, + output: { + sourcemap: true, + format: "esm", + file: `dist/${name}.es.js`, }, + plugins: [ + resolve(), + commonjs(), + svelte({ + emitCss: true, + }), + postcss(), + terser(), + json(), + ], }) -// NOTE configs are in function form to avoid instantiating plugins of the -// config that is not used for nothing (in particular, the HMR plugin launches -// a dev server on startup, this is not desired when just building for prod) -const configs = { - svench: () => ({ - input: ".svench/svench.js", - output: { - format: "es", - dir: "public/svench", - }, - plugins: [ - builtins(), - - // NOTE cleaning old builds is required to avoid serving stale static - // files from a previous build instead of in-memory files from the dev/hmr - // server - del({ - targets: "public/svench/*", - runOnce: true, - }), - - postcss({ - hot: HOT, - extract: path.resolve("public/svench/theme.css"), - sourceMap: true, - }), - - svench, - - svelte({ - dev: !PRODUCTION, - extensions: [".svelte", ".svench", ".svx", ".md"], - // Svench's "combined" preprocessor wraps both Mdsvex preprocessors - // (configured for Svench), and its own preprocessor (for static - // analysis -- eg extract source from views) - preprocess: svench.$.preprocess, - hot: HOT && { - optimistic: true, - noPreserveState: false, - }, - }), - - resolve({ browser: true }), - - commonjs(), - json(), - - HOT && - hmr({ - host: "0.0.0.0", - public: "public", - inMemory: true, - compatModuleHot: !HOT, // for terser - }), - ], - - watch: { - clearScreen: false, - // buildDelay is needed to ensure Svench's code (routes) generator will - // pick file changes before Rollup and prevent a double build (if Rollup - // first sees a change to src/Foo.svench, then to Svench's routes.js) - buildDelay: 100, - }, - }), - - lib: () => ({ - input: "src/index.js", - output: [{ file: "dist/bundle.mjs", format: "es" }], - plugins: [ - svelte({ - dev: !PRODUCTION, - extensions: [".svelte"], - emitCss: true, - }), - postcss(), - copy({ - targets: [ - { - src: ".svench/svench.css", - dest: "public", - rename: "global.css", - }, - ], - }), - resolve(), - commonjs(), - json(), - ], - }), -} - -export default configs[SVENCH ? "svench" : "lib"]() +export default [ + makeConfig({ input: "src/index.js", name: "bbui" }), + makeConfig({ input: "src/Form/internal/index.js", name: "internal" }), +] diff --git a/packages/bbui/src/Button/Button.svelte b/packages/bbui/src/Button/Button.svelte index b646f00c73..1148387a94 100644 --- a/packages/bbui/src/Button/Button.svelte +++ b/packages/bbui/src/Button/Button.svelte @@ -4,16 +4,15 @@ export let disabled = false /** @type {('S', 'M', 'L', 'XL')} Size of button */ - export let size = "M"; + export let size = "M" // Types - export let cta, primary, secondary, warning, overBackground; + export let cta, primary, secondary, warning, overBackground export let quiet = false - - export let icon = undefined; - + export let icon = undefined + diff --git a/packages/bbui/src/Form/Field.svelte b/packages/bbui/src/Form/Field.svelte new file mode 100644 index 0000000000..24131a9707 --- /dev/null +++ b/packages/bbui/src/Form/Field.svelte @@ -0,0 +1,40 @@ + + +
+ +
+ + {#if error} +
{error}
+ {/if} +
+
+ + diff --git a/packages/bbui/src/Form/FieldLabel.svelte b/packages/bbui/src/Form/FieldLabel.svelte new file mode 100644 index 0000000000..c4219f5581 --- /dev/null +++ b/packages/bbui/src/Form/FieldLabel.svelte @@ -0,0 +1,26 @@ + + + + + diff --git a/packages/bbui/src/Form/Input.svelte b/packages/bbui/src/Form/Input.svelte index e8afcffd36..db3774ce0a 100644 --- a/packages/bbui/src/Form/Input.svelte +++ b/packages/bbui/src/Form/Input.svelte @@ -1,190 +1,29 @@ -
- {#if label || edit} -
- {#if label} - - {/if} - {#if edit} -
- - -
- {/if} -
- {/if} - + - {#if error} -
{error}
- {/if} -
- - + on:change={onChange} /> + diff --git a/packages/bbui/src/Form/Multiselect.svelte b/packages/bbui/src/Form/Multiselect.svelte index 924fd4b2b5..f6c4c1f188 100644 --- a/packages/bbui/src/Form/Multiselect.svelte +++ b/packages/bbui/src/Form/Multiselect.svelte @@ -1,324 +1,33 @@ -{#if label} - -{/if} -
-
-
- {#each selectedOptions as option} -
- {option.name} -
remove(option.value)}> - - - -
-
- {/each} - {#if !value || !value.length} - {#if placeholder && placeholder.length} -
{placeholder}
- {:else} -
 
- {/if} - {/if} -
-
- - - - {#if optionsVisible} - -
    showOptions(false)} - transition:fly={{ duration: 200, y: 5 }} - on:mousedown|preventDefault={handleOptionMousedown}> - {#each options as option} -
  • - {option.name} -
  • - {/each} - {#if !options.length} -
  • No results
  • - {/if} -
-
- {/if} -
- - + + + diff --git a/packages/bbui/src/Form/Select.svelte b/packages/bbui/src/Form/Select.svelte index c245abd245..b0c1b9dc4d 100644 --- a/packages/bbui/src/Form/Select.svelte +++ b/packages/bbui/src/Form/Select.svelte @@ -1,95 +1,33 @@ -
- {#if label} - - {/if} -
- -
- -
-
-
- - + + + + + diff --git a/packages/bbui/src/Form/internal/index.js b/packages/bbui/src/Form/internal/index.js new file mode 100644 index 0000000000..ccbfb1d8bb --- /dev/null +++ b/packages/bbui/src/Form/internal/index.js @@ -0,0 +1,2 @@ +export { default as TextField } from "./TextField.svelte" +export { default as Select } from "./Select.svelte" diff --git a/packages/bbui/src/Modal/Modal.svelte b/packages/bbui/src/Modal/Modal.svelte index fe843fc1c3..94bd2b13f4 100644 --- a/packages/bbui/src/Modal/Modal.svelte +++ b/packages/bbui/src/Modal/Modal.svelte @@ -38,12 +38,56 @@ {#if visible} -
-
-
- +
+
-{/if} \ No newline at end of file +{/if} + + diff --git a/packages/bbui/src/Modal/ModalContent.svelte b/packages/bbui/src/Modal/ModalContent.svelte index c07bc57b43..f63b2450cf 100644 --- a/packages/bbui/src/Modal/ModalContent.svelte +++ b/packages/bbui/src/Modal/ModalContent.svelte @@ -29,36 +29,37 @@ } - + fieldApi.setValue(e.detail)} + disabled={$fieldState.disabled} + error={$fieldState.error} + id={$fieldState.fieldId} + {placeholder} + {type} /> {/if} - - diff --git a/packages/standard-components/src/index.js b/packages/standard-components/src/index.js index edc54a1114..c7c536f2ca 100644 --- a/packages/standard-components/src/index.js +++ b/packages/standard-components/src/index.js @@ -1,4 +1,3 @@ -import "@budibase/bbui/dist/style.css" import "@spectrum-css/vars/dist/spectrum-global.css" import "@spectrum-css/vars/dist/spectrum-medium.css" import "@spectrum-css/vars/dist/spectrum-large.css" From 9a7cf3079a496323c05a33196205e20d7ad86767 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 12:09:06 +0100 Subject: [PATCH 03/61] Fix modal transform causing inner overlays to incorrectly calculate window dimensions --- packages/bbui/src/Modal/Modal.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bbui/src/Modal/Modal.svelte b/packages/bbui/src/Modal/Modal.svelte index 94bd2b13f4..74a20f3513 100644 --- a/packages/bbui/src/Modal/Modal.svelte +++ b/packages/bbui/src/Modal/Modal.svelte @@ -89,5 +89,6 @@ overflow: visible; max-height: none; margin: 40px 0; + transform: none; } From c6cc5f95c645fb13b4df6e946fbc8f30c75efec0 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 12:09:36 +0100 Subject: [PATCH 04/61] Remove dependency on BBUI stylesheet in builder --- packages/builder/src/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/main.js b/packages/builder/src/main.js index 6d448c697f..a8483cfda9 100644 --- a/packages/builder/src/main.js +++ b/packages/builder/src/main.js @@ -6,7 +6,6 @@ import "@spectrum-css/vars/dist/spectrum-dark.css" import "@spectrum-css/vars/dist/spectrum-light.css" import "@spectrum-css/vars/dist/spectrum-lightest.css" import "@spectrum-css/page/dist/index-vars.css" -import "@budibase/bbui/dist/style.css" import "./global.css" import "./fonts.css" import "./budibase.css" From dd7bf3fd680c010e73a7403b9cbc5a4cc0218080 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 12:14:51 +0100 Subject: [PATCH 05/61] Fix multiselect --- packages/bbui/src/Form/Multiselect.svelte | 2 +- .../bbui/src/Form/internal/Multiselect.svelte | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/bbui/src/Form/Multiselect.svelte b/packages/bbui/src/Form/Multiselect.svelte index f6c4c1f188..19a99ba816 100644 --- a/packages/bbui/src/Form/Multiselect.svelte +++ b/packages/bbui/src/Form/Multiselect.svelte @@ -4,7 +4,7 @@ import Field from "./Field.svelte" export let value = null - export let label = undefined + export let label = [] export let disabled = false export let labelPosition = "above" export let error = null diff --git a/packages/bbui/src/Form/internal/Multiselect.svelte b/packages/bbui/src/Form/internal/Multiselect.svelte index e1df4ae575..23475a1417 100644 --- a/packages/bbui/src/Form/internal/Multiselect.svelte +++ b/packages/bbui/src/Form/internal/Multiselect.svelte @@ -14,7 +14,9 @@ const dispatch = createEventDispatcher() $: fieldText = getFieldText(value) $: valueLookupMap = getValueLookupMap(value) - $: isOptionSelected = option => valueLookupMap[option] === true + $: isOptionSelected = option => { + return valueLookupMap[option] === true + } const getFieldText = value => { if (value?.length) { @@ -29,21 +31,20 @@ let map = {} if (value?.length) { value.forEach(option => { - const optionValue = getOptionValue(option) - if (optionValue) { - map[optionValue] = true + if (option) { + map[option] = true } }) } return map } - const toggleOption = option => { - if (valueLookupMap[option]) { - const filtered = value.filter(option => option !== id) + const toggleOption = optionValue => { + if (valueLookupMap[optionValue]) { + const filtered = value.filter(option => option !== optionValue) dispatch("change", filtered) } else { - dispatch("change", [...value, option]) + dispatch("change", [...value, optionValue]) } } From d779fbbea4e0f9459402becb24ec0a8531449b6e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 14:05:59 +0100 Subject: [PATCH 06/61] Add pretty labels to multiselect and fix stale props issue --- .../bbui/src/Form/internal/Multiselect.svelte | 45 ++++++++++++------- packages/bbui/src/Form/internal/Picker.svelte | 6 +++ packages/bbui/src/Form/internal/index.js | 1 + 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/packages/bbui/src/Form/internal/Multiselect.svelte b/packages/bbui/src/Form/internal/Multiselect.svelte index 23475a1417..96733ec454 100644 --- a/packages/bbui/src/Form/internal/Multiselect.svelte +++ b/packages/bbui/src/Form/internal/Multiselect.svelte @@ -12,22 +12,22 @@ export let getOptionValue = option => option const dispatch = createEventDispatcher() - $: fieldText = getFieldText(value) - $: valueLookupMap = getValueLookupMap(value) - $: isOptionSelected = option => { - return valueLookupMap[option] === true - } + $: selectedLookupMap = getSelectedLookupMap(value) + $: optionLookupMap = getOptionLookupMap(options) + $: fieldText = getFieldText(value, optionLookupMap, placeholder) + $: isOptionSelected = optionValue => selectedLookupMap[optionValue] === true + $: toggleOption = makeToggleOption(selectedLookupMap, value) - const getFieldText = value => { + const getFieldText = (value, map, placeholder) => { if (value?.length) { - const count = value?.length ?? 0 - return `${count} selected option${count === 1 ? "" : "s"}` + const vals = value.map(option => map[option] || "").join(", ") + return `(${value.length}) ${vals}` } else { return placeholder || "Choose some options" } } - const getValueLookupMap = value => { + const getSelectedLookupMap = value => { let map = {} if (value?.length) { value.forEach(option => { @@ -39,12 +39,27 @@ return map } - const toggleOption = optionValue => { - if (valueLookupMap[optionValue]) { - const filtered = value.filter(option => option !== optionValue) - dispatch("change", filtered) - } else { - dispatch("change", [...value, optionValue]) + const getOptionLookupMap = options => { + let map = {} + if (options) { + options.forEach(option => { + const optionValue = getOptionValue(option) + if (optionValue != null) { + map[optionValue] = getOptionLabel(option) || "" + } + }) + } + return map + } + + const makeToggleOption = (map, value) => { + return optionValue => { + if (map[optionValue]) { + const filtered = value.filter(option => option !== optionValue) + dispatch("change", filtered) + } else { + dispatch("change", [...value, optionValue]) + } } } diff --git a/packages/bbui/src/Form/internal/Picker.svelte b/packages/bbui/src/Form/internal/Picker.svelte index e09a5f66c7..b78ff6fb02 100644 --- a/packages/bbui/src/Form/internal/Picker.svelte +++ b/packages/bbui/src/Form/internal/Picker.svelte @@ -106,4 +106,10 @@ .spectrum-Picker { width: 100%; } + .spectrum-Picker-label { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 0; + } diff --git a/packages/bbui/src/Form/internal/index.js b/packages/bbui/src/Form/internal/index.js index ccbfb1d8bb..3b8d6609ff 100644 --- a/packages/bbui/src/Form/internal/index.js +++ b/packages/bbui/src/Form/internal/index.js @@ -1,2 +1,3 @@ export { default as TextField } from "./TextField.svelte" export { default as Select } from "./Select.svelte" +export { default as Multiselect } from "./Multiselect.svelte" From 591d1c0fc5a6c95b71df95e4bc993024309af086 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 19:28:08 +0100 Subject: [PATCH 07/61] Change BBUI to single bundle export and clean up some form components --- packages/bbui/package.json | 4 --- packages/bbui/rollup.config.js | 13 +++----- .../{internal => Core}/Multiselect.svelte | 0 .../src/Form/{internal => Core}/Picker.svelte | 0 .../src/Form/{internal => Core}/Select.svelte | 0 .../Form/{internal => Core}/TextField.svelte | 0 packages/bbui/src/Form/Core/index.js | 3 ++ packages/bbui/src/Form/Input.svelte | 2 +- packages/bbui/src/Form/Multiselect.svelte | 2 +- packages/bbui/src/Form/Select.svelte | 2 +- packages/bbui/src/Form/internal/index.js | 3 -- packages/bbui/src/index.js | 3 ++ .../src/components/start/Steps/API.svelte | 33 ------------------- 13 files changed, 13 insertions(+), 52 deletions(-) rename packages/bbui/src/Form/{internal => Core}/Multiselect.svelte (100%) rename packages/bbui/src/Form/{internal => Core}/Picker.svelte (100%) rename packages/bbui/src/Form/{internal => Core}/Select.svelte (100%) rename packages/bbui/src/Form/{internal => Core}/TextField.svelte (100%) create mode 100644 packages/bbui/src/Form/Core/index.js delete mode 100644 packages/bbui/src/Form/internal/index.js delete mode 100644 packages/builder/src/components/start/Steps/API.svelte diff --git a/packages/bbui/package.json b/packages/bbui/package.json index bd553a1ce6..fdc7df0931 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -9,14 +9,10 @@ ".": { "import": "./dist/bbui.es.js" }, - "./internal": { - "import": "./dist/internal.es.js" - }, "./package.json": "./package.json", "./dist/style.css": "./dist/style.css" }, "scripts": { - "dev:builder": "rollup -cw", "build": "rollup -c" }, "devDependencies": { diff --git a/packages/bbui/rollup.config.js b/packages/bbui/rollup.config.js index 617df856b4..e285d548d6 100644 --- a/packages/bbui/rollup.config.js +++ b/packages/bbui/rollup.config.js @@ -5,12 +5,12 @@ import json from "@rollup/plugin-json" import { terser } from "rollup-plugin-terser" import postcss from "rollup-plugin-postcss" -const makeConfig = ({ input, name }) => ({ - input, +export default { + input: "src/index.js", output: { sourcemap: true, format: "esm", - file: `dist/${name}.es.js`, + file: "dist/bbui.es.js", }, plugins: [ resolve(), @@ -22,9 +22,4 @@ const makeConfig = ({ input, name }) => ({ terser(), json(), ], -}) - -export default [ - makeConfig({ input: "src/index.js", name: "bbui" }), - makeConfig({ input: "src/Form/internal/index.js", name: "internal" }), -] +} diff --git a/packages/bbui/src/Form/internal/Multiselect.svelte b/packages/bbui/src/Form/Core/Multiselect.svelte similarity index 100% rename from packages/bbui/src/Form/internal/Multiselect.svelte rename to packages/bbui/src/Form/Core/Multiselect.svelte diff --git a/packages/bbui/src/Form/internal/Picker.svelte b/packages/bbui/src/Form/Core/Picker.svelte similarity index 100% rename from packages/bbui/src/Form/internal/Picker.svelte rename to packages/bbui/src/Form/Core/Picker.svelte diff --git a/packages/bbui/src/Form/internal/Select.svelte b/packages/bbui/src/Form/Core/Select.svelte similarity index 100% rename from packages/bbui/src/Form/internal/Select.svelte rename to packages/bbui/src/Form/Core/Select.svelte diff --git a/packages/bbui/src/Form/internal/TextField.svelte b/packages/bbui/src/Form/Core/TextField.svelte similarity index 100% rename from packages/bbui/src/Form/internal/TextField.svelte rename to packages/bbui/src/Form/Core/TextField.svelte diff --git a/packages/bbui/src/Form/Core/index.js b/packages/bbui/src/Form/Core/index.js new file mode 100644 index 0000000000..1570f4e298 --- /dev/null +++ b/packages/bbui/src/Form/Core/index.js @@ -0,0 +1,3 @@ +export { default as CoreTextField } from "./TextField.svelte" +export { default as CoreSelect } from "./Select.svelte" +export { default as CoreMultiselect } from "./Multiselect.svelte" diff --git a/packages/bbui/src/Form/Input.svelte b/packages/bbui/src/Form/Input.svelte index db3774ce0a..3e81b09755 100644 --- a/packages/bbui/src/Form/Input.svelte +++ b/packages/bbui/src/Form/Input.svelte @@ -1,6 +1,6 @@ - -

Set up your API Key

-
- (blurred.api = true)} - label="API Key" - name="apiKey" - placeholder="Use command-V to paste your API Key" - type="password" - error={blurred.api && validationErrors.apiKey} /> - Get API Key -
- - From 910ac855cf392d24d65037c11e0108ed34123a59 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 15 Apr 2021 19:28:50 +0100 Subject: [PATCH 08/61] Rewrite create app modal to work with new spectrum fields --- .../components/start/CreateAppModal.svelte | 178 ++++++------------ .../src/components/start/Steps/Info.svelte | 12 +- .../src/components/start/Steps/User.svelte | 28 +-- .../src/components/start/Steps/index.js | 1 - 4 files changed, 82 insertions(+), 137 deletions(-) diff --git a/packages/builder/src/components/start/CreateAppModal.svelte b/packages/builder/src/components/start/CreateAppModal.svelte index 999bc493c2..d5eb606037 100644 --- a/packages/builder/src/components/start/CreateAppModal.svelte +++ b/packages/builder/src/components/start/CreateAppModal.svelte @@ -4,7 +4,6 @@ import { store, automationStore, hostingStore } from "builderStore" import { string, object } from "yup" import api, { get } from "builderStore/api" - import Form from "@svelteschool/svelte-forms" import Spinner from "components/common/Spinner.svelte" import { Info, User } from "./Steps" import Indicator from "./Indicator.svelte" @@ -16,44 +15,40 @@ import { onMount } from "svelte" import Logo from "/assets/bb-logo.svg" - //Move this to context="module" once svelte-forms is updated so that it can bind to stores correctly - const createAppStore = writable({ currentStep: 0, values: {} }) - export let template - const infoValidation = { - applicationName: string().required("Your application must have a name."), - } - const userValidation = { - email: string() - .email() - .required("Your application needs a first user."), - password: string().required("Please enter a password for your first user."), - roleId: string().required("You need to select a role for your user."), - } + const currentStep = writable(0) + const values = writable({ roleId: "ADMIN" }) + const errors = writable({}) + const touched = writable({}) + const steps = [Info, User] + let validators = [ + { + applicationName: string().required("Your application must have a name."), + }, + { + email: string() + .email() + .required("Your application needs a first user."), + password: string().required( + "Please enter a password for your first user." + ), + roleId: string() + .nullable() + .required("You need to select a role for your user."), + }, + ] let submitting = false - let errors = {} - let validationErrors = {} - let validationSchemas = [infoValidation, userValidation] - - function buildStep(component) { - return { - component, - errors, - } - } - - // steps need to be initialized for cypress from the get go - let steps = [buildStep(Info), buildStep(User)] + let valid = false + $: checkValidity($values, validators[$currentStep]) onMount(async () => { - let hostingInfo = await hostingStore.actions.fetch() - // re-init the steps based on whether self hosting or cloud hosted + const hostingInfo = await hostingStore.actions.fetch() if (hostingInfo.type === "self") { await hostingStore.actions.fetchDeployedApps() const existingAppNames = svelteGet(hostingStore).deployedAppNames - infoValidation.applicationName = string() + validators[0].applicationName = string() .required("Your application must have a name.") .test( "non-existing-app-name", @@ -63,54 +58,20 @@ appName => appName.toLowerCase() === value.toLowerCase() ) ) - - steps = [buildStep(Info), buildStep(User)] - validationSchemas = [infoValidation, userValidation] } }) - // Handles form navigation - const back = () => { - if ($createAppStore.currentStep > 0) { - $createAppStore.currentStep -= 1 - } - } - const next = () => { - $createAppStore.currentStep += 1 - } - - // $: errors = validationSchemas.validate(values); - $: getErrors( - $createAppStore.values, - validationSchemas[$createAppStore.currentStep] - ) - - async function getErrors(values, schema) { + const checkValidity = async (values, validator) => { + const obj = object().shape(validator) + Object.keys(validator).forEach(key => ($errors[key] = null)) try { - validationErrors = {} - await object(schema).validate(values, { abortEarly: false }) - } catch (error) { - validationErrors = extractErrors(error) - } - } - - const checkValidity = async (values, currentStep) => { - const validity = await object() - .shape(validationSchemas[currentStep]) - .isValid(values) - currentStepIsValid = validity - - // Check full form on last step - if (currentStep === steps.length - 1) { - // Make one big schema from all the small ones - const fullSchema = Object.assign({}, ...validationSchemas) - - // Check full form schema - const formIsValid = await object() - .shape(fullSchema) - .isValid(values) - fullFormIsValid = formIsValid + await obj.validate(values, { abortEarly: false }) + } catch (validationErrors) { + validationErrors.inner.forEach(error => { + $errors[error.path] = error.message + }) } + valid = await obj.isValid(values) } async function createNewApp() { @@ -118,7 +79,7 @@ try { // Create form data to create app let data = new FormData() - data.append("name", $createAppStore.values.applicationName) + data.append("name", $values.applicationName) data.append("useTemplate", template != null) if (template) { data.append("templateName", template.name) @@ -134,7 +95,7 @@ } analytics.captureEvent("App Created", { - name: $createAppStore.values.applicationName, + name: $values.applicationName, appId: appJson._id, template, }) @@ -153,12 +114,12 @@ // Create user const user = { - email: $createAppStore.values.email, - password: $createAppStore.values.password, - roleId: $createAppStore.values.roleId, + email: $values.email, + password: $values.password, + roleId: $values.roleId, } const userResp = await api.post(`/api/users`, user) - const json = await userResp.json() + await userResp.json() $goto(`./${appJson._id}`) } catch (error) { console.error(error) @@ -166,33 +127,14 @@ submitting = false } } - - async function updateKey([key, value]) { - const response = await api.put(`/api/keys/${key}`, { value }) - const res = await response.json() - return res - } - - function extractErrors({ inner }) { - if (!inner) return {} - return inner.reduce((acc, err) => { - return { ...acc, [err.path]: err.message } - }, {}) - } - - let currentStepIsValid = false - let fullFormIsValid = false - $: checkValidity($createAppStore.values, $createAppStore.currentStep) - - let onChange = () => {}
@@ -201,34 +143,32 @@

Get Started with Budibase

-
- {#each steps as step, i (i)} -
- -
- {/each} -
+ {#each steps as component, i (i)} +
+ +
+ {/each}