dispatch("click")}}
in:fade
class="swatch"
style={`background: ${color};`}
@@ -38,6 +41,8 @@
border: 1px solid #dedada;
height: 20px;
width: 20px;
+ outline-color: #003cb0;
+ outline-width: thin;
}
.space {
diff --git a/packages/builder/src/components/userInterface/Colorpicker/helpers.js b/packages/builder/src/components/userInterface/Colorpicker/helpers.js
index 5d9ff750af..bd4d666bc1 100644
--- a/packages/builder/src/components/userInterface/Colorpicker/helpers.js
+++ b/packages/builder/src/components/userInterface/Colorpicker/helpers.js
@@ -1,4 +1,4 @@
-export const buildStyle = styles => {
+export function buildStyle(styles) {
let str = ""
for (let s in styles) {
if (styles[s]) {
@@ -12,3 +12,9 @@ export const buildStyle = styles => {
export const convertCamel = str => {
return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)
}
+
+export const debounce = (fn, milliseconds) => {
+ return () => {
+ setTimeout(fn, milliseconds)
+ }
+}
diff --git a/packages/builder/src/components/userInterface/Colorpicker/index.js b/packages/builder/src/components/userInterface/Colorpicker/index.js
index 21e19acc9b..80a44b8a85 100644
--- a/packages/builder/src/components/userInterface/Colorpicker/index.js
+++ b/packages/builder/src/components/userInterface/Colorpicker/index.js
@@ -1,2 +1,2 @@
-import Colorpreview from "./Colorpreview.svelte"
+import Colorpreview from "./components/Colorpreview.svelte"
export default Colorpreview
diff --git a/packages/builder/src/components/userInterface/Colorpicker/utils.js b/packages/builder/src/components/userInterface/Colorpicker/utils.js
index e14c8711ab..6049046e60 100644
--- a/packages/builder/src/components/userInterface/Colorpicker/utils.js
+++ b/packages/builder/src/components/userInterface/Colorpicker/utils.js
@@ -144,13 +144,15 @@ export const hslaToHSVA = ([h, s, l, a = 1]) => {
export const hsvaToHexa = (hsva, asString = false) => {
const [r, g, b, a] = hsvaToRgba(hsva)
+ const padSingle = hex => (hex.length === 1 ? `0${hex}` : hex)
- const hexa = [r, g, b]
- .map(v => {
- let hex = Math.round(v).toString(16)
- return hex.length === 1 ? `0${hex}` : hex
- })
- .concat(Math.round(a * 255).toString(16))
+ let hexa = [r, g, b].map(v => {
+ let hex = Math.round(v).toString(16)
+ return padSingle(hex)
+ })
+
+ let alpha = padSingle(Math.round(a * 255).toString(16))
+ hexa = [...hexa, alpha]
return asString ? `#${hexa.join("")}` : hexa
}
diff --git a/packages/builder/src/components/userInterface/temporaryPanelStructure.js b/packages/builder/src/components/userInterface/temporaryPanelStructure.js
index ae39ce3ee2..99692d2827 100644
--- a/packages/builder/src/components/userInterface/temporaryPanelStructure.js
+++ b/packages/builder/src/components/userInterface/temporaryPanelStructure.js
@@ -406,7 +406,7 @@ export default {
{
name: "List",
_component: "@budibase/standard-components/list",
- description: "Shiny list",
+ description: "Renders all children once per record, of a given model",
icon: "ri-file-list-fill",
properties: {
design: { ...all },
@@ -414,6 +414,18 @@ export default {
},
children: [],
},
+ {
+ name: "Record Detail",
+ _component: "@budibase/standard-components/recorddetail",
+ description:
+ "Loads a record, using an id from the URL, which can be used with {{ context }}, in children",
+ icon: "ri-profile-line",
+ properties: {
+ design: { ...all },
+ settings: [{ label: "Model", key: "model", control: ModelSelect }],
+ },
+ children: [],
+ },
{
name: "Map",
_component: "@budibase/standard-components/datamap",
diff --git a/packages/client/src/render/screenRouter.js b/packages/client/src/render/screenRouter.js
index fb0b005096..4f4256f9fe 100644
--- a/packages/client/src/render/screenRouter.js
+++ b/packages/client/src/render/screenRouter.js
@@ -56,13 +56,13 @@ export const screenRouter = ({ screens, onScreenSelected, window }) => {
const screenIndex = current !== -1 ? current : fallback
- onScreenSelected(screens[screenIndex], _url)
-
try {
!url.state && history.pushState(_url, null, _url)
} catch (_) {
// ignoring an exception here as the builder runs an iframe, which does not like this
}
+
+ onScreenSelected(screens[screenIndex], _url)
}
function click(e) {
diff --git a/packages/server/src/api/controllers/application.js b/packages/server/src/api/controllers/application.js
index 47addee330..890e573817 100644
--- a/packages/server/src/api/controllers/application.js
+++ b/packages/server/src/api/controllers/application.js
@@ -90,6 +90,22 @@ exports.create = async function(ctx) {
ctx.message = `Application ${ctx.request.body.name} created successfully`
}
+exports.update = async function(ctx) {
+ const clientId = await lookupClientId(ctx.params.applicationId)
+ const db = new CouchDB(ClientDb.name(clientId))
+ const application = await db.get(ctx.params.applicationId)
+
+ const data = ctx.request.body
+ const newData = { ...application, ...data }
+
+ const response = await db.put(newData)
+ data._rev = response.rev
+
+ ctx.status = 200
+ ctx.message = `Application ${application.name} updated successfully.`
+ ctx.body = response
+}
+
const createEmptyAppPackage = async (ctx, app) => {
const templateFolder = resolve(
__dirname,
diff --git a/packages/server/src/api/routes/application.js b/packages/server/src/api/routes/application.js
index 60cc781ac6..2843770b46 100644
--- a/packages/server/src/api/routes/application.js
+++ b/packages/server/src/api/routes/application.js
@@ -12,6 +12,7 @@ router
authorized(BUILDER),
controller.fetchAppPackage
)
+ .put("/api/:applicationId", authorized(BUILDER), controller.update)
.post("/api/applications", authorized(BUILDER), controller.create)
module.exports = router
diff --git a/packages/server/src/utilities/builder/index.template.html b/packages/server/src/utilities/builder/index.template.html
index 33a7d104ec..58faca7da6 100644
--- a/packages/server/src/utilities/builder/index.template.html
+++ b/packages/server/src/utilities/builder/index.template.html
@@ -17,6 +17,9 @@
margin: 0px;
padding: 0px;
}
+ *, *:before, *:after {
+ box-sizing: border-box;
+ }
{{ each(options.stylesheets) }}
diff --git a/packages/standard-components/components.json b/packages/standard-components/components.json
index 8df7756499..2c24c02615 100644
--- a/packages/standard-components/components.json
+++ b/packages/standard-components/components.json
@@ -235,15 +235,14 @@
"description": "A configurable data list that attaches to your backend models.",
"data": true,
"props": {
- "model": "models",
- "layout": {
- "type": "options",
- "default": "list",
- "options": [
- "list",
- "grid"
- ]
- }
+ "model": "models"
+ }
+ },
+ "recorddetail": {
+ "description": "Loads a record, using an ID in the url",
+ "data": true,
+ "props": {
+ "model": "models"
}
},
"datamap": {
diff --git a/packages/standard-components/src/List.svelte b/packages/standard-components/src/List.svelte
index 8207ef47ee..ec086cbace 100644
--- a/packages/standard-components/src/List.svelte
+++ b/packages/standard-components/src/List.svelte
@@ -3,7 +3,6 @@
export let _bb
export let model
- export let layout = "list"
let headers = []
let store = _bb.store
@@ -33,39 +32,5 @@
})
-
-
+
-
-
diff --git a/packages/standard-components/src/RecordDetail.svelte b/packages/standard-components/src/RecordDetail.svelte
new file mode 100644
index 0000000000..1ebd89e6f0
--- /dev/null
+++ b/packages/standard-components/src/RecordDetail.svelte
@@ -0,0 +1,52 @@
+
+
+
diff --git a/packages/standard-components/src/index.js b/packages/standard-components/src/index.js
index 37d6abab74..a0c6ee025d 100644
--- a/packages/standard-components/src/index.js
+++ b/packages/standard-components/src/index.js
@@ -23,3 +23,4 @@ export { default as list } from "./List.svelte"
export { default as datasearch } from "./DataSearch.svelte"
export { default as datamap } from "./DataMap.svelte"
export { default as embed } from "./Embed.svelte"
+export { default as recorddetail } from "./RecordDetail.svelte"