forked from tsai/budibase
164 changed files with 5098 additions and 4385 deletions
@ -1,26 +0,0 @@ |
|||||
// Array.flat needs polyfilled in < Node 11
|
|
||||
if (!Array.prototype.flat) { |
|
||||
Object.defineProperty(Array.prototype, "flat", { |
|
||||
configurable: true, |
|
||||
value: function flat() { |
|
||||
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]) |
|
||||
|
|
||||
return depth |
|
||||
? Array.prototype.reduce.call( |
|
||||
this, |
|
||||
function(acc, cur) { |
|
||||
if (Array.isArray(cur)) { |
|
||||
acc.push.apply(acc, flat.call(cur, depth - 1)) |
|
||||
} else { |
|
||||
acc.push(cur) |
|
||||
} |
|
||||
|
|
||||
return acc |
|
||||
}, |
|
||||
[] |
|
||||
) |
|
||||
: Array.prototype.slice.call(this) |
|
||||
}, |
|
||||
writable: true, |
|
||||
}) |
|
||||
} |
|
||||
@ -0,0 +1,25 @@ |
|||||
|
<script> |
||||
|
import { Select } from "@budibase/bbui" |
||||
|
import { makePropSafe } from "@budibase/string-templates" |
||||
|
import { currentAsset, store } from "builderStore" |
||||
|
import { findComponentPath } from "builderStore/storeUtils" |
||||
|
|
||||
|
export let value |
||||
|
|
||||
|
$: path = findComponentPath($currentAsset.props, $store.selectedComponentId) |
||||
|
$: providers = path.filter( |
||||
|
component => |
||||
|
component._component === "@budibase/standard-components/dataprovider" |
||||
|
) |
||||
|
</script> |
||||
|
|
||||
|
<Select thin secondary {value} on:change> |
||||
|
<option value="">Choose option</option> |
||||
|
{#if providers} |
||||
|
{#each providers as component} |
||||
|
<option value={`{{ literal ${makePropSafe(component._id)} }}`}> |
||||
|
{component._instanceName} |
||||
|
</option> |
||||
|
{/each} |
||||
|
{/if} |
||||
|
</Select> |
||||
@ -1,7 +1,14 @@ |
|||||
<div class="root">This action doesn't require any additional settings.</div> |
<script> |
||||
|
import { Body } from "@budibase/bbui" |
||||
|
</script> |
||||
|
|
||||
|
<div class="root"> |
||||
|
<Body small grey>This action doesn't require any additional settings.</Body> |
||||
|
</div> |
||||
|
|
||||
<style> |
<style> |
||||
.root { |
.root { |
||||
font-size: var(--font-size-s); |
max-width: 800px; |
||||
|
margin: 0 auto; |
||||
} |
} |
||||
</style> |
</style> |
||||
|
|||||
@ -1,13 +1,13 @@ |
|||||
<script> |
<script> |
||||
import { Select } from "@budibase/bbui" |
import { Select } from "@budibase/bbui" |
||||
import { backendUiStore } from "builderStore" |
import { roles } from 'stores/backend/' |
||||
|
|
||||
export let value |
export let value |
||||
</script> |
</script> |
||||
|
|
||||
<Select bind:value extraThin secondary on:change> |
<Select bind:value extraThin secondary on:change> |
||||
<option value="">Choose an option</option> |
<option value="">Choose an option</option> |
||||
{#each $backendUiStore.roles as role} |
{#each $roles as role} |
||||
<option value={role._id}>{role.name}</option> |
<option value={role._id}>{role.name}</option> |
||||
{/each} |
{/each} |
||||
</Select> |
</Select> |
||||
|
|||||
@ -1,7 +1,7 @@ |
|||||
<script> |
<script> |
||||
import DatasourceSelect from "./DatasourceSelect.svelte" |
import DataSourceSelect from "./DataSourceSelect.svelte" |
||||
|
|
||||
const otherSources = [{ name: "Custom", label: "Custom" }] |
const otherSources = [{ name: "Custom", label: "Custom" }] |
||||
</script> |
</script> |
||||
|
|
||||
<DatasourceSelect on:change {...$$props} showAllQueries={true} {otherSources} /> |
<DataSourceSelect on:change {...$$props} showAllQueries={true} {otherSources} /> |
||||
|
|||||
@ -1,23 +1,22 @@ |
|||||
<script> |
<script> |
||||
import { backendUiStore } from "builderStore" |
import { datasources, tables } from 'stores/backend/' |
||||
import { goto } from "@sveltech/routify" |
import { goto } from "@sveltech/routify" |
||||
import { onMount } from "svelte" |
import { onMount } from "svelte" |
||||
|
|
||||
onMount(async () => { |
onMount(async () => { |
||||
// navigate to first table in list, if not already selected |
// navigate to first table in list, if not already selected |
||||
$backendUiStore.datasources.length > 0 && |
$datasources.list.length > 0 && $goto(`../${$datasources.list[0]._id}`) |
||||
$goto(`../${$backendUiStore.datasources[0]._id}`) |
}) |
||||
}) |
</script> |
||||
</script> |
|
||||
|
{#if $tables.list.length === 0} |
||||
{#if $backendUiStore.tables.length === 0} |
<i>Connect your first datasource to start building.</i> |
||||
<i>Connect your first datasource to start building.</i> |
{:else}<i>Select a datasource to edit</i>{/if} |
||||
{:else}<i>Select a datasource to edit</i>{/if} |
|
||||
|
<style> |
||||
<style> |
i { |
||||
i { |
font-size: var(--font-size-m); |
||||
font-size: var(--font-size-m); |
color: var(--grey-5); |
||||
color: var(--grey-5); |
margin-top: 2px; |
||||
margin-top: 2px; |
} |
||||
} |
</style> |
||||
</style> |
|
||||
|
|||||
@ -0,0 +1,3 @@ |
|||||
|
import { writable } from "svelte/store" |
||||
|
|
||||
|
export const database = writable({}) |
||||
@ -0,0 +1,66 @@ |
|||||
|
import { writable } from "svelte/store" |
||||
|
import { queries } from "./" |
||||
|
import api from "../../builderStore/api" |
||||
|
|
||||
|
export const INITIAL_DATASOURCE_VALUES = { |
||||
|
list: [], |
||||
|
selected: null, |
||||
|
} |
||||
|
|
||||
|
export function createDatasourcesStore() { |
||||
|
const { subscribe, update, set } = writable(INITIAL_DATASOURCE_VALUES) |
||||
|
|
||||
|
return { |
||||
|
subscribe, |
||||
|
update, |
||||
|
init: async () => { |
||||
|
const response = await api.get(`/api/datasources`) |
||||
|
const json = await response.json() |
||||
|
set({ list: json, selected: null }) |
||||
|
}, |
||||
|
fetch: async () => { |
||||
|
const response = await api.get(`/api/datasources`) |
||||
|
const json = await response.json() |
||||
|
update(state => ({ ...state, list: json })) |
||||
|
return json |
||||
|
}, |
||||
|
select: async datasourceId => { |
||||
|
update(state => ({ ...state, selected: datasourceId })) |
||||
|
queries.update(state => ({ ...state, selected: null })) |
||||
|
}, |
||||
|
save: async datasource => { |
||||
|
const response = await api.post("/api/datasources", datasource) |
||||
|
const json = await response.json() |
||||
|
|
||||
|
update(state => { |
||||
|
const currentIdx = state.list.findIndex(ds => ds._id === json._id) |
||||
|
|
||||
|
const sources = state.list |
||||
|
|
||||
|
if (currentIdx >= 0) { |
||||
|
sources.splice(currentIdx, 1, json) |
||||
|
} else { |
||||
|
sources.push(json) |
||||
|
} |
||||
|
|
||||
|
return { list: sources, selected: json._id } |
||||
|
}) |
||||
|
return json |
||||
|
}, |
||||
|
delete: async datasource => { |
||||
|
const response = await api.delete( |
||||
|
`/api/datasources/${datasource._id}/${datasource._rev}` |
||||
|
) |
||||
|
update(state => { |
||||
|
const sources = state.list.filter( |
||||
|
existing => existing._id !== datasource._id |
||||
|
) |
||||
|
return { list: sources, selected: null } |
||||
|
}) |
||||
|
|
||||
|
return response |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const datasources = createDatasourcesStore() |
||||
@ -0,0 +1,9 @@ |
|||||
|
export { database } from "./database" |
||||
|
export { tables } from "./tables" |
||||
|
export { views } from "./views" |
||||
|
export { rows } from "./rows" |
||||
|
export { permissions } from "./permissions" |
||||
|
export { roles } from "./roles" |
||||
|
export { datasources } from "./datasources" |
||||
|
export { integrations } from "./integrations" |
||||
|
export { queries } from "./queries" |
||||
@ -0,0 +1,3 @@ |
|||||
|
import { writable } from "svelte/store" |
||||
|
|
||||
|
export const integrations = writable({}) |
||||
@ -0,0 +1,17 @@ |
|||||
|
import { writable } from "svelte/store" |
||||
|
import api from "builderStore/api" |
||||
|
|
||||
|
export function createPermissionStore() { |
||||
|
const { subscribe } = writable([]) |
||||
|
|
||||
|
return { |
||||
|
subscribe, |
||||
|
forResource: async resourceId => { |
||||
|
const response = await api.get(`/api/permission/${resourceId}`) |
||||
|
const json = await response.json() |
||||
|
return json |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const permissions = createPermissionStore() |
||||
@ -0,0 +1,77 @@ |
|||||
|
import { writable, get } from "svelte/store" |
||||
|
import { datasources, integrations } from "./" |
||||
|
import api from "builderStore/api" |
||||
|
|
||||
|
export function createQueriesStore() { |
||||
|
const { subscribe, set, update } = writable({ list: [], selected: null }) |
||||
|
|
||||
|
return { |
||||
|
subscribe, |
||||
|
set, |
||||
|
update, |
||||
|
init: async () => { |
||||
|
const response = await api.get(`/api/queries`) |
||||
|
const json = await response.json() |
||||
|
set({ list: json, selected: null }) |
||||
|
}, |
||||
|
fetch: async () => { |
||||
|
const response = await api.get(`/api/queries`) |
||||
|
const json = await response.json() |
||||
|
update(state => ({ ...state, list: json })) |
||||
|
return json |
||||
|
}, |
||||
|
save: async (datasourceId, query) => { |
||||
|
const _integrations = get(integrations) |
||||
|
const dataSource = get(datasources).list.filter( |
||||
|
ds => ds._id === datasourceId |
||||
|
) |
||||
|
// check if readable attribute is found
|
||||
|
if (dataSource.length !== 0) { |
||||
|
const integration = _integrations[dataSource[0].source] |
||||
|
const readable = integration.query[query.queryVerb].readable |
||||
|
if (readable) { |
||||
|
query.readable = readable |
||||
|
} |
||||
|
} |
||||
|
query.datasourceId = datasourceId |
||||
|
const response = await api.post(`/api/queries`, query) |
||||
|
if (response.status !== 200) { |
||||
|
throw new Error("Failed saving query.") |
||||
|
} |
||||
|
const json = await response.json() |
||||
|
update(state => { |
||||
|
const currentIdx = state.list.findIndex(query => query._id === json._id) |
||||
|
|
||||
|
const queries = state.list |
||||
|
|
||||
|
if (currentIdx >= 0) { |
||||
|
queries.splice(currentIdx, 1, json) |
||||
|
} else { |
||||
|
queries.push(json) |
||||
|
} |
||||
|
return { list: queries, selected: json._id } |
||||
|
}) |
||||
|
return json |
||||
|
}, |
||||
|
select: query => { |
||||
|
update(state => ({ ...state, selected: query._id })) |
||||
|
datasources.update(state => ({ ...state, selected: query.datasourceId })) |
||||
|
}, |
||||
|
delete: async query => { |
||||
|
const response = await api.delete( |
||||
|
`/api/queries/${query._id}/${query._rev}` |
||||
|
) |
||||
|
update(state => { |
||||
|
state.list = state.list.filter(existing => existing._id !== query._id) |
||||
|
if (state.selected === query._id) { |
||||
|
state.selected = null |
||||
|
} |
||||
|
|
||||
|
return state |
||||
|
}) |
||||
|
return response |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const queries = createQueriesStore() |
||||
@ -0,0 +1,30 @@ |
|||||
|
import { writable } from "svelte/store" |
||||
|
import api from "builderStore/api" |
||||
|
|
||||
|
export function createRolesStore() { |
||||
|
const { subscribe, update, set } = writable([]) |
||||
|
|
||||
|
return { |
||||
|
subscribe, |
||||
|
fetch: async () => { |
||||
|
set(await getRoles()) |
||||
|
}, |
||||
|
delete: async role => { |
||||
|
const response = await api.delete(`/api/roles/${role._id}/${role._rev}`) |
||||
|
update(state => state.filter(existing => existing._id !== role._id)) |
||||
|
return response |
||||
|
}, |
||||
|
save: async role => { |
||||
|
const response = await api.post("/api/roles", role) |
||||
|
set(await getRoles()) |
||||
|
return response |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function getRoles() { |
||||
|
const response = await api.get("/api/roles") |
||||
|
return await response.json() |
||||
|
} |
||||
|
|
||||
|
export const roles = createRolesStore() |
||||
@ -0,0 +1,14 @@ |
|||||
|
import { writable, get } from "svelte/store" |
||||
|
import { views } from "./" |
||||
|
|
||||
|
export function createRowsStore() { |
||||
|
const { subscribe } = writable([]) |
||||
|
|
||||
|
return { |
||||
|
subscribe, |
||||
|
save: () => views.select(get(views).selected), |
||||
|
delete: () => views.select(get(views).selected), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const rows = createRowsStore() |
||||
@ -0,0 +1,128 @@ |
|||||
|
import { writable, get } from "svelte/store" |
||||
|
import { views } from "./" |
||||
|
import { cloneDeep } from "lodash/fp" |
||||
|
import api from "builderStore/api" |
||||
|
|
||||
|
export function createTablesStore() { |
||||
|
const store = writable({}) |
||||
|
const { subscribe, update, set } = store |
||||
|
|
||||
|
async function fetch() { |
||||
|
const tablesResponse = await api.get(`/api/tables`) |
||||
|
const tables = await tablesResponse.json() |
||||
|
update(state => ({ ...state, list: tables })) |
||||
|
} |
||||
|
|
||||
|
async function select(table) { |
||||
|
if (!table) { |
||||
|
update(state => ({ |
||||
|
...state, |
||||
|
selected: {}, |
||||
|
})) |
||||
|
} else { |
||||
|
update(state => ({ |
||||
|
...state, |
||||
|
selected: table, |
||||
|
draft: cloneDeep(table), |
||||
|
})) |
||||
|
views.select({ name: `all_${table._id}` }) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function save(table) { |
||||
|
const updatedTable = cloneDeep(table) |
||||
|
const oldTable = get(store).list.filter(t => t._id === table._id)[0] |
||||
|
|
||||
|
const fieldNames = [] |
||||
|
// update any renamed schema keys to reflect their names
|
||||
|
for (let key of Object.keys(updatedTable.schema)) { |
||||
|
// if field name has been seen before remove it
|
||||
|
if (fieldNames.indexOf(key.toLowerCase()) !== -1) { |
||||
|
delete updatedTable.schema[key] |
||||
|
continue |
||||
|
} |
||||
|
const field = updatedTable.schema[key] |
||||
|
const oldField = oldTable?.schema[key] |
||||
|
// if the type has changed then revert back to the old field
|
||||
|
if (oldField != null && oldField?.type !== field.type) { |
||||
|
updatedTable.schema[key] = oldField |
||||
|
} |
||||
|
// field has been renamed
|
||||
|
if (field.name && field.name !== key) { |
||||
|
updatedTable.schema[field.name] = field |
||||
|
updatedTable._rename = { old: key, updated: field.name } |
||||
|
delete updatedTable.schema[key] |
||||
|
} |
||||
|
// finally record this field has been used
|
||||
|
fieldNames.push(key.toLowerCase()) |
||||
|
} |
||||
|
|
||||
|
const response = await api.post(`/api/tables`, updatedTable) |
||||
|
const savedTable = await response.json() |
||||
|
await fetch() |
||||
|
await select(savedTable) |
||||
|
return savedTable |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
subscribe, |
||||
|
fetch, |
||||
|
select, |
||||
|
save, |
||||
|
init: async () => { |
||||
|
const response = await api.get("/api/tables") |
||||
|
const json = await response.json() |
||||
|
set({ |
||||
|
list: json, |
||||
|
selected: {}, |
||||
|
draft: {}, |
||||
|
}) |
||||
|
}, |
||||
|
delete: async table => { |
||||
|
await api.delete(`/api/tables/${table._id}/${table._rev}`) |
||||
|
update(state => ({ |
||||
|
...state, |
||||
|
list: state.list.filter(existing => existing._id !== table._id), |
||||
|
selected: {}, |
||||
|
})) |
||||
|
}, |
||||
|
saveField: ({ originalName, field, primaryDisplay = false, indexes }) => { |
||||
|
update(state => { |
||||
|
// delete the original if renaming
|
||||
|
// need to handle if the column had no name, empty string
|
||||
|
if (originalName || originalName === "") { |
||||
|
delete state.draft.schema[originalName] |
||||
|
state.draft._rename = { |
||||
|
old: originalName, |
||||
|
updated: field.name, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Optionally set display column
|
||||
|
if (primaryDisplay) { |
||||
|
state.draft.primaryDisplay = field.name |
||||
|
} |
||||
|
|
||||
|
if (indexes) { |
||||
|
state.draft.indexes = indexes |
||||
|
} |
||||
|
|
||||
|
state.draft.schema = { |
||||
|
...state.draft.schema, |
||||
|
[field.name]: cloneDeep(field), |
||||
|
} |
||||
|
save(state.draft) |
||||
|
return state |
||||
|
}) |
||||
|
}, |
||||
|
deleteField: field => { |
||||
|
update(state => { |
||||
|
delete state.draft.schema[field.name] |
||||
|
save(state.draft) |
||||
|
return state |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const tables = createTablesStore() |
||||
@ -0,0 +1,68 @@ |
|||||
|
import { get } from 'svelte/store' |
||||
|
import api from 'builderStore/api' |
||||
|
|
||||
|
jest.mock('builderStore/api'); |
||||
|
|
||||
|
import { SOME_DATASOURCE, SAVE_DATASOURCE} from './fixtures/datasources' |
||||
|
|
||||
|
import { createDatasourcesStore } from "../datasources" |
||||
|
import { queries } from '../queries' |
||||
|
|
||||
|
describe("Datasources Store", () => { |
||||
|
let store = createDatasourcesStore() |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
api.get.mockReturnValue({ json: () => [SOME_DATASOURCE]}) |
||||
|
await store.init() |
||||
|
}) |
||||
|
|
||||
|
it("Initialises correctly", async () => { |
||||
|
api.get.mockReturnValue({ json: () => [SOME_DATASOURCE]}) |
||||
|
|
||||
|
await store.init() |
||||
|
expect(get(store)).toEqual({ list: [SOME_DATASOURCE], selected: null}) |
||||
|
}) |
||||
|
|
||||
|
it("fetches all the datasources and updates the store", async () => { |
||||
|
api.get.mockReturnValue({ json: () => [SOME_DATASOURCE]}) |
||||
|
|
||||
|
await store.fetch() |
||||
|
expect(get(store)).toEqual({ list: [SOME_DATASOURCE], selected: null}) |
||||
|
}) |
||||
|
|
||||
|
it("selects a datasource", async () => { |
||||
|
store.select(SOME_DATASOURCE._id) |
||||
|
|
||||
|
expect(get(store).select).toEqual(SOME_DATASOURCE._id) |
||||
|
}) |
||||
|
|
||||
|
it("resets the queries store when new datasource is selected", async () => { |
||||
|
|
||||
|
await store.select(SOME_DATASOURCE._id) |
||||
|
const queriesValue = get(queries) |
||||
|
expect(queriesValue.selected).toEqual(null) |
||||
|
}) |
||||
|
|
||||
|
it("saves the datasource, updates the store and returns status message", async () => { |
||||
|
api.post.mockReturnValue({ json: () => SAVE_DATASOURCE}) |
||||
|
|
||||
|
await store.save({ |
||||
|
name: 'CoolDB', |
||||
|
source: 'REST', |
||||
|
config: SOME_DATASOURCE[0].config |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
expect(get(store).list).toEqual(expect.arrayContaining([SAVE_DATASOURCE])) |
||||
|
}) |
||||
|
it("deletes a datasource, updates the store and returns status message", async () => { |
||||
|
api.get.mockReturnValue({ json: () => SOME_DATASOURCE}) |
||||
|
|
||||
|
await store.fetch() |
||||
|
|
||||
|
api.delete.mockReturnValue({status: 200, message: 'Datasource deleted.'}) |
||||
|
|
||||
|
await store.delete(SOME_DATASOURCE[0]) |
||||
|
expect(get(store)).toEqual({ list: [], selected: null}) |
||||
|
}) |
||||
|
}) |
||||
@ -0,0 +1,25 @@ |
|||||
|
export const SOME_DATASOURCE = [ |
||||
|
{ |
||||
|
type: "datasource", |
||||
|
name: "erterter", |
||||
|
source: "REST", |
||||
|
config: { |
||||
|
url: "localhost", |
||||
|
defaultHeaders: {}, |
||||
|
}, |
||||
|
_id: "datasource_04b003a7b4a8428eadd3bb2f7eae0255", |
||||
|
_rev: "1-4e72002f1011e9392e655948469b7908", |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
export const SAVE_DATASOURCE = { |
||||
|
type: "datasource", |
||||
|
name: "CoolDB", |
||||
|
source: "REST", |
||||
|
config: { |
||||
|
url: "localhost", |
||||
|
defaultHeaders: {}, |
||||
|
}, |
||||
|
_id: "datasource_04b003a7b4a8428eadd3bb2f7eae0255", |
||||
|
_rev: "1-4e72002f1011e9392e655948469b7908", |
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
export const SOME_QUERY = { |
||||
|
datasourceId: "datasource_04b003a7b4a8428eadd3bb2f7eae0255", |
||||
|
parameters: [], |
||||
|
fields: { |
||||
|
headers: {}, |
||||
|
queryString: "", |
||||
|
path: "Speakers", |
||||
|
}, |
||||
|
queryVerb: "read", |
||||
|
schema: {}, |
||||
|
name: "Speakers", |
||||
|
_id: |
||||
|
"query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f", |
||||
|
_rev: "2-941f8699eb0adf995f8bd59c99203b26", |
||||
|
readable: true, |
||||
|
} |
||||
|
|
||||
|
export const SAVE_QUERY_RESPONSE = { |
||||
|
datasourceId: "datasource_04b003a7b4a8428eadd3bb2f7eae0255", |
||||
|
parameters: [], |
||||
|
fields: { |
||||
|
headers: {}, |
||||
|
queryString: "", |
||||
|
path: "Speakers", |
||||
|
}, |
||||
|
queryVerb: "read", |
||||
|
schema: { |
||||
|
id: { |
||||
|
name: "id", |
||||
|
type: "string", |
||||
|
}, |
||||
|
firstName: { |
||||
|
name: "firstName", |
||||
|
type: "string", |
||||
|
}, |
||||
|
lastName: { |
||||
|
name: "lastName", |
||||
|
type: "string", |
||||
|
}, |
||||
|
fullName: { |
||||
|
name: "fullName", |
||||
|
type: "string", |
||||
|
}, |
||||
|
bio: { |
||||
|
name: "bio", |
||||
|
type: "string", |
||||
|
}, |
||||
|
tagLine: { |
||||
|
name: "tagLine", |
||||
|
type: "string", |
||||
|
}, |
||||
|
profilePicture: { |
||||
|
name: "profilePicture", |
||||
|
type: "string", |
||||
|
}, |
||||
|
sessions: { |
||||
|
name: "sessions", |
||||
|
type: "string", |
||||
|
}, |
||||
|
isTopSpeaker: { |
||||
|
name: "isTopSpeaker", |
||||
|
type: "string", |
||||
|
}, |
||||
|
links: { |
||||
|
name: "links", |
||||
|
type: "string", |
||||
|
}, |
||||
|
questionAnswers: { |
||||
|
name: "questionAnswers", |
||||
|
type: "string", |
||||
|
}, |
||||
|
categories: { |
||||
|
name: "categories", |
||||
|
type: "string", |
||||
|
}, |
||||
|
}, |
||||
|
name: "Speakers", |
||||
|
_id: |
||||
|
"query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f", |
||||
|
_rev: "3-5a64adef494b1e9c793dc91b51ce73c6", |
||||
|
readable: true, |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
export const ROLES = [ |
||||
|
{ |
||||
|
name: "Test", |
||||
|
permissionId: "admin", |
||||
|
inherits: "ADMIN", |
||||
|
_id: "role_04681b7e71914a0aa53e09a5bea3584f", |
||||
|
_rev: "1-179c71ea61d7fd987306b84b6d64b00e", |
||||
|
}, |
||||
|
{ |
||||
|
_id: "ADMIN", |
||||
|
name: "Admin", |
||||
|
permissionId: "admin", |
||||
|
inherits: "POWER", |
||||
|
}, |
||||
|
{ |
||||
|
_id: "POWER", |
||||
|
name: "Power", |
||||
|
permissionId: "power", |
||||
|
inherits: "BASIC", |
||||
|
}, |
||||
|
{ |
||||
|
_id: "BASIC", |
||||
|
name: "Basic", |
||||
|
permissionId: "write", |
||||
|
inherits: "PUBLIC", |
||||
|
}, |
||||
|
{ |
||||
|
_id: "PUBLIC", |
||||
|
name: "Public", |
||||
|
permissionId: "public", |
||||
|
}, |
||||
|
] |
||||
@ -0,0 +1,717 @@ |
|||||
|
export const SOME_TABLES = [ |
||||
|
{ |
||||
|
type: "table", |
||||
|
views: {}, |
||||
|
name: "Guest", |
||||
|
schema: { |
||||
|
"Auto ID": { |
||||
|
name: "Auto ID", |
||||
|
type: "number", |
||||
|
subtype: "autoID", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
lastID: 1, |
||||
|
}, |
||||
|
"Created By": { |
||||
|
name: "Created By", |
||||
|
type: "link", |
||||
|
subtype: "createdBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Created At": { |
||||
|
name: "Created At", |
||||
|
type: "datetime", |
||||
|
subtype: "createdAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"Updated By": { |
||||
|
name: "Updated By", |
||||
|
type: "link", |
||||
|
subtype: "updatedBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Updated At": { |
||||
|
name: "Updated At", |
||||
|
type: "datetime", |
||||
|
subtype: "updatedAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
Name: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Guest", |
||||
|
name: "Name", |
||||
|
}, |
||||
|
Episode: { |
||||
|
name: "Episode", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Guest", |
||||
|
relationshipType: "one-to-many", |
||||
|
}, |
||||
|
}, |
||||
|
primaryDisplay: "Name", |
||||
|
indexes: [], |
||||
|
_id: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
_rev: "10-27f034bf50ec3e2f180d8f96db1f0f31", |
||||
|
}, |
||||
|
{ |
||||
|
type: "table", |
||||
|
views: {}, |
||||
|
name: "Sponsors", |
||||
|
schema: { |
||||
|
"Auto ID": { |
||||
|
name: "Auto ID", |
||||
|
type: "number", |
||||
|
subtype: "autoID", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
lastID: 1, |
||||
|
}, |
||||
|
"Created By": { |
||||
|
name: "Created By", |
||||
|
type: "link", |
||||
|
subtype: "createdBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Sponsors-Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Created At": { |
||||
|
name: "Created At", |
||||
|
type: "datetime", |
||||
|
subtype: "createdAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"Updated By": { |
||||
|
name: "Updated By", |
||||
|
type: "link", |
||||
|
subtype: "updatedBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Sponsors-Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Updated At": { |
||||
|
name: "Updated At", |
||||
|
type: "datetime", |
||||
|
subtype: "updatedAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
Name: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Sponsors", |
||||
|
name: "Name", |
||||
|
}, |
||||
|
Spot: { |
||||
|
type: "longform", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Sponsors", |
||||
|
name: "Spot", |
||||
|
}, |
||||
|
Episode: { |
||||
|
name: "Episode", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Sponsors", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
}, |
||||
|
primaryDisplay: "Name", |
||||
|
indexes: [], |
||||
|
_id: "ta_7fd0fa15edd54e0f91a47f50b7577281", |
||||
|
_rev: "7-de89b81e21ae4b3f65a6b655144fe097", |
||||
|
}, |
||||
|
{ |
||||
|
type: "table", |
||||
|
views: {}, |
||||
|
name: "Episode", |
||||
|
schema: { |
||||
|
"Auto ID": { |
||||
|
name: "Auto ID", |
||||
|
type: "number", |
||||
|
subtype: "autoID", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
lastID: 1, |
||||
|
}, |
||||
|
"Created By": { |
||||
|
name: "Created By", |
||||
|
type: "link", |
||||
|
subtype: "createdBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Episode-Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Created At": { |
||||
|
name: "Created At", |
||||
|
type: "datetime", |
||||
|
subtype: "createdAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"Updated By": { |
||||
|
name: "Updated By", |
||||
|
type: "link", |
||||
|
subtype: "updatedBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Episode-Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Updated At": { |
||||
|
name: "Updated At", |
||||
|
type: "datetime", |
||||
|
subtype: "updatedAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
Summary: { |
||||
|
type: "longform", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Summary", |
||||
|
}, |
||||
|
Author: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Author", |
||||
|
}, |
||||
|
Published: { |
||||
|
type: "boolean", |
||||
|
constraints: { |
||||
|
type: "boolean", |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Published", |
||||
|
}, |
||||
|
Guest: { |
||||
|
type: "link", |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Guest", |
||||
|
relationshipType: "many-to-one", |
||||
|
tableId: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
}, |
||||
|
Title: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Title", |
||||
|
}, |
||||
|
"Show Notes": { |
||||
|
type: "longform", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Show Notes", |
||||
|
}, |
||||
|
Sponsors: { |
||||
|
type: "link", |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Sponsors", |
||||
|
relationshipType: "many-to-many", |
||||
|
tableId: "ta_7fd0fa15edd54e0f91a47f50b7577281", |
||||
|
}, |
||||
|
Number: { |
||||
|
type: "number", |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Number", |
||||
|
}, |
||||
|
Audio: { |
||||
|
type: "attachment", |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Episode", |
||||
|
name: "Audio", |
||||
|
}, |
||||
|
}, |
||||
|
indexes: [], |
||||
|
primaryDisplay: "Author", |
||||
|
_id: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
_rev: "13-9d70dee825154a9df5c22e1d39bf269c", |
||||
|
}, |
||||
|
{ |
||||
|
type: "table", |
||||
|
views: {}, |
||||
|
name: "Users", |
||||
|
schema: { |
||||
|
email: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
email: true, |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: true, |
||||
|
}, |
||||
|
fieldName: "email", |
||||
|
name: "email", |
||||
|
}, |
||||
|
roleId: { |
||||
|
fieldName: "roleId", |
||||
|
name: "roleId", |
||||
|
type: "options", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
presence: false, |
||||
|
inclusion: ["ADMIN", "POWER", "BASIC", "PUBLIC", "BUILDER"], |
||||
|
}, |
||||
|
}, |
||||
|
status: { |
||||
|
fieldName: "status", |
||||
|
name: "status", |
||||
|
type: "options", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
presence: false, |
||||
|
inclusion: ["active", "inactive"], |
||||
|
}, |
||||
|
}, |
||||
|
"Episode-Created By": { |
||||
|
name: "Episode-Created By", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
autocolumn: true, |
||||
|
}, |
||||
|
"Episode-Updated By": { |
||||
|
name: "Episode-Updated By", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
autocolumn: true, |
||||
|
}, |
||||
|
"Guest-Created By": { |
||||
|
name: "Guest-Created By", |
||||
|
type: "link", |
||||
|
tableId: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
fieldName: "Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
autocolumn: true, |
||||
|
}, |
||||
|
"Guest-Updated By": { |
||||
|
name: "Guest-Updated By", |
||||
|
type: "link", |
||||
|
tableId: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
fieldName: "Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
autocolumn: true, |
||||
|
}, |
||||
|
"Sponsors-Created By": { |
||||
|
name: "Sponsors-Created By", |
||||
|
type: "link", |
||||
|
tableId: "ta_7fd0fa15edd54e0f91a47f50b7577281", |
||||
|
fieldName: "Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
autocolumn: true, |
||||
|
}, |
||||
|
"Sponsors-Updated By": { |
||||
|
name: "Sponsors-Updated By", |
||||
|
type: "link", |
||||
|
tableId: "ta_7fd0fa15edd54e0f91a47f50b7577281", |
||||
|
fieldName: "Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
autocolumn: true, |
||||
|
}, |
||||
|
}, |
||||
|
primaryDisplay: "email", |
||||
|
_id: "ta_users", |
||||
|
_rev: "67-1833e6a0028c100633e31788fe958a62", |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
export const SAVE_TABLES_RESPONSE = { |
||||
|
type: "table", |
||||
|
_id: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
views: {}, |
||||
|
name: "Guest", |
||||
|
schema: { |
||||
|
"Auto ID": { |
||||
|
name: "Auto ID", |
||||
|
type: "number", |
||||
|
subtype: "autoID", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
lastID: 1, |
||||
|
}, |
||||
|
"Created By": { |
||||
|
name: "Created By", |
||||
|
type: "link", |
||||
|
subtype: "createdBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Created At": { |
||||
|
name: "Created At", |
||||
|
type: "datetime", |
||||
|
subtype: "createdAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"Updated By": { |
||||
|
name: "Updated By", |
||||
|
type: "link", |
||||
|
subtype: "updatedBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Updated At": { |
||||
|
name: "Updated At", |
||||
|
type: "datetime", |
||||
|
subtype: "updatedAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
Episode: { |
||||
|
name: "Episode", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Guest", |
||||
|
relationshipType: "one-to-many", |
||||
|
}, |
||||
|
Names: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Guest", |
||||
|
name: "Names", |
||||
|
}, |
||||
|
}, |
||||
|
primaryDisplay: "Names", |
||||
|
indexes: [], |
||||
|
_rev: "11-7c153edbc6d7c43821cfd5ed526266cf", |
||||
|
} |
||||
|
|
||||
|
export const A_TABLE = { |
||||
|
type: "table", |
||||
|
views: {}, |
||||
|
name: "Guest", |
||||
|
schema: { |
||||
|
"Auto ID": { |
||||
|
name: "Auto ID", |
||||
|
type: "number", |
||||
|
subtype: "autoID", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
lastID: 1, |
||||
|
}, |
||||
|
"Created By": { |
||||
|
name: "Created By", |
||||
|
type: "link", |
||||
|
subtype: "createdBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Created At": { |
||||
|
name: "Created At", |
||||
|
type: "datetime", |
||||
|
subtype: "createdAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"Updated By": { |
||||
|
name: "Updated By", |
||||
|
type: "link", |
||||
|
subtype: "updatedBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Updated At": { |
||||
|
name: "Updated At", |
||||
|
type: "datetime", |
||||
|
subtype: "updatedAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
Episode: { |
||||
|
name: "Episode", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Guest", |
||||
|
relationshipType: "one-to-many", |
||||
|
}, |
||||
|
Names: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Guest", |
||||
|
name: "Names", |
||||
|
}, |
||||
|
}, |
||||
|
primaryDisplay: "Names", |
||||
|
indexes: [], |
||||
|
_id: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
_rev: "10-27f034bf50ec3e2f180d8f96db1f0f31", |
||||
|
_rename: { |
||||
|
old: "Name", |
||||
|
updated: "Names", |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,102 @@ |
|||||
|
export const A_VIEW = { |
||||
|
name: "Published", |
||||
|
tableId: "ta_3c78cffe33664ca9bfb6b2b6cb3ee55a", |
||||
|
filters: [], |
||||
|
schema: { |
||||
|
"Auto ID": { |
||||
|
name: "Auto ID", |
||||
|
type: "number", |
||||
|
subtype: "autoID", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "number", |
||||
|
presence: false, |
||||
|
numericality: { |
||||
|
greaterThanOrEqualTo: "", |
||||
|
lessThanOrEqualTo: "", |
||||
|
}, |
||||
|
}, |
||||
|
lastID: 2, |
||||
|
}, |
||||
|
"Created By": { |
||||
|
name: "Created By", |
||||
|
type: "link", |
||||
|
subtype: "createdBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Created By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Created At": { |
||||
|
name: "Created At", |
||||
|
type: "datetime", |
||||
|
subtype: "createdAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
"Updated By": { |
||||
|
name: "Updated By", |
||||
|
type: "link", |
||||
|
subtype: "updatedBy", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "array", |
||||
|
presence: false, |
||||
|
}, |
||||
|
tableId: "ta_users", |
||||
|
fieldName: "Guest-Updated By", |
||||
|
relationshipType: "many-to-many", |
||||
|
}, |
||||
|
"Updated At": { |
||||
|
name: "Updated At", |
||||
|
type: "datetime", |
||||
|
subtype: "updatedAt", |
||||
|
icon: "ri-magic-line", |
||||
|
autocolumn: true, |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: {}, |
||||
|
presence: false, |
||||
|
datetime: { |
||||
|
latest: "", |
||||
|
earliest: "", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
Episode: { |
||||
|
name: "Episode", |
||||
|
type: "link", |
||||
|
tableId: "ta_d4bf541ce0d84b16a1a8e0a060e5f7f7", |
||||
|
fieldName: "Guest", |
||||
|
relationshipType: "one-to-many", |
||||
|
}, |
||||
|
Names: { |
||||
|
type: "string", |
||||
|
constraints: { |
||||
|
type: "string", |
||||
|
length: { |
||||
|
maximum: "", |
||||
|
}, |
||||
|
presence: false, |
||||
|
}, |
||||
|
fieldName: "Guest", |
||||
|
name: "Names", |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
import api from 'builderStore/api' |
||||
|
|
||||
|
jest.mock('builderStore/api'); |
||||
|
|
||||
|
const PERMISSIONS_FOR_RESOURCE = { |
||||
|
"write": "BASIC", |
||||
|
"read": "BASIC" |
||||
|
} |
||||
|
|
||||
|
import { createPermissionStore } from "../permissions" |
||||
|
|
||||
|
describe("Permissions Store", () => { |
||||
|
const store = createPermissionStore() |
||||
|
|
||||
|
it("fetches permissions for specific resource", async () => { |
||||
|
api.get.mockReturnValueOnce({ json: () => PERMISSIONS_FOR_RESOURCE}) |
||||
|
|
||||
|
const resourceId = "ta_013657543b4043b89dbb17e9d3a4723a" |
||||
|
|
||||
|
const permissions = await store.forResource(resourceId) |
||||
|
|
||||
|
expect(api.get).toBeCalledWith(`/api/permission/${resourceId}`) |
||||
|
expect(permissions).toEqual(PERMISSIONS_FOR_RESOURCE) |
||||
|
}) |
||||
|
}) |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue