mirror of
https://github.com/wassname/talk.git
synced 2026-07-25 13:30:59 +08:00
[CORL-159, CORL-160] Stream Config Tab (#2219)
* feat: Implement stream configuration tab * feat: split profile & configure into separate bundles * chore: better role logic * fix+chore: add test cases, implement expectAndFail, refactor tests * chore: add some comments * chore: Update src/core/client/framework/lib/form/helpers.tsx Co-Authored-By: cvle <vinh@wikiwi.io> * feat: support new graphql mutations/schema * fix: ci fixes * fix: improvement to revision loading * fix: updated some tests * fix: adapt client to changes * fix: remove obsolote isClosed in UpdateStory * ci: increase no_output_timeout for build
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
export default function getStory(environment: Environment, id: string) {
|
||||
return environment
|
||||
.getStore()
|
||||
.getSource()
|
||||
.get(id);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
|
||||
import getStory from "./getStory";
|
||||
|
||||
export default function getStorySettings(environment: Environment, id: string) {
|
||||
const story = getStory(environment, id);
|
||||
if (!story) {
|
||||
return null;
|
||||
}
|
||||
const storySettingsRef = story.settings.__ref;
|
||||
return environment
|
||||
.getStore()
|
||||
.getSource()
|
||||
.get(storySettingsRef);
|
||||
}
|
||||
@@ -7,3 +7,5 @@ export { default as redirectOAuth2 } from "./redirectOAuth2";
|
||||
export {
|
||||
default as getParamsFromHashAndClearIt,
|
||||
} from "./getParamsFromHashAndClearIt";
|
||||
export { default as getStory } from "./getStory";
|
||||
export { default as getStorySettings } from "./getStorySettings";
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { FormApi } from "final-form";
|
||||
import { merge } from "lodash";
|
||||
import React from "react";
|
||||
|
||||
interface Props {
|
||||
form: FormApi;
|
||||
rootKey?: string;
|
||||
children: (
|
||||
params: {
|
||||
onInitValues: (data: any) => void;
|
||||
}
|
||||
) => React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormInitializer exposes `onInitValues` property as a render prop.
|
||||
* This prop can be called multiple times until `FormInitializer` will
|
||||
* run `form.initizalize` during mount.
|
||||
*
|
||||
* This is useful if you're initialization data is spread across components.
|
||||
*/
|
||||
class FormInitializer extends React.Component<Props> {
|
||||
private initialValues: any = {};
|
||||
|
||||
public componentDidMount() {
|
||||
let values = this.initialValues;
|
||||
if (this.props.rootKey) {
|
||||
values = { [this.props.rootKey]: values };
|
||||
}
|
||||
this.props.form.initialize(values);
|
||||
}
|
||||
|
||||
private handlePartialInit = (values: any) => {
|
||||
this.initialValues = merge({}, this.initialValues, values);
|
||||
};
|
||||
|
||||
public render() {
|
||||
return this.props.children({
|
||||
onInitValues: this.handlePartialInit,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default FormInitializer;
|
||||
@@ -0,0 +1,22 @@
|
||||
import { noop } from "lodash";
|
||||
import React from "react";
|
||||
|
||||
export type SubmitHook = (
|
||||
data: any,
|
||||
actions: {
|
||||
// Callback will be called after all validations has passed and
|
||||
// the submit has not been cancelled.
|
||||
onExecute: (cb: () => Promise<any>) => void;
|
||||
cancel: (errors?: Record<string, React.ReactNode>) => void;
|
||||
}
|
||||
) => Promise<any> | any;
|
||||
export type RemoveSubmitHook = () => void;
|
||||
export type AddSubmitHook = (hook: SubmitHook) => RemoveSubmitHook;
|
||||
export type SubmitHookContext = AddSubmitHook;
|
||||
|
||||
const { Provider, Consumer } = React.createContext<SubmitHookContext>(
|
||||
() => noop
|
||||
);
|
||||
|
||||
export const SubmitHookContextProvider = Provider;
|
||||
export const SubmitHookContextConsumer = Consumer;
|
||||
@@ -0,0 +1,85 @@
|
||||
import { FormApi } from "final-form";
|
||||
import React from "react";
|
||||
|
||||
import { InvalidRequestError } from "talk-framework/lib/errors";
|
||||
|
||||
import { AddSubmitHook, SubmitHook, SubmitHookContextProvider } from "./";
|
||||
|
||||
interface Props {
|
||||
onExecute: (data: any, form: FormApi) => Promise<void>;
|
||||
children: (
|
||||
params: {
|
||||
onSubmit: (settings: any, form: FormApi) => void;
|
||||
}
|
||||
) => React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* SubmitHookContainer provides the SubmitHook Context and will
|
||||
* run all hooks when calling the `onSubmit` render prop.
|
||||
* If the submit was not cancelled, `onExecute` will be called in
|
||||
* the end, e.g. to call the mutation with the final data.
|
||||
*/
|
||||
class SubmitHookContainer extends React.Component<Props> {
|
||||
private submitHooks: SubmitHook[] = [];
|
||||
|
||||
private handleSave = async (data: any, form: FormApi) => {
|
||||
let cancelled = false;
|
||||
let formErrors: Record<string, React.ReactNode> = {};
|
||||
const executeCallbacks: Array<() => Promise<any>> = [];
|
||||
const cancel = (errors: Record<string, React.ReactNode>) => {
|
||||
cancelled = true;
|
||||
formErrors = { ...errors, ...formErrors };
|
||||
};
|
||||
const onExecute = (cb: () => Promise<any>) => {
|
||||
executeCallbacks.push(cb);
|
||||
};
|
||||
try {
|
||||
// Call submit hooks, that can manipulate what
|
||||
// we send as the mutation.
|
||||
let nextData = data;
|
||||
for (const hook of this.submitHooks) {
|
||||
const result = await hook(nextData, { cancel, onExecute });
|
||||
if (result) {
|
||||
nextData = result;
|
||||
}
|
||||
}
|
||||
if (cancelled) {
|
||||
return formErrors;
|
||||
}
|
||||
|
||||
executeCallbacks.push(() => this.props.onExecute(nextData, form));
|
||||
for (const c of executeCallbacks.map(cb => cb())) {
|
||||
await c;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof InvalidRequestError) {
|
||||
return error.invalidArgs;
|
||||
}
|
||||
// tslint:disable-next-line:no-console
|
||||
console.error(error);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
private addSubmitHook: AddSubmitHook = hook => {
|
||||
this.submitHooks.push(hook);
|
||||
return () => {
|
||||
this.submitHooks = this.submitHooks.filter(h => h !== hook);
|
||||
};
|
||||
};
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<SubmitHookContextProvider value={this.addSubmitHook}>
|
||||
{this.props.children({
|
||||
onSubmit: this.handleSave,
|
||||
})}
|
||||
</SubmitHookContextProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SubmitHookContainer;
|
||||
+1
@@ -44,6 +44,7 @@ export const formatPercentage = (v: any) => {
|
||||
return Math.round(v * 100).toString();
|
||||
};
|
||||
|
||||
export const parseBool = (v: any) => Boolean(v);
|
||||
export const parseStringBool = (v: string) => v === "true";
|
||||
|
||||
export const parseNewLineDelimitedString = (v: string) => v.split("\n");
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from "./helpers";
|
||||
export * from "./SubmitHookContext";
|
||||
export { default as withSubmitHookContext } from "./withSubmitHookContext";
|
||||
export { default as SubmitHookHandler } from "./SubmitHookHandler";
|
||||
export { default as FormInitializer } from "./FormInitializer";
|
||||
@@ -0,0 +1,12 @@
|
||||
import { createContextHOC } from "talk-framework/helpers";
|
||||
import {
|
||||
SubmitHookContext,
|
||||
SubmitHookContextConsumer,
|
||||
} from "./SubmitHookContext";
|
||||
|
||||
const withSubmitHookContext = createContextHOC<SubmitHookContext>(
|
||||
"withSubmitHookContext",
|
||||
SubmitHookContextConsumer
|
||||
);
|
||||
|
||||
export default withSubmitHookContext;
|
||||
@@ -24,11 +24,7 @@ export async function commitMutationPromiseNormalized<T extends OperationBase>(
|
||||
environment: Environment,
|
||||
config: MutationPromiseConfig<T>
|
||||
): Promise<T["response"][keyof T["response"]]> {
|
||||
try {
|
||||
return await commitMutationPromise(environment, config);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
return await commitMutationPromise(environment, config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,9 +2,11 @@ import { RestClient } from "../lib/rest";
|
||||
|
||||
export interface InstallInput {
|
||||
tenant: {
|
||||
organizationName: string;
|
||||
organizationContactEmail: string;
|
||||
organizationURL: string;
|
||||
organization: {
|
||||
name: string;
|
||||
contactEmail: string;
|
||||
url: string;
|
||||
};
|
||||
domains: string[];
|
||||
};
|
||||
user: {
|
||||
|
||||
Reference in New Issue
Block a user