adding nice loading states

This commit is contained in:
Martin McKeaveney 2020-10-05 14:07:39 +01:00
parent 140233960e
commit 3a460429a0
5 changed files with 47 additions and 13 deletions

View File

@ -1,5 +1,6 @@
<script> <script>
import { onMount } from "svelte" import { onMount } from "svelte"
import { fade } from "svelte/transition"
import fsort from "fast-sort" import fsort from "fast-sort"
import getOr from "lodash/fp/getOr" import getOr from "lodash/fp/getOr"
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
@ -8,6 +9,7 @@
import LinkedRecord from "./LinkedRecord.svelte" import LinkedRecord from "./LinkedRecord.svelte"
import AttachmentList from "./AttachmentList.svelte" import AttachmentList from "./AttachmentList.svelte"
import TablePagination from "./TablePagination.svelte" import TablePagination from "./TablePagination.svelte"
import Spinner from "components/common/Spinner.svelte"
import { DeleteRecordModal, CreateEditRecordModal } from "./modals" import { DeleteRecordModal, CreateEditRecordModal } from "./modals"
import RowPopover from "./popovers/Row.svelte" import RowPopover from "./popovers/Row.svelte"
import ColumnPopover from "./popovers/Column.svelte" import ColumnPopover from "./popovers/Column.svelte"
@ -26,14 +28,17 @@
let headers = [] let headers = []
let currentPage = 0 let currentPage = 0
let search let search
let loading
$: { $: {
if ( if (
$backendUiStore.selectedView && $backendUiStore.selectedView &&
$backendUiStore.selectedView.name.startsWith("all_") $backendUiStore.selectedView.name.startsWith("all_")
) { ) {
loading = true
api.fetchDataForView($backendUiStore.selectedView).then(records => { api.fetchDataForView($backendUiStore.selectedView).then(records => {
data = records || [] data = records || []
loading = false
}) })
} }
} }
@ -60,7 +65,14 @@
<section> <section>
<div class="table-controls"> <div class="table-controls">
<h2 class="title">{$backendUiStore.selectedModel.name}</h2> <h2 class="title">
<span>{$backendUiStore.selectedModel.name}</span>
{#if loading}
<div transition:fade>
<Spinner size="15" />
</div>
{/if}
</h2>
<div class="popovers"> <div class="popovers">
<ColumnPopover /> <ColumnPopover />
{#if Object.keys($backendUiStore.selectedModel.schema).length > 0} {#if Object.keys($backendUiStore.selectedModel.schema).length > 0}
@ -123,6 +135,12 @@
font-weight: 600; font-weight: 600;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
text-transform: capitalize; text-transform: capitalize;
display: flex;
align-items: center;
}
.title > span {
margin-right: var(--spacing-xs);
} }
table { table {

View File

@ -2,6 +2,7 @@
import { goto } from "@sveltech/routify" import { goto } from "@sveltech/routify"
import { backendUiStore } from "builderStore" import { backendUiStore } from "builderStore"
import { notifier } from "builderStore/store/notifications" import { notifier } from "builderStore/store/notifications"
import Spinner from "components/common/Spinner.svelte"
import { import {
Body, Body,
DropdownMenu, DropdownMenu,
@ -20,8 +21,10 @@
let dropdown let dropdown
let name let name
let dataImport let dataImport
let loading
async function saveTable() { async function saveTable() {
loading = true
const model = await backendUiStore.actions.models.save({ const model = await backendUiStore.actions.models.save({
name, name,
schema: dataImport.schema || {}, schema: dataImport.schema || {},
@ -32,6 +35,7 @@
name = "" name = ""
dropdown.hide() dropdown.hide()
analytics.captureEvent("Table Created", { name }) analytics.captureEvent("Table Created", { name })
loading = false
} }
const onClosed = () => { const onClosed = () => {
@ -65,7 +69,10 @@
disabled={!name || !dataImport.valid} disabled={!name || !dataImport.valid}
primary primary
on:click={saveTable}> on:click={saveTable}>
Save <span>Save</span>
{#if loading}
<Spinner size="10" />
{/if}
</Button> </Button>
</div> </div>
</footer> </footer>
@ -73,10 +80,15 @@
<style> <style>
h5 { h5 {
margin-bottom: var(--spacing-l); margin-bottom: var(--spacing-m);
margin-top: 0;
font-weight: 500; font-weight: 500;
} }
span {
margin-right: 5px;
}
.container { .container {
padding: var(--spacing-l); padding: var(--spacing-l);
margin: 0; margin: 0;

View File

@ -22,7 +22,7 @@
$: dataImport = { $: dataImport = {
valid, valid,
schema: buildModelSchema(schema), schema: buildModelSchema(schema),
path: files.length && files[0].path, path: files[0] && files[0].path,
} }
function buildModelSchema(schema) { function buildModelSchema(schema) {
@ -89,7 +89,7 @@
<div class="dropzone"> <div class="dropzone">
<input id="file-upload" accept=".csv" type="file" on:change={handleFile} /> <input id="file-upload" accept=".csv" type="file" on:change={handleFile} />
<label for="file-upload"> <label for="file-upload" class:uploaded={files[0]}>
{#if files[0]}{files[0].name}{:else}Upload{/if} {#if files[0]}{files[0].name}{:else}Upload{/if}
</label> </label>
</div> </div>
@ -129,11 +129,17 @@
} }
.field-status { .field-status {
color: green; color: var(--green);
justify-self: center;
font-weight: 500;
} }
.error { .error {
color: red; color: var(--red);
}
.uploaded {
color: var(--blue);
} }
input[type="file"] { input[type="file"] {
@ -169,6 +175,7 @@
font-size: 1.2em; font-size: 1.2em;
color: var(--grey-7); color: var(--grey-7);
cursor: pointer; cursor: pointer;
justify-self: flex-end;
} }
.field { .field {

View File

@ -1,11 +1,7 @@
const Router = require("@koa/router") const Router = require("@koa/router")
const recordController = require("../controllers/record") const recordController = require("../controllers/record")
const authorized = require("../../middleware/authorized") const authorized = require("../../middleware/authorized")
const { const { READ_MODEL, WRITE_MODEL } = require("../../utilities/accessLevels")
READ_MODEL,
WRITE_MODEL,
BUILDER,
} = require("../../utilities/accessLevels")
const router = Router() const router = Router()

View File

@ -42,7 +42,8 @@ function parse(path, parsers) {
const validator = VALIDATORS[parsers[key].type] const validator = VALIDATORS[parsers[key].type]
try { try {
schema[key].success = !!validator(row[key]) // allow null/undefined values
schema[key].success = !row[key] || !!validator(row[key])
} catch (err) { } catch (err) {
schema[key].success = false schema[key].success = false
} }