mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-16 19:57:49 +01:00
v2.6.1 – Bug fixes (#743)
* Bump ejs from 3.1.6 to 3.1.8
Bumps [ejs](https://github.com/mde/ejs) from 3.1.6 to 3.1.8.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mde/ejs/compare/v3.1.6...v3.1.8)
---
updated-dependencies:
- dependency-name: ejs
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
* Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)
---
updated-dependencies:
- dependency-name: minimist
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
* Bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)
---
updated-dependencies:
- dependency-name: tmpl
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
* Bump protobufjs from 6.11.2 to 6.11.3
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.11.2 to 6.11.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/v6.11.3/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/compare/v6.11.2...v6.11.3)
---
updated-dependencies:
- dependency-name: protobufjs
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
* fix(rich-text-editor): fix dark mode ui appearance (#696)
* fix(rich-text-editor): fix dark mode ui appearance
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/components/RichTextEditor.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/theme/RichTextEditorDarkCSS.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* Update src/theme/RichTextEditorLightCSS.tsx
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* fix(rich-text-editor): add stylings to dropdown
* fix(rich-text-editor): add toolbar stylings
* fix(rich-text-editor): reset hover&focus bg
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* update date & time filter operators for clarity
* Action field: prevent selecting self as required field (fixes ROWY-551)
* Date & Time: only show date for date filters
* move fullScreenButton to be shared, remove md settings
* bundle-analyzer
* Leaf icon: use mdi-material-ui
* Feat: Percentage field color customization (#692)
* feat(percentage-c11n): convert to table cell
* feat(percentage-c11n): add logic to default configs
* feat(percentage-c11n): add color picker to settings
* feat(percentage-c11n): change default colors
* feat(percentage-c11n): fix button text color
* feat(percentage-c11n): add labels to settings
* feat(percentage-c11n): add preview section
* feat(percentage-c11n): fix cache issues with debouncing
* feat(percentage-c11n): add width responsiveness to color picker
* feat(percentage-c11n): fix responsiveness issues
* feat(percentage-c11n): add checkbox, refactor a little
* feat(percentage-c11n): convert data type to array
* feat(percentage-c11n): refactor config states
* feat(percentage-c11n): fix defaults
* feat(percentage-c11n): add basic cell without bg
* feat(percentage-c11n): remove collapse
* feat(percentage-c11n): refactor checkStates
* feat(percentage-c11n): add grid layout
* feat(percentage-c11n): chore conventions
* feat(percentage-c11n): add default theme color to sidedrawer
* remove redundant fragment
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* fix text color in preview
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* fix: change state to derived state
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* fix: review suggestions
* fix: remove redundant change call
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* fix(percentage-c11n): remove redundant dependencies
Co-authored-by: Shams <shams.mosowi@gmail.com>
Co-authored-by: Sidney Alcantara <sidney@sidney.me>
* extend callable timeout to over 9minutes
* fix timeout value
* fix page loading with white screen while system is in dark mode
* Revert "bundle-analyzer"
This reverts commit dd214b96e4.
* fix nav items not accessible with Tab
* Percentage: don’t display if value null or undefined
* fix NavDrawer causing compile to fail
* show text field if collections array is empy
* column ids
* row ID
* fix create table showing empty dropdown for collections
* fix row not writing to db once all required fields are written
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Han Tuerker <46192266+htuerker@users.noreply.github.com>
Co-authored-by: shamsmosowi <shams.mosowi@gmail.com>
This commit is contained in:
@@ -75,6 +75,12 @@
|
|||||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap"
|
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<title>Rowy</title>
|
<title>Rowy</title>
|
||||||
|
|
||||||
<meta name="title" content="Rowy – GCP as easy as ABC" />
|
<meta name="title" content="Rowy – GCP as easy as ABC" />
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import SvgIcon, { SvgIconProps } from "@mui/material/SvgIcon";
|
|
||||||
import { mdiLeaf } from "@mdi/js";
|
|
||||||
|
|
||||||
export default function Leaf(props: SvgIconProps) {
|
|
||||||
return (
|
|
||||||
<SvgIcon {...props}>
|
|
||||||
<path d={mdiLeaf} />
|
|
||||||
</SvgIcon>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -88,6 +88,12 @@ export { LanguageMarkdownOutline as Markdown };
|
|||||||
import { TableRow } from "mdi-material-ui";
|
import { TableRow } from "mdi-material-ui";
|
||||||
export { TableRow as Row };
|
export { TableRow as Row };
|
||||||
|
|
||||||
|
import { Table } from "mdi-material-ui";
|
||||||
|
export { Table };
|
||||||
|
|
||||||
|
import { Leaf } from "mdi-material-ui";
|
||||||
|
export { Leaf };
|
||||||
|
|
||||||
export * from "./AddRow";
|
export * from "./AddRow";
|
||||||
export * from "./AddRowTop";
|
export * from "./AddRowTop";
|
||||||
export * from "./ChevronDown";
|
export * from "./ChevronDown";
|
||||||
|
|||||||
@@ -346,16 +346,6 @@ export const updateFieldAtom = atom(
|
|||||||
update[tableSettings.auditFieldUpdatedBy || "_updatedBy"] = auditValue;
|
update[tableSettings.auditFieldUpdatedBy || "_updatedBy"] = auditValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for required fields
|
|
||||||
const requiredFields = ignoreRequiredFields
|
|
||||||
? []
|
|
||||||
: tableColumnsOrdered
|
|
||||||
.filter((column) => column.config?.required)
|
|
||||||
.map((column) => column.key);
|
|
||||||
const missingRequiredFields = ignoreRequiredFields
|
|
||||||
? []
|
|
||||||
: requiredFields.filter((field) => row[field] === undefined);
|
|
||||||
|
|
||||||
// Apply field update
|
// Apply field update
|
||||||
if (!deleteField) {
|
if (!deleteField) {
|
||||||
// Check for equality. If updated value is same as current, skip update
|
// Check for equality. If updated value is same as current, skip update
|
||||||
@@ -367,6 +357,17 @@ export const updateFieldAtom = atom(
|
|||||||
_set(update, fieldName, value);
|
_set(update, fieldName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for required fields
|
||||||
|
const newRowValues = updateRowData(cloneDeep(row), update);
|
||||||
|
const requiredFields = ignoreRequiredFields
|
||||||
|
? []
|
||||||
|
: tableColumnsOrdered
|
||||||
|
.filter((column) => column.config?.required)
|
||||||
|
.map((column) => column.key);
|
||||||
|
const missingRequiredFields = ignoreRequiredFields
|
||||||
|
? []
|
||||||
|
: requiredFields.filter((field) => newRowValues[field] === undefined);
|
||||||
|
|
||||||
// If it’s a local row, update the row in rowsLocal
|
// If it’s a local row, update the row in rowsLocal
|
||||||
if (isLocalRow) {
|
if (isLocalRow) {
|
||||||
set(tableRowsLocalAtom, {
|
set(tableRowsLocalAtom, {
|
||||||
@@ -379,12 +380,11 @@ export const updateFieldAtom = atom(
|
|||||||
// If it has no missingRequiredFields, also write to db
|
// If it has no missingRequiredFields, also write to db
|
||||||
// And write entire row to handle the case where it doesn’t exist in db yet
|
// And write entire row to handle the case where it doesn’t exist in db yet
|
||||||
if (missingRequiredFields.length === 0) {
|
if (missingRequiredFields.length === 0) {
|
||||||
const rowValues = updateRowData(cloneDeep(row), update);
|
if (deleteField) unset(newRowValues, fieldName);
|
||||||
if (deleteField) unset(rowValues, fieldName);
|
|
||||||
|
|
||||||
await updateRowDb(
|
await updateRowDb(
|
||||||
row._rowy_ref.path,
|
row._rowy_ref.path,
|
||||||
omitRowyFields(rowValues),
|
omitRowyFields(newRowValues),
|
||||||
deleteField ? [fieldName] : []
|
deleteField ? [fieldName] : []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { ResizeBottomRight } from "@src/assets/icons";
|
|||||||
import useMonacoCustomizations, {
|
import useMonacoCustomizations, {
|
||||||
IUseMonacoCustomizationsProps,
|
IUseMonacoCustomizationsProps,
|
||||||
} from "./useMonacoCustomizations";
|
} from "./useMonacoCustomizations";
|
||||||
import FullScreenButton from "./FullScreenButton";
|
import FullScreenButton from "@src/components/FullScreenButton";
|
||||||
import { spreadSx } from "@src/utils/ui";
|
import { spreadSx } from "@src/utils/ui";
|
||||||
|
|
||||||
export interface ICodeEditorProps
|
export interface ICodeEditorProps
|
||||||
@@ -73,6 +73,7 @@ export default function CodeEditor({
|
|||||||
return (
|
return (
|
||||||
<TrapFocus open={fullScreen}>
|
<TrapFocus open={fullScreen}>
|
||||||
<Box
|
<Box
|
||||||
|
component="div"
|
||||||
sx={[boxSx, ...spreadSx(containerProps?.sx)]}
|
sx={[boxSx, ...spreadSx(containerProps?.sx)]}
|
||||||
style={fullScreen ? { height: "100%" } : {}}
|
style={fullScreen ? { height: "100%" } : {}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { ResizeBottomRight } from "@src/assets/icons";
|
|||||||
import useMonacoCustomizations, {
|
import useMonacoCustomizations, {
|
||||||
IUseMonacoCustomizationsProps,
|
IUseMonacoCustomizationsProps,
|
||||||
} from "./useMonacoCustomizations";
|
} from "./useMonacoCustomizations";
|
||||||
import FullScreenButton from "./FullScreenButton";
|
import FullScreenButton from "@src/components/FullScreenButton";
|
||||||
import { spreadSx } from "@src/utils/ui";
|
import { spreadSx } from "@src/utils/ui";
|
||||||
|
|
||||||
export interface IDiffEditorProps
|
export interface IDiffEditorProps
|
||||||
@@ -64,6 +64,7 @@ export default function DiffEditor({
|
|||||||
return (
|
return (
|
||||||
<TrapFocus open={fullScreen}>
|
<TrapFocus open={fullScreen}>
|
||||||
<Box
|
<Box
|
||||||
|
component="div"
|
||||||
sx={[boxSx, ...spreadSx(containerProps?.sx)]}
|
sx={[boxSx, ...spreadSx(containerProps?.sx)]}
|
||||||
style={fullScreen ? { height: "100%" } : {}}
|
style={fullScreen ? { height: "100%" } : {}}
|
||||||
>
|
>
|
||||||
|
|||||||
76
src/components/ColorPickerInput.tsx
Normal file
76
src/components/ColorPickerInput.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { useState, useRef, MutableRefObject, useLayoutEffect } from "react";
|
||||||
|
import { Box, useTheme } from "@mui/material";
|
||||||
|
|
||||||
|
import { Color, ColorPicker } from "react-color-palette";
|
||||||
|
|
||||||
|
const useResponsiveWidth = (): [
|
||||||
|
width: number,
|
||||||
|
setRef: MutableRefObject<HTMLElement | null>
|
||||||
|
] => {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const [width, setWidth] = useState(0);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (!ref || !ref.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const resizeObserver = new ResizeObserver((targets) => {
|
||||||
|
const { width: currentWidth } = targets[0].contentRect;
|
||||||
|
setWidth(currentWidth);
|
||||||
|
});
|
||||||
|
|
||||||
|
resizeObserver.observe(ref.current);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [width, ref];
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface IColorPickerProps {
|
||||||
|
value: Color;
|
||||||
|
onChangeComplete: (color: Color) => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ColorPickerInput({
|
||||||
|
value,
|
||||||
|
onChangeComplete,
|
||||||
|
disabled = false,
|
||||||
|
}: IColorPickerProps) {
|
||||||
|
const [localValue, setLocalValue] = useState(value);
|
||||||
|
const [width, setRef] = useResponsiveWidth();
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
ref={setRef}
|
||||||
|
sx={[
|
||||||
|
{
|
||||||
|
padding: theme.spacing(1.5),
|
||||||
|
paddingTop: theme.spacing(1),
|
||||||
|
transitionDuration: 0,
|
||||||
|
"& .rcp": {
|
||||||
|
border: "none",
|
||||||
|
"& .rcp-saturation": {
|
||||||
|
borderRadius: theme.spacing(0.5),
|
||||||
|
},
|
||||||
|
"& .rcp-body": {
|
||||||
|
boxSizing: "unset",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<ColorPicker
|
||||||
|
width={width}
|
||||||
|
height={150}
|
||||||
|
color={localValue}
|
||||||
|
onChange={(color) => setLocalValue(color)}
|
||||||
|
onChangeComplete={onChangeComplete}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -124,8 +124,9 @@ export default function ColumnMenu() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const localViewActions: IMenuContentsProps["menuItems"] = [
|
const localViewActions: IMenuContentsProps["menuItems"] = [
|
||||||
{ type: "subheader" },
|
{ type: "subheader", key: "subLocalView" },
|
||||||
{
|
{
|
||||||
|
key: "sortDesc",
|
||||||
label: "Sort: descending",
|
label: "Sort: descending",
|
||||||
activeLabel: "Remove sort: descending",
|
activeLabel: "Remove sort: descending",
|
||||||
icon: <ArrowDownwardIcon />,
|
icon: <ArrowDownwardIcon />,
|
||||||
@@ -139,6 +140,7 @@ export default function ColumnMenu() {
|
|||||||
disabled: column.type === FieldType.id,
|
disabled: column.type === FieldType.id,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
key: "sortAsc",
|
||||||
label: "Sort: ascending",
|
label: "Sort: ascending",
|
||||||
activeLabel: "Remove sort: ascending",
|
activeLabel: "Remove sort: ascending",
|
||||||
icon: <ArrowUpwardIcon />,
|
icon: <ArrowUpwardIcon />,
|
||||||
@@ -152,6 +154,7 @@ export default function ColumnMenu() {
|
|||||||
disabled: column.type === FieldType.id,
|
disabled: column.type === FieldType.id,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
key: "hide",
|
||||||
label: "Hide",
|
label: "Hide",
|
||||||
icon: <VisibilityIcon />,
|
icon: <VisibilityIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -168,6 +171,7 @@ export default function ColumnMenu() {
|
|||||||
disabled: !updateUserSettings,
|
disabled: !updateUserSettings,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
key: "filter",
|
||||||
label: "Filter…",
|
label: "Filter…",
|
||||||
icon: <FilterIcon />,
|
icon: <FilterIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -187,9 +191,10 @@ export default function ColumnMenu() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const configActions: IMenuContentsProps["menuItems"] = [
|
const configActions: IMenuContentsProps["menuItems"] = [
|
||||||
{ type: "subheader" },
|
{ type: "subheader", key: "subActionsConfig" },
|
||||||
{
|
{
|
||||||
label: "Lock",
|
label: "Lock",
|
||||||
|
key: "lock",
|
||||||
activeLabel: "Unlock",
|
activeLabel: "Unlock",
|
||||||
icon: <LockOpenIcon />,
|
icon: <LockOpenIcon />,
|
||||||
activeIcon: <LockIcon />,
|
activeIcon: <LockIcon />,
|
||||||
@@ -204,6 +209,7 @@ export default function ColumnMenu() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Disable resize",
|
label: "Disable resize",
|
||||||
|
key: "disableResize",
|
||||||
activeLabel: "Enable resize",
|
activeLabel: "Enable resize",
|
||||||
icon: <CellResizeIcon />,
|
icon: <CellResizeIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -217,6 +223,7 @@ export default function ColumnMenu() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Freeze",
|
label: "Freeze",
|
||||||
|
key: "freeze",
|
||||||
activeLabel: "Unfreeze",
|
activeLabel: "Unfreeze",
|
||||||
icon: <FreezeIcon />,
|
icon: <FreezeIcon />,
|
||||||
activeIcon: <UnfreezeIcon />,
|
activeIcon: <UnfreezeIcon />,
|
||||||
@@ -229,6 +236,7 @@ export default function ColumnMenu() {
|
|||||||
// { type: "subheader" },
|
// { type: "subheader" },
|
||||||
{
|
{
|
||||||
label: "Rename…",
|
label: "Rename…",
|
||||||
|
key: "rename",
|
||||||
icon: <EditIcon />,
|
icon: <EditIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
openColumnModal({ type: "name", columnKey: column.key });
|
openColumnModal({ type: "name", columnKey: column.key });
|
||||||
@@ -237,6 +245,7 @@ export default function ColumnMenu() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `Edit type: ${getFieldProp("name", column.type)}…`,
|
label: `Edit type: ${getFieldProp("name", column.type)}…`,
|
||||||
|
key: "editType",
|
||||||
// This is based on the cell type
|
// This is based on the cell type
|
||||||
icon: getFieldProp("icon", column.type),
|
icon: getFieldProp("icon", column.type),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -246,6 +255,7 @@ export default function ColumnMenu() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `Column config…`,
|
label: `Column config…`,
|
||||||
|
key: "columConfig",
|
||||||
icon: <SettingsIcon />,
|
icon: <SettingsIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
openColumnModal({ type: "config", columnKey: column.key });
|
openColumnModal({ type: "config", columnKey: column.key });
|
||||||
@@ -299,8 +309,9 @@ export default function ColumnMenu() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const derivativeActions: IMenuContentsProps["menuItems"] = [
|
const derivativeActions: IMenuContentsProps["menuItems"] = [
|
||||||
{ type: "subheader" },
|
{ type: "subheader", key: "sub-derivative" },
|
||||||
{
|
{
|
||||||
|
key: "evaluateAll",
|
||||||
label: altPress ? "Evaluate all" : "Evaluate all…",
|
label: altPress ? "Evaluate all" : "Evaluate all…",
|
||||||
icon: <EvalIcon />,
|
icon: <EvalIcon />,
|
||||||
onClick: altPress
|
onClick: altPress
|
||||||
@@ -323,9 +334,10 @@ export default function ColumnMenu() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const columnActions: IMenuContentsProps["menuItems"] = [
|
const columnActions: IMenuContentsProps["menuItems"] = [
|
||||||
{ type: "subheader" },
|
{ type: "subheader", key: "subActions" },
|
||||||
{
|
{
|
||||||
label: "Insert to the left…",
|
label: "Insert to the left…",
|
||||||
|
key: "insertLeft",
|
||||||
icon: <ColumnPlusBeforeIcon />,
|
icon: <ColumnPlusBeforeIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
openColumnModal({ type: "new", index: column.index - 1 });
|
openColumnModal({ type: "new", index: column.index - 1 });
|
||||||
@@ -334,6 +346,7 @@ export default function ColumnMenu() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Insert to the right…",
|
label: "Insert to the right…",
|
||||||
|
key: "insertRight",
|
||||||
icon: <ColumnPlusAfterIcon />,
|
icon: <ColumnPlusAfterIcon />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
openColumnModal({ type: "new", index: column.index + 1 });
|
openColumnModal({ type: "new", index: column.index + 1 });
|
||||||
@@ -342,6 +355,7 @@ export default function ColumnMenu() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `Delete column${altPress ? "" : "…"}`,
|
label: `Delete column${altPress ? "" : "…"}`,
|
||||||
|
key: "delete",
|
||||||
icon: <ColumnRemoveIcon />,
|
icon: <ColumnRemoveIcon />,
|
||||||
onClick: altPress
|
onClick: altPress
|
||||||
? handleDeleteColumn
|
? handleDeleteColumn
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { MenuItem, ListItemIcon, ListSubheader, Divider } from "@mui/material";
|
|||||||
|
|
||||||
export interface IMenuContentsProps {
|
export interface IMenuContentsProps {
|
||||||
menuItems: {
|
menuItems: {
|
||||||
|
key: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
activeLabel?: string;
|
activeLabel?: string;
|
||||||
@@ -36,6 +37,7 @@ export default function MenuContents({ menuItems }: IMenuContentsProps) {
|
|||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={index}
|
key={index}
|
||||||
|
id={`column-menu-item-${item.key}`}
|
||||||
onClick={item.onClick}
|
onClick={item.onClick}
|
||||||
color={item.color}
|
color={item.color}
|
||||||
selected={item.active}
|
selected={item.active}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { GlobalStyles } from "tss-react";
|
||||||
import { styled, useTheme } from "@mui/material";
|
import { alpha, styled, useTheme } from "@mui/material";
|
||||||
import { Editor } from "@tinymce/tinymce-react";
|
import { Editor } from "@tinymce/tinymce-react";
|
||||||
|
|
||||||
// TinyMCE so the global var exists
|
// TinyMCE so the global var exists
|
||||||
@@ -10,7 +10,9 @@ import "tinymce/themes/silver";
|
|||||||
// Toolbar icons
|
// Toolbar icons
|
||||||
import "tinymce/icons/default";
|
import "tinymce/icons/default";
|
||||||
// Editor styles
|
// Editor styles
|
||||||
import "tinymce/skins/ui/oxide/skin.min.css";
|
/* eslint import/no-webpack-loader-syntax: off */
|
||||||
|
import skinCss from "!!raw-loader!tinymce/skins/ui/oxide/skin.min.css";
|
||||||
|
import skinDarkCss from "!!raw-loader!tinymce/skins/ui/oxide-dark/skin.min.css";
|
||||||
// Content styles, including inline UI like fake cursors
|
// Content styles, including inline UI like fake cursors
|
||||||
/* eslint import/no-webpack-loader-syntax: off */
|
/* eslint import/no-webpack-loader-syntax: off */
|
||||||
import contentCss from "!!raw-loader!tinymce/skins/content/default/content.min.css";
|
import contentCss from "!!raw-loader!tinymce/skins/content/default/content.min.css";
|
||||||
@@ -55,7 +57,32 @@ const Styles = styled("div", {
|
|||||||
},
|
},
|
||||||
"& .tox-edit-area__iframe": { colorScheme: "auto" },
|
"& .tox-edit-area__iframe": { colorScheme: "auto" },
|
||||||
|
|
||||||
"& .tox-toolbar__group": { border: "none !important" },
|
"& .tox-toolbar__group": {
|
||||||
|
border: "none !important",
|
||||||
|
"& .tox-tbtn": {
|
||||||
|
"&:hover:": {
|
||||||
|
backgroundColor: "inherit",
|
||||||
|
},
|
||||||
|
"&:focus": {
|
||||||
|
backgroundColor: "inherit",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"& .tox-tbtn__select-chevron": {
|
||||||
|
transition: theme.transitions.create("transform", {
|
||||||
|
duration: theme.transitions.duration.short,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
"& .tox-tbtn--select": {
|
||||||
|
"& .tox-tbtn__select-chevron": {
|
||||||
|
transform: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"& .tox-tbtn--active": {
|
||||||
|
"& .tox-tbtn__select-chevron": {
|
||||||
|
transform: "rotate(180deg)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
"& .tox-tbtn": {
|
"& .tox-tbtn": {
|
||||||
borderRadius: theme.shape.borderRadius,
|
borderRadius: theme.shape.borderRadius,
|
||||||
@@ -118,7 +145,74 @@ export default function RichTextEditor({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Styles focus={focus} disabled={disabled}>
|
<Styles focus={focus} disabled={disabled}>
|
||||||
|
<style>{theme.palette.mode === "dark" ? skinDarkCss : skinCss}</style>
|
||||||
|
<GlobalStyles
|
||||||
|
styles={{
|
||||||
|
".tox": {
|
||||||
|
"& .tox-menu.tox-menu, &.tox-tinymce-aux .tox-toolbar__overflow.tox-toolbar__overflow":
|
||||||
|
{
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
backgroundImage:
|
||||||
|
"linear-gradient(rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.12))", // elevation 8
|
||||||
|
boxShadow: theme.shadows[8],
|
||||||
|
border: "none",
|
||||||
|
borderRadius: (theme.shape.borderRadius as number) * 2,
|
||||||
|
},
|
||||||
|
|
||||||
|
"& .tox-collection--list": {
|
||||||
|
"& .tox-collection__group.tox-collection__group": {
|
||||||
|
padding: theme.spacing(0.5),
|
||||||
|
paddingLeft: 0,
|
||||||
|
paddingRight: 0,
|
||||||
|
},
|
||||||
|
"& .tox-collection__item": {
|
||||||
|
padding: theme.spacing(0.5),
|
||||||
|
marginLeft: theme.spacing(0.5),
|
||||||
|
marginRight: theme.spacing(0.5),
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
},
|
||||||
|
|
||||||
|
"& .tox-collection__item--enabled": {
|
||||||
|
backgroundColor: theme.palette.action.hover + " !important",
|
||||||
|
position: "relative",
|
||||||
|
"&::before": {
|
||||||
|
content: '""',
|
||||||
|
display: "block",
|
||||||
|
position: "absolute",
|
||||||
|
top: theme.spacing(1),
|
||||||
|
bottom: theme.spacing(1),
|
||||||
|
left: 0,
|
||||||
|
width: theme.spacing(0.3),
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
backgroundColor: theme.palette.primary.main,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"& .tox-collection__item--active": {
|
||||||
|
backgroundColor:
|
||||||
|
alpha(
|
||||||
|
theme.palette.primary.main,
|
||||||
|
theme.palette.action.selectedOpacity
|
||||||
|
) + "!important",
|
||||||
|
},
|
||||||
|
"& .tox-collection__item-checkmark": {
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"&.tox-tinymce-aux .tox-toolbar__overflow.tox-toolbar__overflow": {
|
||||||
|
padding: theme.spacing(0.5, 0),
|
||||||
|
},
|
||||||
|
"& .tox-tbtn.tox-tbtn": {
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<Editor
|
<Editor
|
||||||
|
key={theme.palette.mode}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
init={{
|
init={{
|
||||||
skin: false,
|
skin: false,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { sortBy } from "lodash-es";
|
|||||||
|
|
||||||
import MultiSelect from "@rowy/multiselect";
|
import MultiSelect from "@rowy/multiselect";
|
||||||
import { Grid } from "@mui/material";
|
import { Grid } from "@mui/material";
|
||||||
import LeafIcon from "@src/assets/icons/Leaf";
|
import { Leaf as LeafIcon } from "@src/assets/icons";
|
||||||
|
|
||||||
import { CLOUD_RUN_REGIONS } from "@src/constants/regions";
|
import { CLOUD_RUN_REGIONS } from "@src/constants/regions";
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ export default function DraggableHeaderRenderer({
|
|||||||
return (
|
return (
|
||||||
<Grid
|
<Grid
|
||||||
key={column.key}
|
key={column.key}
|
||||||
|
id={`column-header-${column.key}`}
|
||||||
ref={(ref) => {
|
ref={(ref) => {
|
||||||
dragRef(ref);
|
dragRef(ref);
|
||||||
dropRef(ref);
|
dropRef(ref);
|
||||||
@@ -213,6 +214,7 @@ export default function DraggableHeaderRenderer({
|
|||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
aria-label={`Column settings for ${column.name as string}`}
|
aria-label={`Column settings for ${column.name as string}`}
|
||||||
|
id={`column-settings-${column.key}`}
|
||||||
color="inherit"
|
color="inherit"
|
||||||
onClick={handleOpenMenu}
|
onClick={handleOpenMenu}
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export default function TableRow(props: RowRendererProps<any>) {
|
|||||||
return (
|
return (
|
||||||
<Row
|
<Row
|
||||||
key={props.row._rowy_ref.path}
|
key={props.row._rowy_ref.path}
|
||||||
|
id={`row-${props.row._rowy_ref.path}`}
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -232,7 +232,10 @@ export default function TableSettingsDialog() {
|
|||||||
})),
|
})),
|
||||||
["section", "label"]
|
["section", "label"]
|
||||||
),
|
),
|
||||||
Array.isArray(collections) ? collections.filter((x) => x !== CONFIG) : null
|
Array.isArray(collections) &&
|
||||||
|
collections.filter((x) => x !== CONFIG).length > 0
|
||||||
|
? collections.filter((x) => x !== CONFIG)
|
||||||
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
import { Suspense, createElement } from "react";
|
import { Suspense, createElement } from "react";
|
||||||
|
import { ErrorBoundary } from "react-error-boundary";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
ListItemText,
|
ListItemText,
|
||||||
|
Divider,
|
||||||
|
ListSubheader,
|
||||||
Typography,
|
Typography,
|
||||||
TextField,
|
TextField,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
||||||
import ColumnSelect from "@src/components/Table/ColumnSelect";
|
import ColumnSelect from "@src/components/Table/ColumnSelect";
|
||||||
import FieldSkeleton from "@src/components/SideDrawer/FieldSkeleton";
|
import FieldSkeleton from "@src/components/SideDrawer/FieldSkeleton";
|
||||||
import IdFilterInput from "./IdFilterInput";
|
import IdFilterInput from "./IdFilterInput";
|
||||||
|
import { InlineErrorFallback } from "@src/components/ErrorFallback";
|
||||||
|
|
||||||
import type { useFilterInputs } from "./useFilterInputs";
|
import type { useFilterInputs } from "./useFilterInputs";
|
||||||
import { getFieldType, getFieldProp } from "@src/components/fields";
|
import { getFieldType, getFieldProp } from "@src/components/fields";
|
||||||
@@ -30,6 +35,45 @@ export default function FilterInputs({
|
|||||||
}: IFilterInputsProps) {
|
}: IFilterInputsProps) {
|
||||||
const columnType = selectedColumn ? getFieldType(selectedColumn) : null;
|
const columnType = selectedColumn ? getFieldType(selectedColumn) : null;
|
||||||
|
|
||||||
|
const operators = availableFilters?.operators ?? [];
|
||||||
|
const renderedOperatorItems = operators.map((operator) => (
|
||||||
|
<MenuItem key={operator.value} value={operator.value}>
|
||||||
|
<ListItemText style={{ flexShrink: 0 }}>{operator.label}</ListItemText>
|
||||||
|
|
||||||
|
{operator.secondaryLabel && (
|
||||||
|
<Typography
|
||||||
|
variant="inherit"
|
||||||
|
color="text.disabled"
|
||||||
|
sx={{ overflow: "hidden", textOverflow: "ellipsis", ml: 1 }}
|
||||||
|
>
|
||||||
|
{operator.secondaryLabel}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</MenuItem>
|
||||||
|
));
|
||||||
|
|
||||||
|
// Insert ListSubheader components in between groups of operators
|
||||||
|
for (let i = 0; i < operators.length; i++) {
|
||||||
|
if (!operators[i].group) continue;
|
||||||
|
|
||||||
|
if (i === 0 || operators[i - 1].group !== operators[i].group) {
|
||||||
|
renderedOperatorItems.splice(
|
||||||
|
i === 0 ? 0 : i + 1,
|
||||||
|
0,
|
||||||
|
<ListSubheader key={operators[i].group}>
|
||||||
|
{operators[i].group}
|
||||||
|
</ListSubheader>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
renderedOperatorItems.splice(
|
||||||
|
i + 1,
|
||||||
|
0,
|
||||||
|
<Divider key={`divider-${operators[i].group}`} variant="middle" />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={2} sx={{ mb: 3 }}>
|
<Grid container spacing={2} sx={{ mb: 3 }}>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
@@ -65,29 +109,13 @@ export default function FilterInputs({
|
|||||||
<MenuItem disabled value="" style={{ display: "none" }}>
|
<MenuItem disabled value="" style={{ display: "none" }}>
|
||||||
Select operator
|
Select operator
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{availableFilters?.operators.map((operator) => (
|
{renderedOperatorItems}
|
||||||
<MenuItem key={operator.value} value={operator.value}>
|
|
||||||
<ListItemText style={{ flexShrink: 0 }}>
|
|
||||||
{operator.label}
|
|
||||||
</ListItemText>
|
|
||||||
|
|
||||||
{operator.secondaryLabel && (
|
|
||||||
<Typography
|
|
||||||
variant="inherit"
|
|
||||||
color="text.disabled"
|
|
||||||
style={{ overflow: "hidden", textOverflow: "ellipsis" }}
|
|
||||||
>
|
|
||||||
{operator.secondaryLabel}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</TextField>
|
</TextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4} key={query.key + query.operator}>
|
||||||
{query.key && query.operator && (
|
{query.key && query.operator && (
|
||||||
<>
|
<ErrorBoundary FallbackComponent={InlineErrorFallback}>
|
||||||
<InputLabel
|
<InputLabel
|
||||||
variant="filled"
|
variant="filled"
|
||||||
id={`filters-label-${query.key}`}
|
id={`filters-label-${query.key}`}
|
||||||
@@ -111,10 +139,11 @@ export default function FilterInputs({
|
|||||||
setQuery((query) => ({ ...query, value }));
|
setQuery((query) => ({ ...query, value }));
|
||||||
},
|
},
|
||||||
disabled,
|
disabled,
|
||||||
|
operator: query.operator,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</ErrorBoundary>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ export default function FiltersPopover({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const formattedValue = availableFilters?.valueFormatter
|
const formattedValue = availableFilters?.valueFormatter
|
||||||
? availableFilters.valueFormatter(filter.value)
|
? availableFilters.valueFormatter(filter.value, filter.operator)
|
||||||
: filter.value;
|
: filter.value.toString();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chip
|
<Chip
|
||||||
|
|||||||
@@ -93,10 +93,9 @@ export default function ActionFab({
|
|||||||
return resp;
|
return resp;
|
||||||
};
|
};
|
||||||
const handleCallableAction = async (data: any) => {
|
const handleCallableAction = async (data: any) => {
|
||||||
const resp: any = await httpsCallable(
|
const resp: any = await httpsCallable(firebaseFunctions, callableName, {
|
||||||
firebaseFunctions,
|
timeout: 550000,
|
||||||
callableName
|
})(data);
|
||||||
)(data);
|
|
||||||
return resp.data;
|
return resp.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const CodeEditor = lazy(
|
|||||||
import("@src/components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
import("@src/components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||||
);
|
);
|
||||||
|
|
||||||
const Settings = ({ config, onChange }: ISettingsProps) => {
|
const Settings = ({ config, onChange, fieldName }: ISettingsProps) => {
|
||||||
const [projectId] = useAtom(projectIdAtom, globalScope);
|
const [projectId] = useAtom(projectIdAtom, globalScope);
|
||||||
const [roles] = useAtom(projectRolesAtom, globalScope);
|
const [roles] = useAtom(projectRolesAtom, globalScope);
|
||||||
const [settings] = useAtom(projectSettingsAtom, globalScope);
|
const [settings] = useAtom(projectSettingsAtom, globalScope);
|
||||||
@@ -77,10 +77,12 @@ const Settings = ({ config, onChange }: ISettingsProps) => {
|
|||||||
// ? ["requirements", "friction", "action", "undo", "customization"]
|
// ? ["requirements", "friction", "action", "undo", "customization"]
|
||||||
// : ["requirements", "friction", "action", "customization"];
|
// : ["requirements", "friction", "action", "customization"];
|
||||||
|
|
||||||
const columnOptions = tableColumnsOrdered.map((c) => ({
|
const columnOptions = tableColumnsOrdered
|
||||||
label: c.name,
|
.map((c) => ({
|
||||||
value: c.key,
|
label: c.name,
|
||||||
}));
|
value: c.key,
|
||||||
|
}))
|
||||||
|
.filter((c) => c.value !== fieldName);
|
||||||
|
|
||||||
const formattedParamsJson = stringify(
|
const formattedParamsJson = stringify(
|
||||||
Array.isArray(config.params) ? config.params : [],
|
Array.isArray(config.params) ? config.params : [],
|
||||||
@@ -145,6 +147,7 @@ const Settings = ({ config, onChange }: ISettingsProps) => {
|
|||||||
<Grid item xs={12} sm={6}>
|
<Grid item xs={12} sm={6}>
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
label="Required roles"
|
label="Required roles"
|
||||||
|
labelPlural="roles"
|
||||||
options={roles ?? []}
|
options={roles ?? []}
|
||||||
value={config.requiredRoles ?? []}
|
value={config.requiredRoles ?? []}
|
||||||
onChange={onChange("requiredRoles")}
|
onChange={onChange("requiredRoles")}
|
||||||
@@ -158,6 +161,7 @@ const Settings = ({ config, onChange }: ISettingsProps) => {
|
|||||||
<Grid item xs={12} sm={6}>
|
<Grid item xs={12} sm={6}>
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
label="Required fields"
|
label="Required fields"
|
||||||
|
labelPlural="fields"
|
||||||
options={columnOptions}
|
options={columnOptions}
|
||||||
value={config.requiredFields ?? []}
|
value={config.requiredFields ?? []}
|
||||||
onChange={onChange("requiredFields")}
|
onChange={onChange("requiredFields")}
|
||||||
|
|||||||
14
src/components/fields/DateTime/FilterCustomInput.tsx
Normal file
14
src/components/fields/DateTime/FilterCustomInput.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { IFilterCustomInputProps } from "@src/components/fields/types";
|
||||||
|
import DateTimeInput from "./SideDrawerField";
|
||||||
|
import DateInput from "@src/components/fields/Date/SideDrawerField";
|
||||||
|
|
||||||
|
export default function FilterCustomInput({
|
||||||
|
onChange,
|
||||||
|
operator,
|
||||||
|
...props
|
||||||
|
}: IFilterCustomInputProps) {
|
||||||
|
if (operator && operator.startsWith("date-"))
|
||||||
|
return <DateInput {...(props as any)} onChange={onChange} />;
|
||||||
|
|
||||||
|
return <DateTimeInput {...(props as any)} onChange={onChange} />;
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ import { getFieldId } from "@src/components/SideDrawer/utils";
|
|||||||
|
|
||||||
export interface IDateProps extends ISideDrawerFieldProps {}
|
export interface IDateProps extends ISideDrawerFieldProps {}
|
||||||
|
|
||||||
export default function Date_({
|
export default function DateTime({
|
||||||
column,
|
column,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { DATE_TIME_FORMAT } from "@src/constants/dates";
|
import { DATE_TIME_FORMAT, DATE_FORMAT } from "@src/constants/dates";
|
||||||
import { IFilterOperator } from "@src/components/fields/types";
|
import { IFilterOperator } from "@src/components/fields/types";
|
||||||
|
|
||||||
export const filterOperators: IFilterOperator[] = [
|
export const filterOperators: IFilterOperator[] = [
|
||||||
@@ -7,60 +7,75 @@ export const filterOperators: IFilterOperator[] = [
|
|||||||
label: "equals",
|
label: "equals",
|
||||||
secondaryLabel: "==",
|
secondaryLabel: "==",
|
||||||
value: "time-minute-equal",
|
value: "time-minute-equal",
|
||||||
|
group: "Date & Time",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "not equal to",
|
label: "not equal to",
|
||||||
secondaryLabel: "!=",
|
secondaryLabel: "!=",
|
||||||
value: "!=",
|
value: "!=",
|
||||||
|
group: "Date & Time",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "before",
|
label: "before",
|
||||||
secondaryLabel: "<",
|
secondaryLabel: "<",
|
||||||
value: "<",
|
value: "<",
|
||||||
|
group: "Date & Time",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "after",
|
label: "after",
|
||||||
secondaryLabel: ">",
|
secondaryLabel: ">",
|
||||||
value: ">",
|
value: ">",
|
||||||
|
group: "Date & Time",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "before or at",
|
label: "before or at",
|
||||||
secondaryLabel: "<=",
|
secondaryLabel: "<=",
|
||||||
value: "<=",
|
value: "<=",
|
||||||
|
group: "Date & Time",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "at or after",
|
label: "at or after",
|
||||||
secondaryLabel: ">=",
|
secondaryLabel: ">=",
|
||||||
value: ">=",
|
value: ">=",
|
||||||
|
group: "Date & Time",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "where date is is",
|
label: "where date is",
|
||||||
secondaryLabel: "date ==",
|
secondaryLabel: "date ==",
|
||||||
value: "date-equal",
|
value: "date-equal",
|
||||||
|
group: "Date",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "where date is before",
|
label: "where date is before",
|
||||||
secondaryLabel: "date <",
|
secondaryLabel: "date <",
|
||||||
value: "date-before",
|
value: "date-before",
|
||||||
|
group: "Date",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "where date is after",
|
label: "where date is after",
|
||||||
secondaryLabel: "date >",
|
secondaryLabel: "date >",
|
||||||
value: "date-after",
|
value: "date-after",
|
||||||
|
group: "Date",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "where date is before or on",
|
label: "where date is before or on",
|
||||||
secondaryLabel: "date <=",
|
secondaryLabel: "date <=",
|
||||||
value: "date-before-equal",
|
value: "date-before-equal",
|
||||||
|
group: "Date",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "where date is on or after",
|
label: "where date is on or after",
|
||||||
secondaryLabel: "date >=",
|
secondaryLabel: "date >=",
|
||||||
value: "date-after-equal",
|
value: "date-after-equal",
|
||||||
|
group: "Date",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const valueFormatter = (value: any) => {
|
export const valueFormatter = (value: any, operator: string) => {
|
||||||
if (value && value.toDate) return format(value.toDate(), DATE_TIME_FORMAT);
|
if (value && value.toDate)
|
||||||
|
return format(
|
||||||
|
value.toDate(),
|
||||||
|
operator.startsWith("date") ? DATE_FORMAT : DATE_TIME_FORMAT
|
||||||
|
);
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ const SideDrawerField = lazy(
|
|||||||
const Settings = lazy(
|
const Settings = lazy(
|
||||||
() => import("./Settings" /* webpackChunkName: "Settings-DateTime" */)
|
() => import("./Settings" /* webpackChunkName: "Settings-DateTime" */)
|
||||||
);
|
);
|
||||||
|
const FilterCustomInput = lazy(
|
||||||
|
() =>
|
||||||
|
import(
|
||||||
|
"./FilterCustomInput" /* webpackChunkName: "FilterCustomInput-DateTime" */
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
export const config: IFieldConfig = {
|
export const config: IFieldConfig = {
|
||||||
type: FieldType.dateTime,
|
type: FieldType.dateTime,
|
||||||
@@ -34,7 +40,11 @@ export const config: IFieldConfig = {
|
|||||||
TableCell: withHeavyCell(BasicCell, TableCell),
|
TableCell: withHeavyCell(BasicCell, TableCell),
|
||||||
TableEditor: NullEditor as any,
|
TableEditor: NullEditor as any,
|
||||||
SideDrawerField,
|
SideDrawerField,
|
||||||
filter: { operators: filterOperators, valueFormatter },
|
filter: {
|
||||||
|
operators: filterOperators,
|
||||||
|
valueFormatter,
|
||||||
|
customInput: FilterCustomInput,
|
||||||
|
},
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
csvImportParser: (value) => parseJSON(value).getTime(),
|
csvImportParser: (value) => parseJSON(value).getTime(),
|
||||||
csvExportFormatter: (value: any, config?: any) =>
|
csvExportFormatter: (value: any, config?: any) =>
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
import { ISettingsProps } from "@src/components/fields/types";
|
|
||||||
import MultiSelect from "@rowy/multiselect";
|
|
||||||
|
|
||||||
const languages = [
|
|
||||||
"javascript",
|
|
||||||
"typescript",
|
|
||||||
"json",
|
|
||||||
"html",
|
|
||||||
"css",
|
|
||||||
"scss",
|
|
||||||
"shell",
|
|
||||||
"yaml",
|
|
||||||
"xml",
|
|
||||||
"ruby",
|
|
||||||
"python",
|
|
||||||
"php",
|
|
||||||
"markdown",
|
|
||||||
"rust",
|
|
||||||
"csharp",
|
|
||||||
"cpp",
|
|
||||||
"c",
|
|
||||||
"java",
|
|
||||||
"go",
|
|
||||||
"plaintext",
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function Settings({ config, onChange }: ISettingsProps) {
|
|
||||||
return (
|
|
||||||
<MultiSelect
|
|
||||||
searchable
|
|
||||||
multiple={false}
|
|
||||||
options={languages}
|
|
||||||
value={config.language ?? "javascript"}
|
|
||||||
onChange={(value) => {
|
|
||||||
onChange("language")(value);
|
|
||||||
}}
|
|
||||||
label="Language"
|
|
||||||
labelPlural="languages"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -6,10 +6,6 @@ import { Markdown as MarkdownIcon } from "@src/assets/icons";
|
|||||||
import BasicCell from "./BasicCell";
|
import BasicCell from "./BasicCell";
|
||||||
import withSideDrawerEditor from "@src/components/Table/editors/withSideDrawerEditor";
|
import withSideDrawerEditor from "@src/components/Table/editors/withSideDrawerEditor";
|
||||||
|
|
||||||
const Settings = lazy(
|
|
||||||
() => import("./Settings" /* webpackChunkName: "Settings-markdown" */)
|
|
||||||
);
|
|
||||||
|
|
||||||
const SideDrawerField = lazy(
|
const SideDrawerField = lazy(
|
||||||
() =>
|
() =>
|
||||||
import(
|
import(
|
||||||
@@ -29,6 +25,5 @@ export const config: IFieldConfig = {
|
|||||||
TableCell: withBasicCell(BasicCell),
|
TableCell: withBasicCell(BasicCell),
|
||||||
TableEditor: withSideDrawerEditor(BasicCell),
|
TableEditor: withSideDrawerEditor(BasicCell),
|
||||||
SideDrawerField,
|
SideDrawerField,
|
||||||
settings: Settings,
|
|
||||||
};
|
};
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -1,41 +1,23 @@
|
|||||||
import { IBasicCellProps } from "@src/components/fields/types";
|
import { IBasicCellProps } from "@src/components/fields/types";
|
||||||
|
|
||||||
import { useTheme } from "@mui/material";
|
import { useTheme } from "@mui/material";
|
||||||
import { resultColorsScale } from "@src/utils/color";
|
|
||||||
|
|
||||||
export default function Percentage({ value }: IBasicCellProps) {
|
export default function Percentage({ value }: IBasicCellProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
if (typeof value === "number")
|
if (value === null || value === undefined) return null;
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
backgroundColor: resultColorsScale(value).toHex(),
|
|
||||||
|
|
||||||
position: "absolute",
|
const percentage = typeof value === "number" ? value : 0;
|
||||||
top: 0,
|
return (
|
||||||
right: 0,
|
<div
|
||||||
bottom: 0,
|
style={{
|
||||||
left: 0,
|
textAlign: "right",
|
||||||
opacity: 0.5,
|
color: theme.palette.text.primary,
|
||||||
|
position: "relative",
|
||||||
zIndex: 0,
|
zIndex: 1,
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
<div
|
{Math.round(percentage * 100)}%
|
||||||
style={{
|
</div>
|
||||||
textAlign: "right",
|
);
|
||||||
color: theme.palette.text.primary,
|
|
||||||
|
|
||||||
position: "relative",
|
|
||||||
zIndex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.round(value * 100)}%
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|||||||
171
src/components/fields/Percentage/Settings.tsx
Normal file
171
src/components/fields/Percentage/Settings.tsx
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Checkbox,
|
||||||
|
Grid,
|
||||||
|
InputLabel,
|
||||||
|
MenuItem,
|
||||||
|
TextField,
|
||||||
|
Typography,
|
||||||
|
useTheme,
|
||||||
|
} from "@mui/material";
|
||||||
|
import ColorPickerInput from "@src/components/ColorPickerInput";
|
||||||
|
import { ISettingsProps } from "@src/components/fields/types";
|
||||||
|
|
||||||
|
import { Color, toColor } from "react-color-palette";
|
||||||
|
import { fieldSx } from "@src/components/SideDrawer/utils";
|
||||||
|
import { resultColorsScale, defaultColors } from "@src/utils/color";
|
||||||
|
|
||||||
|
const colorLabels: { [key: string]: string } = {
|
||||||
|
0: "Start",
|
||||||
|
1: "Middle",
|
||||||
|
2: "End",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Settings({ onChange, config }: ISettingsProps) {
|
||||||
|
const colors: string[] = config.colors ?? defaultColors;
|
||||||
|
|
||||||
|
const [checkStates, setCheckStates] = useState<boolean[]>(
|
||||||
|
colors.map(Boolean)
|
||||||
|
);
|
||||||
|
|
||||||
|
const onCheckboxChange = (index: number, checked: boolean) => {
|
||||||
|
onChange("colors")(
|
||||||
|
colors.map((value: any, idx: number) =>
|
||||||
|
index === idx ? (checked ? value || defaultColors[idx] : null) : value
|
||||||
|
)
|
||||||
|
);
|
||||||
|
setCheckStates(
|
||||||
|
checkStates.map((value, idx) => (index === idx ? checked : value))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleColorChange = (index: number, color: Color): void => {
|
||||||
|
onChange("colors")(
|
||||||
|
colors.map((value, idx) => (index === idx ? color.hex : value))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Grid container>
|
||||||
|
{checkStates.map((checked: boolean, index: number) => {
|
||||||
|
const colorHex = colors[index];
|
||||||
|
return (
|
||||||
|
<Grid
|
||||||
|
xs={12}
|
||||||
|
md={4}
|
||||||
|
item
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "end",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={checked}
|
||||||
|
sx={[
|
||||||
|
fieldSx,
|
||||||
|
{
|
||||||
|
width: "auto",
|
||||||
|
boxShadow: "none",
|
||||||
|
backgroundColor: "inherit",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "inherit",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
onChange={() => onCheckboxChange(index, !checked)}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
select
|
||||||
|
label={colorLabels[index]}
|
||||||
|
value={1}
|
||||||
|
fullWidth
|
||||||
|
disabled={!checkStates[index]}
|
||||||
|
>
|
||||||
|
<MenuItem value={1} sx={{ display: "none" }}>
|
||||||
|
{checked && (
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
backgroundColor: colorHex,
|
||||||
|
width: 15,
|
||||||
|
height: 15,
|
||||||
|
mr: 1.5,
|
||||||
|
boxShadow: (theme) =>
|
||||||
|
`0 0 0 1px ${theme.palette.divider} inset`,
|
||||||
|
borderRadius: 0.5,
|
||||||
|
opacity: 0.5,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box>{colorHex}</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</MenuItem>
|
||||||
|
{colorHex && (
|
||||||
|
<div>
|
||||||
|
<ColorPickerInput
|
||||||
|
value={toColor("hex", colorHex)}
|
||||||
|
onChangeComplete={(color) =>
|
||||||
|
handleColorChange(index, color)
|
||||||
|
}
|
||||||
|
disabled={!checkStates[index]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Grid>
|
||||||
|
<Preview colors={config.colors} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Preview = ({ colors }: { colors: any }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
return (
|
||||||
|
<InputLabel>
|
||||||
|
Preview:
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1].map((value) => {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: "relative",
|
||||||
|
width: "100%",
|
||||||
|
padding: "0.5rem 0",
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
key={value}
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
inset: 0,
|
||||||
|
backgroundColor: resultColorsScale(
|
||||||
|
value,
|
||||||
|
colors,
|
||||||
|
theme.palette.background.paper
|
||||||
|
).toHex(),
|
||||||
|
opacity: 0.5,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography style={{ position: "relative", zIndex: 1 }}>
|
||||||
|
{Math.floor(value * 100)}%
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
</InputLabel>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ISideDrawerFieldProps } from "@src/components/fields/types";
|
import { ISideDrawerFieldProps } from "@src/components/fields/types";
|
||||||
|
|
||||||
import { TextField, InputAdornment, Box } from "@mui/material";
|
import { TextField, InputAdornment, Box, useTheme } from "@mui/material";
|
||||||
import { emphasize } from "@mui/material/styles";
|
|
||||||
import { resultColorsScale } from "@src/utils/color";
|
import { resultColorsScale } from "@src/utils/color";
|
||||||
import { getFieldId } from "@src/components/SideDrawer/utils";
|
import { getFieldId } from "@src/components/SideDrawer/utils";
|
||||||
|
|
||||||
@@ -12,6 +11,8 @@ export default function Percentage({
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
disabled,
|
disabled,
|
||||||
}: ISideDrawerFieldProps) {
|
}: ISideDrawerFieldProps) {
|
||||||
|
const { colors } = (column as any).config;
|
||||||
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
<TextField
|
<TextField
|
||||||
variant="filled"
|
variant="filled"
|
||||||
@@ -34,11 +35,14 @@ export default function Percentage({
|
|||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
borderRadius: 0.5,
|
borderRadius: 0.5,
|
||||||
boxShadow: (theme) =>
|
boxShadow: `0 0 0 1px ${theme.palette.divider} inset`,
|
||||||
`0 0 0 1px ${theme.palette.divider} inest`,
|
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
typeof value === "number"
|
typeof value === "number"
|
||||||
? resultColorsScale(value).toHex() + "!important"
|
? resultColorsScale(
|
||||||
|
value,
|
||||||
|
colors,
|
||||||
|
theme.palette.background.paper
|
||||||
|
).toHex() + "!important"
|
||||||
: undefined,
|
: undefined,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
41
src/components/fields/Percentage/TableCell.tsx
Normal file
41
src/components/fields/Percentage/TableCell.tsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { IHeavyCellProps } from "@src/components/fields/types";
|
||||||
|
|
||||||
|
import { useTheme } from "@mui/material";
|
||||||
|
import { resultColorsScale } from "@src/utils/color";
|
||||||
|
|
||||||
|
export default function Percentage({ column, value }: IHeavyCellProps) {
|
||||||
|
const theme = useTheme();
|
||||||
|
const { colors } = (column as any).config;
|
||||||
|
|
||||||
|
const percentage = typeof value === "number" ? value : 0;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: resultColorsScale(
|
||||||
|
percentage,
|
||||||
|
colors,
|
||||||
|
theme.palette.background.paper
|
||||||
|
).toHex(),
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
opacity: 0.5,
|
||||||
|
zIndex: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
textAlign: "right",
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
position: "relative",
|
||||||
|
zIndex: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Math.round(percentage * 100)}%
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
import { lazy } from "react";
|
import { lazy } from "react";
|
||||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||||
import withBasicCell from "@src/components/fields/_withTableCell/withBasicCell";
|
import withHeavyCell from "@src/components/fields/_withTableCell/withHeavyCell";
|
||||||
|
|
||||||
import { Percentage as PercentageIcon } from "@src/assets/icons";
|
import { Percentage as PercentageIcon } from "@src/assets/icons";
|
||||||
import BasicCell from "./BasicCell";
|
|
||||||
import TextEditor from "@src/components/Table/editors/TextEditor";
|
import TextEditor from "@src/components/Table/editors/TextEditor";
|
||||||
import { filterOperators } from "@src/components/fields/Number/Filter";
|
import { filterOperators } from "@src/components/fields/Number/Filter";
|
||||||
import BasicContextMenuActions from "@src/components/fields/_BasicCell/BasicCellContextMenuActions";
|
import BasicContextMenuActions from "@src/components/fields/_BasicCell/BasicCellContextMenuActions";
|
||||||
|
|
||||||
|
const BasicCell = lazy(
|
||||||
|
() => import("./BasicCell" /* webpackChunkName: "BasicCell-Percentage" */)
|
||||||
|
);
|
||||||
|
|
||||||
|
const TableCell = lazy(
|
||||||
|
() => import("./TableCell" /* webpackChunkName: "TableCell-Percentage" */)
|
||||||
|
);
|
||||||
|
|
||||||
const SideDrawerField = lazy(
|
const SideDrawerField = lazy(
|
||||||
() =>
|
() =>
|
||||||
import(
|
import(
|
||||||
@@ -14,6 +22,10 @@ const SideDrawerField = lazy(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const Settings = lazy(
|
||||||
|
() => import("./Settings" /* webpackChunkName: "Settings-Percentage" */)
|
||||||
|
);
|
||||||
|
|
||||||
export const config: IFieldConfig = {
|
export const config: IFieldConfig = {
|
||||||
type: FieldType.percentage,
|
type: FieldType.percentage,
|
||||||
name: "Percentage",
|
name: "Percentage",
|
||||||
@@ -22,11 +34,13 @@ export const config: IFieldConfig = {
|
|||||||
initialValue: 0,
|
initialValue: 0,
|
||||||
initializable: true,
|
initializable: true,
|
||||||
icon: <PercentageIcon />,
|
icon: <PercentageIcon />,
|
||||||
|
requireConfiguration: true,
|
||||||
description: "Percentage stored as a number between 0 and 1.",
|
description: "Percentage stored as a number between 0 and 1.",
|
||||||
contextMenuActions: BasicContextMenuActions,
|
contextMenuActions: BasicContextMenuActions,
|
||||||
TableCell: withBasicCell(BasicCell),
|
TableCell: withHeavyCell(BasicCell, TableCell),
|
||||||
TableEditor: TextEditor,
|
TableEditor: TextEditor,
|
||||||
SideDrawerField,
|
SideDrawerField,
|
||||||
|
settings: Settings,
|
||||||
filter: {
|
filter: {
|
||||||
operators: filterOperators,
|
operators: filterOperators,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ export interface IFieldConfig {
|
|||||||
settingsValidator?: (config: Record<string, any>) => Record<string, string>;
|
settingsValidator?: (config: Record<string, any>) => Record<string, string>;
|
||||||
filter?: {
|
filter?: {
|
||||||
operators: IFilterOperator[];
|
operators: IFilterOperator[];
|
||||||
customInput?: React.ComponentType<{ onChange: (value: any) => void }>;
|
customInput?: React.ComponentType<IFilterCustomInputProps>;
|
||||||
defaultValue?: any;
|
defaultValue?: any;
|
||||||
valueFormatter?: (value: any) => string;
|
valueFormatter?: (value: any, operator: TableFilter["operator"]) => string;
|
||||||
};
|
};
|
||||||
sortKey?: string;
|
sortKey?: string;
|
||||||
csvExportFormatter?: (value: any, config?: any) => string;
|
csvExportFormatter?: (value: any, config?: any) => string;
|
||||||
@@ -104,4 +104,11 @@ export interface IFilterOperator {
|
|||||||
value: TableFilter["operator"];
|
value: TableFilter["operator"];
|
||||||
label: string;
|
label: string;
|
||||||
secondaryLabel?: React.ReactNode;
|
secondaryLabel?: React.ReactNode;
|
||||||
|
group?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFilterCustomInputProps {
|
||||||
|
onChange: (value: any) => void;
|
||||||
|
operator: TableFilter["operator"];
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ export default function NavDrawer({
|
|||||||
{...({ component: "button" } as any)}
|
{...({ component: "button" } as any)}
|
||||||
style={{ textAlign: "left" }}
|
style={{ textAlign: "left" }}
|
||||||
sx={{ mb: 1 }}
|
sx={{ mb: 1 }}
|
||||||
onClick={(e) => {
|
onClick={(e: any) => {
|
||||||
if (closeDrawer) closeDrawer(e);
|
if (closeDrawer) closeDrawer(e);
|
||||||
openTableSettingsDialog({});
|
openTableSettingsDialog({});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,29 +1,45 @@
|
|||||||
import { Link, useLocation } from "react-router-dom";
|
import { Link, useLocation } from "react-router-dom";
|
||||||
import { MenuItem, MenuItemProps } from "@mui/material";
|
import { MenuItem, MenuItemProps } from "@mui/material";
|
||||||
|
import { spreadSx } from "@src/utils/ui";
|
||||||
|
|
||||||
export default function NavItem(props: MenuItemProps<typeof Link>) {
|
const linkProps = { target: "_blank", rel: "noopener noreferrer" };
|
||||||
|
|
||||||
|
export default function NavItem(
|
||||||
|
props: MenuItemProps<typeof Link | "a" | "button">
|
||||||
|
) {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
component={Link}
|
role="none"
|
||||||
selected={pathname === props.to}
|
tabIndex={0}
|
||||||
|
component={"to" in props ? Link : "href" in props ? "a" : "button"}
|
||||||
|
selected={"to" in props ? pathname === props.to : false}
|
||||||
{...props}
|
{...props}
|
||||||
sx={{
|
{...("href" in props ? linkProps : {})}
|
||||||
"& .MuiListItemText-primary": {
|
sx={[
|
||||||
typography: "button",
|
{
|
||||||
|
overflow: "hidden",
|
||||||
|
textAlign: "left",
|
||||||
color: "text.secondary",
|
color: "text.secondary",
|
||||||
},
|
|
||||||
"& .MuiListItemIcon-root": { opacity: 0.87 },
|
|
||||||
|
|
||||||
"&:hover, &.Mui-selected": {
|
"& .MuiListItemText-primary": {
|
||||||
"& .MuiListItemText-primary": { color: "text.primary" },
|
typography: "button",
|
||||||
"& .MuiSvgIcon-root": { color: "text.primary" },
|
overflow: "hidden",
|
||||||
},
|
},
|
||||||
|
"& .MuiSvgIcon-root": {
|
||||||
|
color: "inherit",
|
||||||
|
opacity: 0.87,
|
||||||
|
display: "block",
|
||||||
|
},
|
||||||
|
|
||||||
...props.sx,
|
"&:hover, &.Mui-selected": {
|
||||||
"&&::before": { left: "auto", right: 0 },
|
"& .MuiListItemText-primary": { color: "text.primary" },
|
||||||
}}
|
"& .MuiSvgIcon-root": { color: "text.primary" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...spreadSx(props.sx),
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
import { colord } from "colord";
|
import { colord } from "colord";
|
||||||
|
|
||||||
export const resultColors = {
|
export const defaultColors = ["#ED4747", "#F3C900", "#1FAD5F"];
|
||||||
No: "#ED4747",
|
|
||||||
Maybe: "#f3c900",
|
|
||||||
Yes: "#1fad5f",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const resultColorsScale = (value: number) =>
|
export const resultColorsScale = (
|
||||||
|
value: number,
|
||||||
|
colors: any = defaultColors,
|
||||||
|
defaultColor: string = "#fff"
|
||||||
|
) =>
|
||||||
value <= 0.5
|
value <= 0.5
|
||||||
? colord(resultColors.No).mix(resultColors.Maybe, value * 2)
|
? colord(colors[0] || defaultColor).mix(
|
||||||
: colord(resultColors.Maybe).mix(resultColors.Yes, (value - 0.5) * 2);
|
colors[1] || defaultColor,
|
||||||
|
value * 2
|
||||||
|
)
|
||||||
|
: colord(colors[1] || defaultColor).mix(
|
||||||
|
colors[2] || defaultColor,
|
||||||
|
(value - 0.5) * 2
|
||||||
|
);
|
||||||
|
|||||||
104
yarn.lock
104
yarn.lock
@@ -3100,7 +3100,7 @@
|
|||||||
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
|
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
|
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
|
||||||
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
|
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
|
||||||
|
|
||||||
"@protobufjs/base64@^1.1.2":
|
"@protobufjs/base64@^1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
@@ -3115,12 +3115,12 @@
|
|||||||
"@protobufjs/eventemitter@^1.1.0":
|
"@protobufjs/eventemitter@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
|
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
|
||||||
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
|
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
|
||||||
|
|
||||||
"@protobufjs/fetch@^1.1.0":
|
"@protobufjs/fetch@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
|
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
|
||||||
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
|
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@protobufjs/aspromise" "^1.1.1"
|
"@protobufjs/aspromise" "^1.1.1"
|
||||||
"@protobufjs/inquire" "^1.1.0"
|
"@protobufjs/inquire" "^1.1.0"
|
||||||
@@ -3128,27 +3128,27 @@
|
|||||||
"@protobufjs/float@^1.0.2":
|
"@protobufjs/float@^1.0.2":
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
|
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
|
||||||
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
|
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
|
||||||
|
|
||||||
"@protobufjs/inquire@^1.1.0":
|
"@protobufjs/inquire@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
|
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
|
||||||
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
|
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
|
||||||
|
|
||||||
"@protobufjs/path@^1.1.2":
|
"@protobufjs/path@^1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
|
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
|
||||||
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
|
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
|
||||||
|
|
||||||
"@protobufjs/pool@^1.1.0":
|
"@protobufjs/pool@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
|
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
|
||||||
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
|
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
|
||||||
|
|
||||||
"@protobufjs/utf8@^1.1.0":
|
"@protobufjs/utf8@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
||||||
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
|
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
||||||
|
|
||||||
"@react-dnd/asap@^4.0.0":
|
"@react-dnd/asap@^4.0.0":
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
@@ -3836,9 +3836,9 @@
|
|||||||
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
|
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
|
||||||
|
|
||||||
"@types/long@^4.0.1":
|
"@types/long@^4.0.1":
|
||||||
version "4.0.1"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
|
||||||
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
|
integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
|
||||||
|
|
||||||
"@types/mdast@^3.0.0":
|
"@types/mdast@^3.0.0":
|
||||||
version "3.0.10"
|
version "3.0.10"
|
||||||
@@ -3862,21 +3862,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
|
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
|
||||||
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
|
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0":
|
||||||
|
version "18.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
|
||||||
|
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
|
||||||
|
|
||||||
|
"@types/node@^17.0.23":
|
||||||
version "17.0.26"
|
version "17.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.26.tgz#1bbff9b23ee5a64f87b4f30c0c854b112ee2e635"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.26.tgz#1bbff9b23ee5a64f87b4f30c0c854b112ee2e635"
|
||||||
integrity sha512-z/FG/6DUO7pnze3AE3TBGIjGGKkvCcGcWINe1C7cADY8hKLJPDYpzsNE37uExQ4md5RFtTCvg+M8Mu1Enyeg2A==
|
integrity sha512-z/FG/6DUO7pnze3AE3TBGIjGGKkvCcGcWINe1C7cADY8hKLJPDYpzsNE37uExQ4md5RFtTCvg+M8Mu1Enyeg2A==
|
||||||
|
|
||||||
"@types/node@>=12.12.47", "@types/node@>=13.7.0":
|
|
||||||
version "16.4.13"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.13.tgz#7dfd9c14661edc65cccd43a29eb454174642370d"
|
|
||||||
integrity sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==
|
|
||||||
|
|
||||||
"@types/node@^17.0.23":
|
|
||||||
version "17.0.23"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
|
|
||||||
integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==
|
|
||||||
|
|
||||||
"@types/parse-json@^4.0.0":
|
"@types/parse-json@^4.0.0":
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||||
@@ -4676,11 +4671,6 @@ astral-regex@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
|
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
|
||||||
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
|
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
|
||||||
|
|
||||||
async@0.9.x:
|
|
||||||
version "0.9.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
|
|
||||||
integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
|
|
||||||
|
|
||||||
async@^2.6.2:
|
async@^2.6.2:
|
||||||
version "2.6.3"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
|
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
|
||||||
@@ -4689,9 +4679,9 @@ async@^2.6.2:
|
|||||||
lodash "^4.17.14"
|
lodash "^4.17.14"
|
||||||
|
|
||||||
async@^3.2.3:
|
async@^3.2.3:
|
||||||
version "3.2.3"
|
version "3.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
|
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
|
||||||
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
|
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
asynckit@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
@@ -5439,7 +5429,7 @@ compression@^1.7.4:
|
|||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||||
|
|
||||||
concat-stream@~1.6.0:
|
concat-stream@~1.6.0:
|
||||||
version "1.6.2"
|
version "1.6.2"
|
||||||
@@ -6215,20 +6205,13 @@ ee-first@1.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
|
||||||
|
|
||||||
ejs@^3.1.5:
|
ejs@^3.1.5, ejs@^3.1.6:
|
||||||
version "3.1.7"
|
version "3.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.7.tgz#c544d9c7f715783dd92f0bddcf73a59e6962d006"
|
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b"
|
||||||
integrity sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==
|
integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
jake "^10.8.5"
|
jake "^10.8.5"
|
||||||
|
|
||||||
ejs@^3.1.6:
|
|
||||||
version "3.1.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a"
|
|
||||||
integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==
|
|
||||||
dependencies:
|
|
||||||
jake "^10.6.1"
|
|
||||||
|
|
||||||
electron-to-chromium@^1.3.649:
|
electron-to-chromium@^1.3.649:
|
||||||
version "1.3.671"
|
version "1.3.671"
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.671.tgz#8feaed6eae42d279fa4611f58c42a5a1eb81b2a0"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.671.tgz#8feaed6eae42d279fa4611f58c42a5a1eb81b2a0"
|
||||||
@@ -6935,11 +6918,11 @@ file-selector@^0.1.12:
|
|||||||
tslib "^2.0.1"
|
tslib "^2.0.1"
|
||||||
|
|
||||||
filelist@^1.0.1:
|
filelist@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b"
|
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
|
||||||
integrity sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==
|
integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
minimatch "^3.0.4"
|
minimatch "^5.0.1"
|
||||||
|
|
||||||
filesize@^8.0.6:
|
filesize@^8.0.6:
|
||||||
version "8.0.7"
|
version "8.0.7"
|
||||||
@@ -8133,16 +8116,6 @@ istanbul-reports@^3.1.3:
|
|||||||
html-escaper "^2.0.0"
|
html-escaper "^2.0.0"
|
||||||
istanbul-lib-report "^3.0.0"
|
istanbul-lib-report "^3.0.0"
|
||||||
|
|
||||||
jake@^10.6.1:
|
|
||||||
version "10.8.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.4.tgz#f6a8b7bf90c6306f768aa82bb7b98bf4ca15e84a"
|
|
||||||
integrity sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==
|
|
||||||
dependencies:
|
|
||||||
async "0.9.x"
|
|
||||||
chalk "^4.0.2"
|
|
||||||
filelist "^1.0.1"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
|
|
||||||
jake@^10.8.5:
|
jake@^10.8.5:
|
||||||
version "10.8.5"
|
version "10.8.5"
|
||||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46"
|
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46"
|
||||||
@@ -9754,12 +9727,7 @@ minimatch@^5.0.1, minimatch@^5.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^2.0.1"
|
brace-expansion "^2.0.1"
|
||||||
|
|
||||||
minimist@^1.1.1, minimist@^1.2.5:
|
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
|
||||||
version "1.2.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
|
||||||
|
|
||||||
minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.6:
|
|
||||||
version "1.2.6"
|
version "1.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
@@ -11047,9 +11015,9 @@ property-information@^6.0.0:
|
|||||||
integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==
|
integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==
|
||||||
|
|
||||||
protobufjs@^6.10.0:
|
protobufjs@^6.10.0:
|
||||||
version "6.11.2"
|
version "6.11.3"
|
||||||
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b"
|
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74"
|
||||||
integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==
|
integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@protobufjs/aspromise" "^1.1.2"
|
"@protobufjs/aspromise" "^1.1.2"
|
||||||
"@protobufjs/base64" "^1.1.2"
|
"@protobufjs/base64" "^1.1.2"
|
||||||
@@ -12964,9 +12932,9 @@ tmp@^0.2.1:
|
|||||||
rimraf "^3.0.0"
|
rimraf "^3.0.0"
|
||||||
|
|
||||||
tmpl@1.0.x:
|
tmpl@1.0.x:
|
||||||
version "1.0.4"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
|
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
|
||||||
integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
|
integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
|
||||||
|
|
||||||
to-fast-properties@^2.0.0:
|
to-fast-properties@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user