Compare commits

..

No commits in common. "2720e09b0531de991e72e12a7f52cbb6c1651545" and "a8966730351318327cb08453ffec60fbdec0defa" have entirely different histories.

14 changed files with 26182 additions and 2256 deletions

File diff suppressed because it is too large Load Diff

25232
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"version": "0.0.0",
"license": "MIT",
"scripts": {
"build": "preact build --no-prerender",
"build": "preact build",
"serve": "sirv build --port 7123 --cors --single",
"dev": "preact watch --port 7123",
"predev": "npm run graphql",
@ -25,39 +25,38 @@
"build/*"
],
"dependencies": {
"@apollo/client": "^3.3.13",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@apollo/client": "^3.3.11",
"@fortawesome/fontawesome-svg-core": "^1.2.34",
"@fortawesome/free-solid-svg-icons": "^5.15.2",
"@fortawesome/react-fontawesome": "^0.1.14",
"@tailwindcss/postcss7-compat": "^2.0.4",
"@tailwindcss/postcss7-compat": "^2.0.3",
"@types/classnames": "^2.2.11",
"@types/ramda": "^0.27.39",
"autoprefixer": "^9.8.6",
"classnames": "^2.3.1",
"classnames": "^2.2.6",
"formik": "^2.2.6",
"graphql": "^15.5.0",
"mobx": "^6.1.8",
"mobx": "^6.1.7",
"mobx-react": "^7.1.0",
"postcss": "^7.0.35",
"preact": "^10.5.13",
"preact": "^10.3.1",
"preact-jsx-chai": "^3.0.0",
"preact-markup": "^2.1.1",
"preact-render-to-string": "^5.1.18",
"preact-render-to-string": "^5.1.4",
"preact-router": "^3.2.1",
"ramda": "^0.27.1",
"subscriptions-transport-ws": "^0.9.18",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.3"
},
"devDependencies": {
"@graphql-codegen/cli": "^1.21.3",
"@graphql-codegen/cli": "^1.21.1",
"@graphql-codegen/introspection": "^1.18.1",
"@graphql-codegen/typescript-operations": "^1.17.15",
"@graphql-codegen/typescript-react-apollo": "^2.2.3",
"@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
"@types/classnames": "^2.2.11",
"@graphql-codegen/typescript-operations": "^1.17.14",
"@graphql-codegen/typescript-react-apollo": "^2.2.1",
"@teamsupercell/typings-for-css-modules-loader": "^2.2.0",
"@types/enzyme": "^3.10.5",
"@types/jest": "^26.0.22",
"@types/ramda": "0.27.35",
"@types/jest": "^26.0.8",
"@types/webpack-env": "^1.15.1",
"@types/ws": "^7.4.1",
"@typescript-eslint/eslint-plugin": "^2.25.0",
"@typescript-eslint/parser": "^2.25.0",
"css-loader": "^3.5.3",
@ -66,7 +65,7 @@
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^3.0.0",
"husky": "^4.2.1",
"jest": "^26.2.2",

View File

@ -1 +0,0 @@
[{"timestamp":1617509072250,"files":[{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1017,"size":1102,"diff":85},{"filename":"200.html","previous":1023,"size":1108,"diff":85},{"filename":"bundle.cfced.css","previous":3513,"size":0,"diff":-3513},{"filename":"bundle.4663d.js","previous":113123,"size":0,"diff":-113123},{"filename":"bundle.7a645.css","previous":0,"size":4569,"diff":4569},{"filename":"bundle.49e2d.js","previous":0,"size":113122,"diff":113122}]},{"timestamp":1617508895910,"files":[{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1018,"size":1017,"diff":-1},{"filename":"200.html","previous":1024,"size":1023,"diff":-1},{"filename":"bundle.49cd0.css","previous":3513,"size":0,"diff":-3513},{"filename":"bundle.9466b.js","previous":113123,"size":0,"diff":-113123},{"filename":"bundle.cfced.css","previous":0,"size":3513,"diff":3513},{"filename":"bundle.4663d.js","previous":0,"size":113123,"diff":113123}]},{"timestamp":1617508710764,"files":[{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1102,"size":1018,"diff":-84},{"filename":"200.html","previous":1108,"size":1024,"diff":-84},{"filename":"bundle.7a645.css","previous":4569,"size":0,"diff":-4569},{"filename":"bundle.49e2d.js","previous":113122,"size":0,"diff":-113122},{"filename":"bundle.49cd0.css","previous":0,"size":3513,"diff":3513},{"filename":"bundle.9466b.js","previous":0,"size":113123,"diff":113123}]},{"timestamp":1617508442140,"files":[{"filename":"bundle.8730a.css","previous":440652,"size":0,"diff":-440652},{"filename":"bundle.*****.esm.js","previous":112647,"size":112647,"diff":0},{"filename":"polyfills.*****.esm.js","previous":2177,"size":2177,"diff":0},{"filename":"sw-esm.js","previous":8486,"size":8486,"diff":0},{"filename":"sw.js","previous":8482,"size":8482,"diff":0},{"filename":"bundle.7a35f.js","previous":113123,"size":0,"diff":-113123},{"filename":"polyfills.03bf6.js","previous":2175,"size":2175,"diff":0},{"filename":"index.html","previous":1101,"size":1102,"diff":1},{"filename":"200.html","previous":1107,"size":1108,"diff":1},{"filename":"bundle.7a645.css","previous":0,"size":4569,"diff":4569},{"filename":"bundle.49e2d.js","previous":0,"size":113122,"diff":113122}]},{"timestamp":1617506457357,"files":[{"filename":"bundle.8730a.css","previous":0,"size":440652,"diff":440652},{"filename":"bundle.*****.esm.js","previous":0,"size":112647,"diff":112647},{"filename":"polyfills.*****.esm.js","previous":0,"size":2177,"diff":2177},{"filename":"sw-esm.js","previous":0,"size":8486,"diff":8486},{"filename":"sw.js","previous":0,"size":8482,"diff":8482},{"filename":"bundle.7a35f.js","previous":0,"size":113123,"diff":113123},{"filename":"polyfills.03bf6.js","previous":0,"size":2175,"diff":2175},{"filename":"index.html","previous":0,"size":1101,"diff":1101},{"filename":"200.html","previous":0,"size":1107,"diff":1107}]}]

View File

@ -0,0 +1,23 @@
.component {
@apply bg-red-200;
}
.item {
@apply bg-gray-50 p-2 text-red-400 border-red-500 my-px
transition-colors
flex justify-between items-center w-32
overflow-ellipsis select-none cursor-pointer;
@apply hover:bg-red-50;
svg {
@apply hidden;
}
}
.itemActive {
@apply bg-red-400 text-white;
@apply hover:bg-red-400;
svg {
@apply inline-block;
}
}

View File

@ -0,0 +1,12 @@
// This file is automatically generated from your CSS. Any edits will be overwritten.
declare namespace BranchesListScssNamespace {
export interface IBranchesListScss {
component: string;
item: string;
itemActive: string;
}
}
declare const BranchesListScssModule: BranchesListScssNamespace.IBranchesListScss;
export = BranchesListScssModule;

View File

@ -0,0 +1,78 @@
import {
LogList,
Project,
ListLogsArgs,
ListBranchesArgs,
BranchList
} from '../../generated/graphql';
import { h } from 'preact';
import { gql, useQuery } from '@apollo/client';
import styles from './branches-list.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronRight } from '@fortawesome/free-solid-svg-icons';
import { action, makeObservable, observable } from 'mobx';
import { PropTypes, useLocalObservable, useObserver } from 'mobx-react';
const LIST_BRANCHES = gql`
query ListBranches($args: ListBranchesArgs!) {
listBranches(listBranchesArgs: $args) {
all
}
}
`;
interface Props {
project: Project;
onSelect?: (branch: string) => void;
}
class Store {
constructor() {
makeObservable(this);
}
@observable
currBranch?: string;
@action
setCurrBranch(branch?: string) {
this.currBranch = branch;
}
}
export const BranchesList = ({ project, onSelect }: Props) => {
const store = useLocalObservable(() => new Store());
const { data, loading } = useQuery<
{ listBranches: BranchList },
{ args: ListBranchesArgs }
>(LIST_BRANCHES, {
variables: { args: { projectId: project.id } }
});
const list = useObserver(() =>
data?.listBranches?.all?.map(text => {
return (
<li
key={text}
className={[
styles.item,
store.currBranch === text ? styles.itemActive : ''
].join(' ')}
onClick={() => {
store.setCurrBranch(text);
onSelect?.(text);
}}
>
{text.replace(/^.*\/(.+?)$/, '$1')}
<FontAwesomeIcon icon={faChevronRight} />
</li>
);
})
);
return (
<section className={styles.component}>
{loading ? <span>Loading...</span> : <ol>{list}</ol>}
</section>
);
};

View File

@ -5,19 +5,16 @@
@apply bg-gray-100 overflow-auto max-h-full;
}
.item {
header {
@apply relative;
@apply grid grid-cols-2 grid-rows-2;
@apply bg-white text-gray-700;
@apply py-2 px-4 my-px;
@apply hover:bg-gray-50;
}
time {
@apply col-start-1;
@apply text-sm text-gray-400;
}
:global(.commit-actions) {
@apply absolute right-0 top-0 bottom-0;
@apply justify-self-end self-center;
@apply col-start-2 row-start-1 row-span-2 justify-self-end self-center;
}
}

View File

@ -1,11 +1,14 @@
import { LogList, Pipeline, LogFields } from '../../generated/graphql';
import {
LogList,
Project,
ListLogsArgs,
Pipeline
} from '../../generated/graphql';
import { h } from 'preact';
import { gql, useQuery, useSubscription } from '@apollo/client';
import styles from './commit-log-list.scss';
import { CommitActions } from '../commit-actions/commit-actions';
import { FIND_PIPELINE } from '../pipelines/pipeline-list.constants';
import { route } from 'preact-router';
import { PipelineTaskStatus } from '../pipeline-tasks/pipeline-task-status';
const LIST_LOGS = gql`
subscription listLogsForPipeline($id: String!) {
@ -15,13 +18,6 @@ const LIST_LOGS = gql`
author_email
message
hash
tasks {
id
status
startedAt
endedAt
units
}
}
total
}
@ -45,34 +41,17 @@ export const CommitLogList = ({ pipelineId }: Props) => {
variables: { id: pipelineId }
});
const pipeline = queryResult.data?.pipeline;
const Item = ({ log }: { log: LogFields }) => (
<li className={styles.item}>
<header>
const list = data?.listLogs?.all?.map(log => {
return (
<li className={styles.item} key={log.hash}>
<h4>{log.message}</h4>
<time dateTime={log.date}>{log.date}</time>
{pipeline ? (
<CommitActions pipeline={pipeline} commit={log.hash} />
) : null}
</header>
<ol>
{log.tasks.map(task => (
<li
key={task.id}
onClick={() =>
route(
`/projects/${pipeline?.projectId}/pipelines/${pipeline?.id}/tasks/${task.id}`
)
}
>
<PipelineTaskStatus status={task.status} /> {task.startedAt}
</li>
))}
</ol>
</li>
);
const list = data?.listLogs?.all?.map(log => (
<Item log={log} key={log.hash} />
));
});
return (
<section className={styles.component}>

View File

@ -118,14 +118,10 @@ export const PipelineTaskDetails = ({ taskId }: Props) => {
{ taskId: string }
>(FIND_PIPELINE_TASK, { variables: { taskId } });
useMemo(
() =>
subscribeToMore({
document: PIPELINE_TASK_CHANGED,
variables: { taskId }
}),
[subscribeToMore, taskId]
);
});
const store = useLocalObservable(() => new Store());

View File

@ -1,8 +1,14 @@
import { h } from 'preact';
import styles from './pipeline-tasks.scss';
import { gql, useQuery } from '@apollo/client';
import { PipelineTask } from '../../generated/graphql';
import { PipelineTaskStatus } from './pipeline-task-status';
import { PipelineTask, TaskStatuses } from '../../generated/graphql';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faCheckCircle,
faClock,
faExclamationCircle,
faRunning
} from '@fortawesome/free-solid-svg-icons';
const LIST_TASKS = gql`
query ListTasks($pipelineId: String!) {
@ -49,7 +55,7 @@ export const PipelineTaskList = ({ pipelineId }: Props) => {
const Item = ({ task }: { task: PipelineTask }) => {
return (
<li key={task.id} className={styles.item}>
<PipelineTaskStatus status={task.status} />
<Status status={task.status} />
<span>{task.id}</span>
<span>{task.commit}</span>
<span>{task.startedAt}</span>
@ -62,3 +68,23 @@ const Item = ({ task }: { task: PipelineTask }) => {
</li>
);
};
const Status = ({ status }: { status: TaskStatuses }) => {
let icon;
switch (status) {
case TaskStatuses.Failed:
icon = faExclamationCircle;
break;
case TaskStatuses.Success:
icon = faCheckCircle;
break;
case TaskStatuses.Pending:
icon = faClock;
break;
case TaskStatuses.Working:
icon = faRunning;
break;
}
return <FontAwesomeIcon icon={icon} />;
};

View File

@ -1,45 +0,0 @@
import { h } from 'preact';
import { TaskStatuses } from '../../generated/graphql';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faCheckCircle,
faExclamationCircle,
faPauseCircle,
faSpinner
} from '@fortawesome/free-solid-svg-icons';
import classNames from 'classnames';
export const PipelineTaskStatus = ({ status }: { status: TaskStatuses }) => {
switch (status) {
case TaskStatuses.Working:
return (
<FontAwesomeIcon
icon={faSpinner}
className={classNames(['animate-spin', 'text-blue-500'])}
/>
);
case TaskStatuses.Failed:
return (
<FontAwesomeIcon
icon={faExclamationCircle}
className={classNames(['text-red-700'])}
/>
);
case TaskStatuses.Success:
return (
<FontAwesomeIcon
icon={faCheckCircle}
className={classNames(['text-green-500'])}
/>
);
case TaskStatuses.Pending:
return (
<FontAwesomeIcon
icon={faPauseCircle}
className={classNames(['text-yellow-500'])}
/>
);
default:
return null;
}
};

View File

@ -14,20 +14,14 @@ export type Scalars = {
DateTime: any;
};
export type CreatePipelineInput = {
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput;
export type Hello = {
__typename?: 'Hello';
message: Scalars['String'];
};
export type CreatePipelineTaskInput = {
pipelineId: Scalars['String'];
commit: Scalars['String'];
units: Array<PipelineUnits>;
};
export type CreateProjectInput = {
export type Project = {
__typename?: 'Project';
id: Scalars['ID'];
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
@ -35,10 +29,35 @@ export type CreateProjectInput = {
webHookSecret?: Maybe<Scalars['String']>;
};
export type WorkUnit = {
__typename?: 'WorkUnit';
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type Hello = {
__typename?: 'Hello';
message: Scalars['String'];
/** 流水线单元 */
export enum PipelineUnits {
Checkout = 'checkout',
InstallDependencies = 'installDependencies',
Test = 'test',
Deploy = 'deploy',
CleanUp = 'cleanUp'
}
export type WorkUnitMetadata = {
__typename?: 'WorkUnitMetadata';
version: Scalars['Float'];
units: Array<WorkUnit>;
};
export type Pipeline = {
__typename?: 'Pipeline';
id: Scalars['ID'];
project: Project;
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadata;
};
export type LogFields = {
@ -50,7 +69,6 @@ export type LogFields = {
body: Scalars['String'];
author_name: Scalars['String'];
author_email: Scalars['String'];
tasks: Array<PipelineTask>;
};
export type LogList = {
@ -60,6 +78,90 @@ export type LogList = {
latest: LogFields;
};
export type PipelineTaskLogs = {
__typename?: 'PipelineTaskLogs';
unit: PipelineUnits;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
logs: Scalars['String'];
};
/** 任务状态 */
export enum TaskStatuses {
Success = 'success',
Failed = 'failed',
Working = 'working',
Pending = 'pending'
}
export type PipelineTask = {
__typename?: 'PipelineTask';
id: Scalars['ID'];
pipeline: Pipeline;
pipelineId: Scalars['String'];
commit: Scalars['String'];
units: Array<PipelineUnits>;
logs: Array<PipelineTaskLogs>;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
};
export type PipelineTaskLogMessage = {
__typename?: 'PipelineTaskLogMessage';
unit?: Maybe<PipelineUnits>;
time: Scalars['DateTime'];
message: Scalars['String'];
};
export type WorkUnitInput = {
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type WorkUnitMetadataInput = {
version?: Maybe<Scalars['Float']>;
units: Array<WorkUnitInput>;
};
export type Query = {
__typename?: 'Query';
hello: Hello;
findProjects: Array<Project>;
findProject: Project;
listPipelines: Array<Pipeline>;
findPipeline: Pipeline;
listPipelineTaskByPipelineId: Array<PipelineTask>;
findPipelineTask: PipelineTask;
};
export type QueryFindProjectArgs = {
id: Scalars['String'];
};
export type QueryListPipelinesArgs = {
projectId?: Maybe<Scalars['String']>;
};
export type QueryFindPipelineArgs = {
id: Scalars['String'];
};
export type QueryListPipelineTaskByPipelineIdArgs = {
pipelineId: Scalars['String'];
};
export type QueryFindPipelineTaskArgs = {
id: Scalars['String'];
};
export type Mutation = {
__typename?: 'Mutation';
createProject: Project;
@ -108,58 +210,7 @@ export type MutationCreatePipelineTaskArgs = {
task: CreatePipelineTaskInput;
};
export type Pipeline = {
__typename?: 'Pipeline';
id: Scalars['ID'];
project: Project;
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadata;
};
export type PipelineTask = {
__typename?: 'PipelineTask';
id: Scalars['ID'];
pipeline: Pipeline;
pipelineId: Scalars['String'];
commit: Scalars['String'];
units: Array<PipelineUnits>;
logs: Array<PipelineTaskLogs>;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
};
export type PipelineTaskLogMessage = {
__typename?: 'PipelineTaskLogMessage';
unit?: Maybe<PipelineUnits>;
time: Scalars['DateTime'];
message: Scalars['String'];
isError: Scalars['Boolean'];
};
export type PipelineTaskLogs = {
__typename?: 'PipelineTaskLogs';
unit: PipelineUnits;
status: TaskStatuses;
startedAt?: Maybe<Scalars['DateTime']>;
endedAt?: Maybe<Scalars['DateTime']>;
logs: Scalars['String'];
};
/** 流水线单元 */
export enum PipelineUnits {
Checkout = 'checkout',
InstallDependencies = 'installDependencies',
Test = 'test',
Deploy = 'deploy',
CleanUp = 'cleanUp'
}
export type Project = {
__typename?: 'Project';
id: Scalars['ID'];
export type CreateProjectInput = {
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
@ -167,47 +218,38 @@ export type Project = {
webHookSecret?: Maybe<Scalars['String']>;
};
export type Query = {
__typename?: 'Query';
hello: Hello;
findProjects: Array<Project>;
findProject: Project;
listPipelines: Array<Pipeline>;
findPipeline: Pipeline;
listPipelineTaskByPipelineId: Array<PipelineTask>;
findPipelineTask: PipelineTask;
export type UpdateProjectInput = {
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
webUrl?: Maybe<Scalars['String']>;
webHookSecret?: Maybe<Scalars['String']>;
};
export type QueryFindProjectArgs = {
id: Scalars['String'];
export type CreatePipelineInput = {
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput;
};
export type QueryListPipelinesArgs = {
projectId?: Maybe<Scalars['String']>;
export type UpdatePipelineInput = {
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput;
};
export type QueryFindPipelineArgs = {
id: Scalars['String'];
};
export type QueryListPipelineTaskByPipelineIdArgs = {
export type CreatePipelineTaskInput = {
pipelineId: Scalars['String'];
};
export type QueryFindPipelineTaskArgs = {
id: Scalars['String'];
commit: Scalars['String'];
units: Array<PipelineUnits>;
};
export type Subscription = {
__typename?: 'Subscription';
listLogsForPipeline: LogList;
pipelineTaskLog: PipelineTaskLogMessage;
pipelineTaskChanged: PipelineTask;
};
@ -219,53 +261,3 @@ export type SubscriptionListLogsForPipelineArgs = {
export type SubscriptionPipelineTaskLogArgs = {
taskId: Scalars['String'];
};
export type SubscriptionPipelineTaskChangedArgs = {
id: Scalars['String'];
};
/** 任务状态 */
export enum TaskStatuses {
Success = 'success',
Failed = 'failed',
Working = 'working',
Pending = 'pending'
}
export type UpdatePipelineInput = {
projectId: Scalars['String'];
branch: Scalars['String'];
name: Scalars['String'];
workUnitMetadata: WorkUnitMetadataInput;
};
export type UpdateProjectInput = {
name: Scalars['String'];
comment: Scalars['String'];
sshUrl: Scalars['String'];
webUrl?: Maybe<Scalars['String']>;
webHookSecret?: Maybe<Scalars['String']>;
};
export type WorkUnit = {
__typename?: 'WorkUnit';
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type WorkUnitInput = {
type: PipelineUnits;
scripts: Array<Scalars['String']>;
};
export type WorkUnitMetadata = {
__typename?: 'WorkUnitMetadata';
version: Scalars['Float'];
units: Array<WorkUnit>;
};
export type WorkUnitMetadataInput = {
version?: Maybe<Scalars['Float']>;
units: Array<WorkUnitInput>;
};

View File

@ -1,8 +1,5 @@
module.exports = {
purge: {
enabled: true,
content: ['./src/**/*']
},
purge: [],
darkMode: 'class', // or 'media' or 'class'
theme: {
extend: {}