5 Commits

Author SHA1 Message Date
Eric Tuvesson
eb71536cb0 chore: Update branding info (#31)
* fix: branding info for package.json

* fix: updated package jsons with updated contact & author info

---------

Co-authored-by: alan-x-n <x.alanan.x@gmail.com>
2024-06-02 17:43:03 +02:00
Eric Tuvesson
d67afd3c60 feat(runtime): Date To String node, add "yearShort" format (#29) 2024-06-02 07:55:39 -07:00
Eric Tuvesson
1a048587d9 feat(editor): Tooltip support multiple fineTypes (#28) 2024-05-31 08:58:17 +02:00
Eric Tuvesson
8e16d5f9d4 feat: Add tooltip to cloud service "Open Dashboard" button (#27) 2024-05-29 10:05:38 +02:00
Eric Tuvesson
cdeb4b1c15 feat: Improve the Noodl.Records.query typings API (#25) 2024-05-24 15:49:05 +02:00
20 changed files with 185 additions and 49 deletions

View File

@@ -2,8 +2,8 @@
"private": true, "private": true,
"name": "@noodl/repo", "name": "@noodl/repo",
"description": "Low-code for when experience matter", "description": "Low-code for when experience matter",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxcsape.io>",
"homepage": "https://noodl.net", "homepage": "https://fluxscape.io",
"version": "1.0.0", "version": "1.0.0",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"

View File

@@ -11,7 +11,7 @@ import css from './Tooltip.module.scss';
export interface TooltipProps extends UnsafeStyleProps { export interface TooltipProps extends UnsafeStyleProps {
content: SingleSlot; content: SingleSlot;
fineType?: string; fineType?: string | string[];
children: Slot; children: Slot;
showAfterMs?: number; showAfterMs?: number;
@@ -79,9 +79,17 @@ export function Tooltip({
{fineType && ( {fineType && (
<div className={css['FineType']}> <div className={css['FineType']}>
{Array.isArray(fineType) ? (
fineType.map((x) => (
<Label size={LabelSize.Small} variant={TextType.Secondary}>
{x}
</Label>
))
) : (
<Label size={LabelSize.Small} variant={TextType.Secondary}> <Label size={LabelSize.Small} variant={TextType.Secondary}>
{fineType} {fineType}
</Label> </Label>
)}
</div> </div>
)} )}
</BaseDialog> </BaseDialog>

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Noodl</title> <title>Fluxscape</title>
<link href="../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet" /> <link href="../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet" />
<link href="../assets/css/style.css" rel="stylesheet" /> <link href="../assets/css/style.css" rel="stylesheet" />

View File

@@ -2,6 +2,11 @@ import { Keybinding } from '@noodl-utils/keyboard/Keybinding';
import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode'; import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode';
export namespace Keybindings { export namespace Keybindings {
export const SEARCH = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_F);
export const CLOUD_SERVICE_OPEN_DASHBOARD = new Keybinding(KeyMod.CtrlCmd, KeyMod.Shift, KeyCode.KEY_P);
export const CLOUD_SERVICE_OPEN_DASHBOARD_BROWSER = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_P);
export const REFRESH_PREVIEW = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_R); export const REFRESH_PREVIEW = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_R);
export const OPEN_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_D); export const OPEN_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_D);
export const OPEN_CLOUD_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyMod.Shift, KeyCode.KEY_R); export const OPEN_CLOUD_DEVTOOLS = new Keybinding(KeyMod.CtrlCmd, KeyMod.Shift, KeyCode.KEY_R);

View File

@@ -1,7 +1,6 @@
import { AppRegistry } from '@noodl-models/app_registry'; import { AppRegistry } from '@noodl-models/app_registry';
import { SidebarModel } from '@noodl-models/sidebar'; import { SidebarModel } from '@noodl-models/sidebar';
import { Keybinding } from '@noodl-utils/keyboard/Keybinding'; import { Keybindings } from '@noodl-constants/Keybindings';
import { KeyCode, KeyMod } from '@noodl-utils/keyboard/KeyCode';
import { IconName } from '@noodl-core-ui/components/common/Icon'; import { IconName } from '@noodl-core-ui/components/common/Icon';
@@ -69,7 +68,7 @@ export function installSidePanel({ isLesson }: SetupEditorOptions) {
SidebarModel.instance.register({ SidebarModel.instance.register({
id: 'search', id: 'search',
name: 'Search', name: 'Search',
fineType: new Keybinding(KeyMod.CtrlCmd, KeyCode.KEY_F).label, fineType: Keybindings.SEARCH.label,
order: 2, order: 2,
icon: IconName.Search, icon: IconName.Search,
panel: SearchPanel panel: SearchPanel

View File

@@ -41,7 +41,7 @@ export class HtmlProcessor {
baseUrl = baseUrl + '/'; baseUrl = baseUrl + '/';
} }
const title = parameters.title || settings.htmlTitle || 'Noodl Viewer'; const title = parameters.title || settings.htmlTitle || 'Fluxscape Viewer';
let headCode = settings.headCode || ''; let headCode = settings.headCode || '';
if (parameters.headCode) { if (parameters.headCode) {

View File

@@ -1,13 +1,16 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Keybindings } from '@noodl-constants/Keybindings';
import { Environment } from '@noodl-models/CloudServices'; import { Environment } from '@noodl-models/CloudServices';
import ParseDashboardServer from '@noodl-utils/parsedashboardserver'; import ParseDashboardServer from '@noodl-utils/parsedashboardserver';
import { Icon, IconName, IconSize } from '@noodl-core-ui/components/common/Icon'; import { Icon, IconName, IconSize } from '@noodl-core-ui/components/common/Icon';
import { IconButton, IconButtonState, IconButtonVariant } from '@noodl-core-ui/components/inputs/IconButton'; import { IconButton, IconButtonState, IconButtonVariant } from '@noodl-core-ui/components/inputs/IconButton';
import { PrimaryButton, PrimaryButtonSize, PrimaryButtonVariant } from '@noodl-core-ui/components/inputs/PrimaryButton'; import { PrimaryButton, PrimaryButtonSize, PrimaryButtonVariant } from '@noodl-core-ui/components/inputs/PrimaryButton';
import { DialogRenderDirection } from '@noodl-core-ui/components/layout/BaseDialog';
import { Collapsible } from '@noodl-core-ui/components/layout/Collapsible'; import { Collapsible } from '@noodl-core-ui/components/layout/Collapsible';
import { Tooltip } from '@noodl-core-ui/components/popups/Tooltip';
import { Label, LabelSpacingSize } from '@noodl-core-ui/components/typography/Label'; import { Label, LabelSpacingSize } from '@noodl-core-ui/components/typography/Label';
import { Text, TextType } from '@noodl-core-ui/components/typography/Text'; import { Text, TextType } from '@noodl-core-ui/components/typography/Text';
@@ -118,12 +121,21 @@ export function CloudServiceCard({
</div> </div>
{isEditorEnvironment && ( {isEditorEnvironment && (
<Tooltip
content="Open the Parse Dashboard"
fineType={[
`In Window: ${Keybindings.CLOUD_SERVICE_OPEN_DASHBOARD.label}`,
`In Browser: ${Keybindings.CLOUD_SERVICE_OPEN_DASHBOARD_BROWSER.label}`
]}
renderDirection={DialogRenderDirection.Below}
>
<PrimaryButton <PrimaryButton
label="Open dashboard" label="Open dashboard"
size={PrimaryButtonSize.Small} size={PrimaryButtonSize.Small}
onClick={onDashboardClicked} onClick={onDashboardClicked}
isGrowing isGrowing
/> />
</Tooltip>
)} )}
</div> </div>
</div> </div>

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Noodl Viewer</title> <title>Fluxscape Viewer</title>
<link href="../../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet"> <link href="../../assets/lib/fontawesome/css/font-awesome.min.css" rel="stylesheet">
<link href="assets/style.css" rel="stylesheet"> <link href="assets/style.css" rel="stylesheet">
<script type="text/javascript" src="../../assets/lib/jquery-min.js"></script> <script type="text/javascript" src="../../assets/lib/jquery-min.js"></script>

View File

@@ -67,7 +67,7 @@ function startServer(app, projectGetSettings, projectGetInfo, projectGetComponen
ProjectModules.instance.injectIntoHtml(info.projectDirectory, data, '/', function (injected) { ProjectModules.instance.injectIntoHtml(info.projectDirectory, data, '/', function (injected) {
projectGetSettings((settings) => { projectGetSettings((settings) => {
settings = settings || {}; settings = settings || {};
injected = injected.replace('{{#title#}}', settings.htmlTitle || 'Noodl Viewer'); injected = injected.replace('{{#title#}}', settings.htmlTitle || 'Fluxscape Viewer');
injected = injected.replace('{{#customHeadCode#}}', settings.headCode || ''); injected = injected.replace('{{#customHeadCode#}}', settings.headCode || '');
response.writeHead(200, { response.writeHead(200, {

View File

@@ -3,8 +3,8 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "", "description": "",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://noodl.net", "homepage": "https://fluxscape.io",
"dependencies": { "dependencies": {
"desktop-trampoline": "https://github.com/desktop/desktop-trampoline/archive/refs/tags/v0.9.8.tar.gz", "desktop-trampoline": "https://github.com/desktop/desktop-trampoline/archive/refs/tags/v0.9.8.tar.gz",
"dugite": "^1.106.0", "dugite": "^1.106.0",

View File

@@ -3,8 +3,8 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "Cross platform implementation of platform specific features.", "description": "Cross platform implementation of platform specific features.",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://noodl.net", "homepage": "https://fluxscape.io",
"dependencies": { "dependencies": {
"@noodl/platform": "file:../noodl-platform", "@noodl/platform": "file:../noodl-platform",
"@noodl/platform-node": "file:../noodl-platform-node" "@noodl/platform-node": "file:../noodl-platform-node"

View File

@@ -3,8 +3,8 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "Cross platform implementation of platform specific features.", "description": "Cross platform implementation of platform specific features.",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://noodl.net", "homepage": "https://fluxscape.io",
"scripts": { "scripts": {
"test": "jest", "test": "jest",
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage"

View File

@@ -3,6 +3,6 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.ts", "main": "src/index.ts",
"description": "Cross platform implementation of platform specific features.", "description": "Cross platform implementation of platform specific features.",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://noodl.net" "homepage": "https://fluxscape.io"
} }

View File

@@ -75,10 +75,10 @@ var SetDbModelPropertiedNodeDefinition = {
_this.setError('Missing Record Id'); _this.setError('Missing Record Id');
return; return;
} }
var model = internal.model;
for (var i in internal.inputValues) { const model = internal.model;
model.set(i, internal.inputValues[i], { resolve: true }); for (const key in internal.inputValues) {
model.set(key, internal.inputValues[key], { resolve: true });
} }
CloudStore.forScope(_this.nodeScope.modelScope).save({ CloudStore.forScope(_this.nodeScope.modelScope).save({

View File

@@ -59,6 +59,7 @@ const DateToStringNode = {
const month = ('0' + (t.getMonth() + 1)).slice(-2); const month = ('0' + (t.getMonth() + 1)).slice(-2);
const monthShort = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(t); const monthShort = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(t);
const year = t.getFullYear(); const year = t.getFullYear();
const yearShort = year.toString().substring(2);
const hours = ('0' + t.getHours()).slice(-2); const hours = ('0' + t.getHours()).slice(-2);
const minutes = ('0' + t.getMinutes()).slice(-2); const minutes = ('0' + t.getMinutes()).slice(-2);
const seconds = ('0' + t.getSeconds()).slice(-2); const seconds = ('0' + t.getSeconds()).slice(-2);
@@ -68,6 +69,7 @@ const DateToStringNode = {
.replace(/\{month\}/g, month) .replace(/\{month\}/g, month)
.replace(/\{monthShort\}/g, monthShort) .replace(/\{monthShort\}/g, monthShort)
.replace(/\{year\}/g, year) .replace(/\{year\}/g, year)
.replace(/\{yearShort\}/g, yearShort)
.replace(/\{hours\}/g, hours) .replace(/\{hours\}/g, hours)
.replace(/\{minutes\}/g, minutes) .replace(/\{minutes\}/g, minutes)
.replace(/\{seconds\}/g, seconds); .replace(/\{seconds\}/g, seconds);

View File

@@ -3,6 +3,6 @@
"version": "2.7.0", "version": "2.7.0",
"main": "src/index.d.ts", "main": "src/index.d.ts",
"description": "", "description": "",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://noodl.net" "homepage": "https://fluxscape.io"
} }

View File

@@ -1,7 +1,7 @@
{ {
"name": "@noodl/cloud-runtime", "name": "@noodl/cloud-runtime",
"author": "Noodl <info@noodl.net>", "author": "Fluxscape <contact@fluxscape.io>",
"homepage": "https://noodl.net", "homepage": "https://fluxscape.io",
"version": "0.6.3", "version": "0.6.3",
"license": "MIT", "license": "MIT",
"main": "dist/main.js", "main": "dist/main.js",

View File

@@ -74,6 +74,59 @@ declare namespace Noodl {
*/ */
const Object: any; const Object: any;
type RecordQuery<T> =
{
lessThan: T
} |
{
lessThanOrEqualTo: T
} |
{
greaterThan: T
} |
{
greaterThanOrEqualTo: T
} |
{
equalTo: T
} |
{
notEqualTo: T
} |
{
containedIn: T
} |
{
notContainedIn : T
} |
{
exists: T
} |
{
matchesRegex: T
} |
{
text: T
} |
{
idEqualTo: T
} |
{
idContainedIn: T
} |
{
pointsTo: T
} |
{
relatedTo: T
};
type RecordQueryField<T> = T extends RecordQuery<any> ?
{ [K in keyof T]: { [P in K]: T[P] } & Partial<Record<Exclude<keyof T, K>, never>> }[keyof T]
: never;
type RecordSortKey<T extends string> = (`${T}` | `-${T}`)[];
interface RecordsApi { interface RecordsApi {
/** /**
* This is an async function that will query the database using the query * This is an async function that will query the database using the query
@@ -115,15 +168,17 @@ declare namespace Noodl {
* }) * })
* ``` * ```
*/ */
query( query<TClassName extends RecordClassName>(
className: RecordClassName, className: TClassName,
query?: any, query?:
RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }> |
{ and: RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }>[] },
options?: { options?: {
limit?: number; limit?: number;
skip?: number; skip?: number;
sort?: string[]; sort?: string | RecordSortKey<keyof DatabaseSchema[TClassName]>;
include?: any; include?: string | (keyof DatabaseSchema[TClassName])[];
select?: any; select?: string | (keyof DatabaseSchema[TClassName])[];
} }
): Promise<any>; ): Promise<any>;

View File

@@ -6,7 +6,7 @@ export default {
group: 'General', group: 'General',
plug: 'input', plug: 'input',
type: 'string', type: 'string',
default: 'Noodl Viewer', default: 'Fluxscape Viewer',
tooltip: 'The title that web browsers show', tooltip: 'The title that web browsers show',
ignoreInExport: true ignoreInExport: true
}, },

View File

@@ -131,6 +131,59 @@ declare namespace Noodl {
*/ */
const Events: EventsApi; const Events: EventsApi;
type RecordQuery<T> =
{
lessThan: T
} |
{
lessThanOrEqualTo: T
} |
{
greaterThan: T
} |
{
greaterThanOrEqualTo: T
} |
{
equalTo: T
} |
{
notEqualTo: T
} |
{
containedIn: T
} |
{
notContainedIn : T
} |
{
exists: T
} |
{
matchesRegex: T
} |
{
text: T
} |
{
idEqualTo: T
} |
{
idContainedIn: T
} |
{
pointsTo: T
} |
{
relatedTo: T
};
type RecordQueryField<T> = T extends RecordQuery<any> ?
{ [K in keyof T]: { [P in K]: T[P] } & Partial<Record<Exclude<keyof T, K>, never>> }[keyof T]
: never;
type RecordSortKey<T extends string> = (`${T}` | `-${T}`)[];
interface RecordsApi { interface RecordsApi {
/** /**
* This is an async function that will query the database using the query * This is an async function that will query the database using the query
@@ -172,15 +225,17 @@ declare namespace Noodl {
* }) * })
* ``` * ```
*/ */
query( query<TClassName extends RecordClassName>(
className: RecordClassName, className: TClassName,
query?: any, query?:
RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }> |
{ and: RecordQueryField<{ [K in keyof DatabaseSchema[TClassName]]: RecordQuery<any> }>[] },
options?: { options?: {
limit?: number; limit?: number;
skip?: number; skip?: number;
sort?: string[]; sort?: string | RecordSortKey<keyof DatabaseSchema[TClassName]>;
include?: any; include?: string | (keyof DatabaseSchema[TClassName])[];
select?: any; select?: string | (keyof DatabaseSchema[TClassName])[];
} }
): Promise<any>; ): Promise<any>;