Skip to content

Latest commit

 

History

History
414 lines (326 loc) · 11.2 KB

CONTRIBUTING.md

File metadata and controls

414 lines (326 loc) · 11.2 KB

Contributing

Contributions are always welcome.

Before opening a PR, please make sure that the following points apply to your changes:

  • commits messages follow the AngularJS commit message format
  • npm run lint completes without errors
  • npm run build completes without errors
  • npm run test completes without errors

Setup Development Environment

Requires NodeJS >= 18.0

First you need to clone the vue-js-cron repository. You should fork the repository if you plan to submit a pull request.

git clone https://github.com/abichinger/vue-js-cron.git
cd vue-js-cron

After you have obtained a copy of vue-js-cron you can install all it's dependencies by running:

npm install

That's all, your development environment is ready.

npm run <task>

# Build packages, demo and docs
npm run build -w=core   # Build the core package, required by other packages
npm run build           # builds all public packages
npm run build-demo      # build demo, embedded inside docs
npm run build-docs      # build documentaion using vuepress

# Start a developement server for the core package
npm run dev -w=core

# Run the development server of @vue-js-cron/light
npm run dev -w=light

# Start a development server of the documentation
cd docs && npm run dev

# Run tests
npm run test

# Have a look at package.json for more scripts

Add new localization

You can use the commit feat: add portuguese translation as a reference.

Here you can find the structure of a localization object.

Add a new UI Framework

This section will show how to add a new UI framework using PrimeVue as an example. The finished package will be called @vue-js-cron/prime.

Create the package

Scaffold the new package by running:

mkdir prime && cd prime
npm create vue@latest .

✔ Package name: @vue-js-cron/prime
✔ Add TypeScript? › Yes
✔ Add JSX Support? › No
✔ Add Vue Router for Single Page Application development? › No
✔ Add Pinia for state management? › No
✔ Add Vitest for Unit Testing? › No
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? › No

Commits:

Configure the package

Update the package.json file of @vue-js-cron/prime. Here is an overview of the changes you should make:

  • Make @vue-js-cron/core the only dependency
  • Add the UI framework to the dev dependencies

Note: Dependencies like vue will be provieded by the workspace level dependencies.

// prime/package.json
{
  "name": "@vue-js-cron/prime",
  "version": "0.0.0",
  "description": "Cron editor for PrimeVue",
  "type": "module",
  "main": "dist/prime.umd.cjs",
  "module": "dist/prime.js",
  "types": "dist/prime.d.ts",
  "repository": "https://github.com/abichinger/vue-js-cron",
  "author": "Andreas Bichinger",
  "license": "MIT",
  "private": false,
  "scripts": {
    "dev": "vite",
    "build": "run-p type-check \"build-only {@}\" --",
    "preview": "vite preview",
    "build-only": "vite build",
    "type-check": "vue-tsc --build --force"
  },
  "dependencies": {
    "@vue-js-cron/core": "5.3.0"
  },
  "devDependencies": {
    "@primevue/themes": "^4.2.1",
    "primevue": "^4.2.1"
  },
  "files": [
    "package.json",
    "dist",
    "README.md"
  ],
  "keywords": [
    "vue",
    "vue.js",
    "vue component",
    "cron",
    "cron expression",
    "cron editor",
    "PrimeVue"
  ]
}

Add the new package to the list of workspaces

--- package.json
@@ -10,7 +10,8 @@
     "element-plus",
     "ant",
     "quasar",
-    "naive-ui"
+    "naive-ui",
+    "prime"
   ],
   "private": true,
   "scripts": {

Next we are going to add some build options to the vite configuration to build the package. Note that packages like vue are declared as external, because we want to exclude these packages from the build artifacts. The dts plugin is registered to generate declaration files.

// prime/vite.config.ts

import { fileURLToPath, URL } from 'node:url'

import vue from '@vitejs/plugin-vue'
import path from 'node:path'
import { defineConfig } from 'vite'
import dts from 'vite-plugin-dts'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    dts({
      tsconfigPath: './tsconfig.app.json',
      rollupTypes: true,
      entryRoot: 'src',
    }),
  ],
  build: {
    sourcemap: true,
    lib: {
      entry: path.resolve(__dirname, 'src/index.ts'),
      name: 'CronPrime',
      formats: ['es', 'umd'],
    },
    rollupOptions: {
      external: ['vue', '@vue', 'primevue', '@primevue/themes'],
      output: {
        assetFileNames: 'prime.css',
        exports: 'named',
        globals: {
          vue: 'Vue',
          '@vue-js-cron/core': 'CronCore',
        },
      },
    },
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
})

Update the typescript configuration to generate .d.ts files.

--- b/prime/tsconfig.app.json
@@ -5,7 +5,8 @@
   "compilerOptions": {
     "composite": true,
     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
-
+    "declaration": true,
+    "declarationMap": true,
     "baseUrl": ".",
     "paths": {
       "@/*": ["./src/*"]

Add a typescript configuration for TypeDoc and add the the newly created config to the entry points of TypeDoc.

// prime/tsconfig.typedoc.json
{
  "extends": "./tsconfig.app.json",
  "include": ["dist/index.d.ts"],
}
--- a/typedoc.json
@@ -1,6 +1,6 @@
 {
     "$schema": "https://typedoc.org/schema.json",   
-    "entryPoints": ["core", "light", "ant", "element-plus", "quasar", "vuetify", "naive-ui"],
+    "entryPoints": ["core", "light", "ant", "element-plus", "quasar", "vuetify", "naive-ui", "prime"],
     "entryPointStrategy": "packages",
     "out": "typedoc",
     "plugin": ["typedoc-plugin-vue"]

Commits:

Package structure

Make sure the src directory is empty and create the following files:

.
└── src/
    ├── components/
    │   ├── cron-prime.vue
    │   └── select.vue
    ├── App.vue
    ├── index.ts
    └── main.ts

index.ts defines the public interface of the package and exports the following:

  • CronPrime - The vue component
  • cronPrimeProps - a function which returns the props of CronPrime
  • CronPrimeProps - The type of CronPrime.props
  • the default export is a vue plugin
// prime/src/index.ts

import {
  default as CronPrime,
  cronPrimeProps,
  type CronPrimeProps,
} from '@/components/cron-prime.vue'
import type { App } from 'vue'

export { CronPrime, cronPrimeProps, type CronPrimeProps }
export const CronPrimePlugin = {
  install: (app: App) => {
    app.component('CronPrime', CronPrime)
  },
}
export default CronPrimePlugin

main.ts and App.vue are used to run the development server of Vite.

// prime/src/main.ts

import PrimeVue from 'primevue/config'
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.use(PrimeVue)
app.mount('#app')
<!-- prime/src/App.vue -->

<template>
  <div id="app">
    <CronPrime v-model="value" />
  </div>
</template>

<script lang="ts" setup>
import CronPrime from '@/components/cron-prime.vue'
import { ref } from 'vue'

const value = ref('* * * * *')
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
}
</style>

cron-prime.vue contains the vue component to edit cron expressions.

<!-- prime/src/components/cron-prime.vue -->

<template>
  <span>CronPrime</span>
</template>

<script lang="ts">
import { cronCoreProps } from '@vue-js-cron/core'
import { defineComponent, type ExtractPropTypes } from 'vue'

export const cronPrimeProps = () => ({
  ...cronCoreProps(),
})

/**
 * Props of {@link CronPrime}
 *
 * See {@link @vue-js-cron/core!CronCoreProps | CronCoreProps} for a detailed description of each prop
 *
 * @interface
 */
export type CronPrimeProps = Partial<ExtractPropTypes<ReturnType<typeof cronPrimeProps>>>

export default defineComponent({
  name: 'CronPrime',
  props: cronPrimeProps(),
  // This component will be implemented in the next step
})
</script>

select.vue defines a custom select component, which is going to be used by CronPrime

<!-- prime/src/components/select.vue -->

<template>
  <span>CustomSelect</span>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'CustomSelect',
  // This component will be implemented in the next step
})
</script>

After you have created the project structure, you can run npm run dev to start the development server.

Commits:

Implement the component

CustomSelect

The select component of most UI frameworks can only display the available items in a list. That's why we need to implement a custom select component with grid support. The composable setupSelect from vue-js-cron provides the stateful logic of the select component. The function selectProps returns the props required by setupSelect.

select.vue

CronPrime

CronPrime is the cron editor component. The state of the component is defined by setupCron. The function cronCoreProps returns the props required by setupCron.

select.vue

Commits: