Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling entity level setting for sourceCapture optional settings #1326

Merged
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
25f61b0
Moving file and adding new section
travjenkins Oct 24, 2024
d5083a7
Merge branch 'main' into travjenkins/feature/incompatible-schema-enti…
travjenkins Oct 24, 2024
72d8b19
Merge remote-tracking branch 'origin/main' into travjenkins/feature/i…
travjenkins Nov 1, 2024
fea1924
Starting wiring up stuff. Going to end up sharing a lot of this code
travjenkins Nov 1, 2024
8075993
Merge branch 'main' into travjenkins/feature/incompatible-schema-enti…
travjenkins Nov 5, 2024
faea0de
Switching to new design where both settings are just switches
travjenkins Nov 7, 2024
2be4a10
Merge remote-tracking branch 'origin/main' into travjenkins/feature/i…
travjenkins Nov 12, 2024
3be6125
adding items to the store
travjenkins Nov 12, 2024
c7b33d1
Moving everything inside the chip
travjenkins Nov 13, 2024
688e424
Moving everything inside the chip as requested
travjenkins Nov 13, 2024
4dca48b
Fixing the delete button size
travjenkins Nov 13, 2024
7777ede
Adding some more space
travjenkins Nov 13, 2024
3349e4a
more spacing tweaks
travjenkins Nov 13, 2024
49055ca
tweaking spacing a bit more
travjenkins Nov 13, 2024
d8af346
final spacing tweak
travjenkins Nov 13, 2024
f45097f
more work to get the styling right
travjenkins Nov 13, 2024
a813a3d
this is so gross but works and I am out of patience
travjenkins Nov 13, 2024
e68e51c
Starting to wire up passing around the new props
travjenkins Nov 13, 2024
3dc7ff6
Making this fetch just grab the object we need
travjenkins Nov 13, 2024
8c921a0
TODO
travjenkins Nov 14, 2024
ecc9ac6
moving around and adding util functions
travjenkins Nov 14, 2024
752b262
Doing deeper compares to know when to update (so flags are updated pr…
travjenkins Nov 15, 2024
003bda8
Getting some more specific typing handled
travjenkins Nov 15, 2024
e661964
Won't need binding index because these settings are INSIDE the resource
travjenkins Nov 15, 2024
b7e583f
reducing duplication for json schema annotations
travjenkins Nov 15, 2024
954b42e
Starting to wire up if the optional settings are supported
travjenkins Nov 15, 2024
d6f7828
Moving some shared stuff out to make file smaller
travjenkins Nov 15, 2024
eaf7f57
Moving some content to lang files
travjenkins Nov 15, 2024
9635b2d
Merge remote-tracking branch 'origin/main' into travjenkins/feature/i…
travjenkins Nov 26, 2024
2e56e23
Adding support for the labels to always show
travjenkins Nov 26, 2024
9973289
Do not need to mess with opacity
travjenkins Nov 26, 2024
77c8293
Changing how we generate our AJV instance
travjenkins Nov 26, 2024
e6aa9e3
Disabling stuff so this can be merged while we wait on the new wasm
travjenkins Nov 26, 2024
cfa6e26
disabling always updating
travjenkins Nov 26, 2024
a762449
putting everything back in
travjenkins Nov 26, 2024
0727a7d
Getting the initial loading working
travjenkins Nov 27, 2024
0933a0d
Removing some of the code to handle setting on bindings as that will be
travjenkins Nov 27, 2024
a8d153d
A better way to default settings just for edit
travjenkins Nov 27, 2024
a178979
Merge branch 'main' into travjenkins/feature/incompatible-schema-enti…
travjenkins Nov 27, 2024
393e161
Being safe and checking if the form is active. Hard to open the modal
travjenkins Dec 2, 2024
4471f04
Removing an unused file from a previous approach
travjenkins Dec 2, 2024
c062aa4
cleaning up logging
travjenkins Dec 2, 2024
c449b99
Not used
travjenkins Dec 2, 2024
76683b3
pr: noting why a hack exists
travjenkins Dec 2, 2024
a52b7ea
removing TODO as this seems alright now
travjenkins Dec 2, 2024
a0fb0c7
Using the shared hook and merging the updates in
travjenkins Dec 2, 2024
1fdd888
Renaming files
travjenkins Dec 2, 2024
8349a56
not needed
travjenkins Dec 2, 2024
c96ca7a
marking todo
travjenkins Dec 2, 2024
ff5d994
marking todo
travjenkins Dec 2, 2024
4eb0b59
removing commented code
travjenkins Dec 2, 2024
b028f0b
Not needed
travjenkins Dec 2, 2024
d44619e
Merge remote-tracking branch 'origin/main' into travjenkins/feature/i…
travjenkins Dec 3, 2024
a93eedb
PR: copy and paste design bug
travjenkins Dec 4, 2024
0e3dfaf
Need to always make sure the input assume it is a boolean
travjenkins Dec 4, 2024
5235df5
Need the memo to stop extra renders
travjenkins Dec 4, 2024
b9f4c74
keeping the optional settings rendering like buttons so we can always
travjenkins Dec 4, 2024
be7d94d
This needs to get each independent part of the def because it needs
travjenkins Dec 4, 2024
a7879c7
Similar to add where it is safest to piece this together
travjenkins Dec 4, 2024
6d51ce4
Merge branch 'main' into travjenkins/feature/incompatible-schema-enti…
travjenkins Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions src/components/collection/Selector/Add/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@ import { Button, Tooltip } from '@mui/material';
import AddDialog from 'components/shared/Entity/AddDialog';
import { useEntityType } from 'context/EntityContext';
import invariableStores from 'context/Zustand/invariableStores';
import { ReactNode, useState } from 'react';
import { useState } from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import { useStore } from 'zustand';

interface Props {
selectedCollections: string[];
AddSelectedButton: ReactNode;
disabled?: boolean;
}
import { BindingsEditorAddProps } from '../types';

const DIALOG_ID = 'add-collection-search-dialog';

function BindingsEditorAdd({
AddSelectedButton,
disabled,
selectedCollections,
}: Props) {
}: BindingsEditorAddProps) {
const intl = useIntl();
const entityType = useEntityType();

Expand Down Expand Up @@ -80,7 +75,7 @@ function BindingsEditorAdd({
entity="collection"
id={DIALOG_ID}
open={open}
primaryCTA={AddSelectedButton}
PrimaryCTA={AddSelectedButton}
selectedCollections={selectedCollections}
toggle={toggleDialog}
title={itemType}
Expand Down
12 changes: 2 additions & 10 deletions src/components/collection/Selector/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
import { Box, Stack, Typography, useTheme } from '@mui/material';
import { defaultOutline } from 'context/Theme';
import { ReactNode } from 'react';
import { useIntl } from 'react-intl';
import BindingsEditorAdd from './Add';

interface Props {
selectedCollections: string[];
AddSelectedButton: ReactNode;
itemType?: string;
readOnly?: boolean;
RediscoverButton?: ReactNode;
}
import { CollectionSelectorProps } from './types';

function CollectionSelector({
readOnly = false,
itemType,
RediscoverButton,
AddSelectedButton,
selectedCollections,
}: Props) {
}: CollectionSelectorProps) {
const intl = useIntl();
const theme = useTheme();

Expand Down
16 changes: 16 additions & 0 deletions src/components/collection/Selector/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AddDialogProps } from 'components/shared/Entity/AddDialog/types';
import { ReactNode } from 'react';

export interface CollectionSelectorProps {
selectedCollections: string[];
AddSelectedButton: AddDialogProps['PrimaryCTA'];
itemType?: string;
readOnly?: boolean;
RediscoverButton?: ReactNode;
}

export interface BindingsEditorAddProps {
selectedCollections: string[];
AddSelectedButton: AddDialogProps['PrimaryCTA'];
disabled?: boolean;
}
41 changes: 41 additions & 0 deletions src/components/editor/Bindings/DeltaUpdates/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FormControl, FormControlLabel, Stack, Switch } from '@mui/material';
import { useIntl } from 'react-intl';
import { useFormStateStore_isActive } from 'stores/FormState/hooks';
import { useSourceCaptureStore } from 'stores/SourceCapture/Store';

// https://docs.estuary.dev/concepts/materialization/#delta-updates
function DeltaUpdates() {
const intl = useIntl();

const formActive = useFormStateStore_isActive();

const [deltaUpdates, setDeltaUpdates] = useSourceCaptureStore((state) => [
state.deltaUpdates,
state.setDeltaUpdates,
]);

return (
<Stack spacing={2} sx={{ maxWidth: 'fit-content' }}>
<FormControl>
<FormControlLabel
control={
<Switch
size="small"
value={deltaUpdates}
checked={deltaUpdates}
disabled={formActive}
onChange={(event, checked) => {
setDeltaUpdates(checked);
}}
/>
}
label={intl.formatMessage({
id: 'workflows.sourceCapture.optionalSettings.deltaUpdates.control',
})}
/>
</FormControl>
</Stack>
);
}

export default DeltaUpdates;
23 changes: 23 additions & 0 deletions src/components/editor/Bindings/SchemaMode/SelectorOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Stack, Typography } from '@mui/material';
import { SelectorOptionProps } from './types';

function SelectorOption({ option }: SelectorOptionProps) {
const { description, label } = option;

return (
<Stack component="span" spacing={1}>
<Typography component="span">{label}</Typography>
<Typography
component="span"
variant="caption"
sx={{
pl: 1.5,
}}
>
{description}
</Typography>
</Stack>
);
}

export default SelectorOption;
40 changes: 40 additions & 0 deletions src/components/editor/Bindings/SchemaMode/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { FormControl, FormControlLabel, Switch } from '@mui/material';
import { useIntl } from 'react-intl';
import { useFormStateStore_isActive } from 'stores/FormState/hooks';
import { useSourceCaptureStore } from 'stores/SourceCapture/Store';

function SchemaMode() {
const intl = useIntl();

const formActive = useFormStateStore_isActive();

const [targetSchema, setTargetSchema] = useSourceCaptureStore((state) => [
state.targetSchema,
state.setTargetSchema,
]);

return (
<FormControl>
<FormControlLabel
control={
<Switch
size="small"
value={targetSchema}
checked={targetSchema === 'fromSourceName'}
disabled={formActive}
onChange={(event, checked) => {
setTargetSchema(
checked ? 'fromSourceName' : 'leaveEmpty'
);
}}
/>
}
label={intl.formatMessage({
id: 'workflows.sourceCapture.optionalSettings.targetSchema.control',
})}
/>
</FormControl>
);
}

export default SchemaMode;
7 changes: 7 additions & 0 deletions src/components/editor/Bindings/SchemaMode/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getTypedAutoCompleteDefaults } from 'components/shared/AutoComplete/DefaultProps';
import { AutoCompleteOption } from './types';

export const choices = ['leaveEmpty', 'fromSourceName'] as const;

export const autoCompleteDefaultProps =
getTypedAutoCompleteDefaults<AutoCompleteOption>();
11 changes: 11 additions & 0 deletions src/components/editor/Bindings/SchemaMode/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { choices } from './shared';

export interface AutoCompleteOption {
description: string;
label: string;
val: (typeof choices)[number];
}

export interface SelectorOptionProps {
option: AutoCompleteOption;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Button } from '@mui/material';
import { AddCollectionDialogCTAProps } from 'components/shared/Entity/types';
import invariableStores from 'context/Zustand/invariableStores';

import { FormattedMessage } from 'react-intl';

import { useBinding_prefillResourceConfigs } from 'stores/Binding/hooks';
import { useSourceCaptureStore_sourceCaptureDefinition } from 'stores/SourceCapture/hooks';
import { useSourceCaptureStore } from 'stores/SourceCapture/Store';
import { useStore } from 'zustand';
import useSourceCapture from '../useSourceCapture';
Expand All @@ -17,33 +16,60 @@ function AddSourceCaptureToSpecButton({ toggle }: AddCollectionDialogCTAProps) {
}
);

const [sourceCapture, setSourceCapture] = useSourceCaptureStore((state) => [
state.sourceCapture,
const sourceCaptureDefinition =
useSourceCaptureStore_sourceCaptureDefinition();

const [setSourceCapture] = useSourceCaptureStore((state) => [
state.setSourceCapture,
]);

const updateDraft = useSourceCapture();
const { existingSourceCapture, updateDraft } = useSourceCapture();

// Binding Store
const prefillResourceConfigs = useBinding_prefillResourceConfigs();

const close = async () => {
const selectedRow = Array.from(selected).map(([_key, row]) => row)[0];
const updatedSourceCapture = selectedRow
const updatedSourceCaptureName = selectedRow
? selectedRow.catalog_name
: null;

// Only fire updates if a change happened. Since single select table can allow the user
// to deselect a row and then select it again
if (updatedSourceCapture && sourceCapture !== updatedSourceCapture) {
setSourceCapture(updatedSourceCapture);
// We need to know if the name or settings changed so that we can control
// what name is used in the call to update the source capture setting
const nameUpdated = Boolean(
updatedSourceCaptureName &&
sourceCaptureDefinition?.capture !== updatedSourceCaptureName
);
const settingsUpdated =
sourceCaptureDefinition?.deltaUpdates !==
existingSourceCapture?.deltaUpdates ||
sourceCaptureDefinition?.targetSchema !==
existingSourceCapture?.targetSchema;

if (selectedRow?.writes_to) {
prefillResourceConfigs(selectedRow.writes_to, true);
// Only update draft is something in the settings changed
if (nameUpdated || settingsUpdated) {
const updatedSourceCapture = {
...sourceCaptureDefinition,
capture: nameUpdated
? updatedSourceCaptureName
: sourceCaptureDefinition?.capture,
};

// Check the name since the optional settings may
// have changed but not the name. Also, we have
// already saved the new optional settings in the
// store so we do not need to update that here
if (nameUpdated) {
setSourceCapture(updatedSourceCapture.capture);

if (selectedRow?.writes_to) {
prefillResourceConfigs(selectedRow.writes_to, true);
}
}

await updateDraft(updatedSourceCapture);
}

toggle(false);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button } from '@mui/material';
import { AddCollectionDialogCTAProps } from 'components/shared/Entity/types';
import { useRef } from 'react';

import { FormattedMessage } from 'react-intl';
import { useMount } from 'react-use';
import {
useSourceCaptureStore_setSourceCaptureDefinition,
useSourceCaptureStore_sourceCaptureDefinition,
} from 'stores/SourceCapture/hooks';

import { SourceCaptureDef } from 'types';

function CancelSourceCaptureButton({ toggle }: AddCollectionDialogCTAProps) {
// This is here so that we can switch settings back to how they originally were.
// Since the Source Capture modal has a 'cancel' button we need to allow the user
// to change the optional settings and then click cancel and not change anything
// on their draft.
const settingsCacheHack = useRef<SourceCaptureDef | null>(null);

const sourceCaptureDefinition =
useSourceCaptureStore_sourceCaptureDefinition();
const setSourceCaptureDefinition =
useSourceCaptureStore_setSourceCaptureDefinition();

const close = async () => {
if (settingsCacheHack.current) {
if (settingsCacheHack.current.capture.length > 0) {
setSourceCaptureDefinition(settingsCacheHack.current);
} else {
setSourceCaptureDefinition(null);
}
}

toggle(false);
};

useMount(() => {
settingsCacheHack.current = sourceCaptureDefinition;
});

return (
<Button variant="contained" onClick={close}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use the contained variant for this Cancel button and not one of lesser weight?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy and paste error - it is supposed to be outlined like it is today.

<FormattedMessage id="cta.cancel" />
</Button>
);
}

export default CancelSourceCaptureButton;
Loading
Loading