├── .npmignore
├── .eslintignore
├── src
├── demo
│ ├── github_logo.png
│ ├── index.js
│ ├── index.css
│ └── App.js
└── lib
│ ├── translations
│ ├── index.js
│ ├── english.js
│ └── german.js
│ ├── utils
│ ├── computeRRule
│ │ ├── toString
│ │ └── fromString
│ │ │ ├── computeStartOnDate.js
│ │ │ ├── computeEndOnDate.js
│ │ │ ├── computeWeekStartDay.js
│ │ │ ├── computeEndAfter.js
│ │ │ ├── computeDailyInterval.js
│ │ │ ├── computeHourlyInterval.js
│ │ │ ├── computeMonthlyInterval.js
│ │ │ ├── computeWeeklyInterval.js
│ │ │ ├── computeEndMode.js
│ │ │ ├── computeMonthlyMode.js
│ │ │ ├── computeYearlyMode.js
│ │ │ ├── computeMonthlyOnDay.js
│ │ │ ├── computeYearlyOnMonthday.js
│ │ │ ├── computeYearlyOnMonth.js
│ │ │ ├── computeYearlyOnTheMonth.js
│ │ │ ├── computeFrequency.js
│ │ │ ├── computeWeeklyDays.js
│ │ │ ├── computeYearlyOnTheWhich.js
│ │ │ ├── computeMonthlyOnTheWhich.js
│ │ │ ├── computeMonthlyOnTheDay.js
│ │ │ ├── computeYearlyOnTheMonthday.js
│ │ │ └── computeRRule.js
│ ├── numericalFieldHandler.js
│ ├── translateLabel.js
│ └── configureInitialState.js
│ ├── styles
│ ├── index.css
│ └── react-datetime.css
│ ├── index.js
│ ├── constants
│ └── index.js
│ └── components
│ ├── Start
│ ├── index.js
│ └── OnDate.js
│ ├── End
│ ├── After.js
│ ├── OnDate.js
│ └── index.js
│ ├── Repeat
│ ├── Daily
│ │ └── index.js
│ ├── Hourly
│ │ └── index.js
│ ├── Yearly
│ │ ├── index.js
│ │ ├── On.js
│ │ └── OnThe.js
│ ├── Monthly
│ │ ├── On.js
│ │ ├── index.js
│ │ └── OnThe.js
│ ├── Weekly
│ │ └── index.js
│ └── index.js
│ └── ReactRRuleGenerator.js
├── .babelrc
├── config
├── jest
│ ├── fileTransform.js
│ └── cssTransform.js
├── polyfills.js
├── paths.js
├── env.js
├── webpackDevServer.config.js
├── webpack.config.prod.js
├── webpack.config.dev.js
└── webpack.config.prod.demo.js
├── .gitignore
├── .eslintrc
├── public
└── index.html
├── scripts
├── test.js
├── start.js
├── build.js
└── build-demo.js
├── LICENSE
├── package.json
└── README.md
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | /src/demo/registerServiceWorker.js
2 |
--------------------------------------------------------------------------------
/src/demo/github_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/teq/react-rrule-generator/master/src/demo/github_logo.png
--------------------------------------------------------------------------------
/src/lib/translations/index.js:
--------------------------------------------------------------------------------
1 | import english from './english';
2 | import german from './german';
3 |
4 | export default { english, german };
5 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react", "es2015"],
3 | "plugins": [
4 | "transform-class-properties",
5 | "transform-object-rest-spread"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeMonthlyOn.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyOn = on => ({
2 | bymonthday: on.day,
3 | });
4 |
5 | export default computeMonthlyOn;
6 |
--------------------------------------------------------------------------------
/src/demo/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/src/lib/styles/index.css:
--------------------------------------------------------------------------------
1 | @import 'react-datetime.css';
2 |
3 | .rdt .form-control {
4 | background-color: white;
5 | }
6 |
7 | .opacity-50 {
8 | opacity: 0.5;
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/index.js:
--------------------------------------------------------------------------------
1 | import ReactRRuleGenerator from './components/ReactRRuleGenerator';
2 | import translations from './translations';
3 |
4 | export default ReactRRuleGenerator;
5 | export { translations };
6 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeDaily.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 |
3 | const computeDaily = ({ interval }) => ({
4 | freq: RRule.DAILY,
5 | interval,
6 | });
7 |
8 | export default computeDaily;
9 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeHourly.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 |
3 | const computeHourly = ({ interval }) => ({
4 | freq: RRule.HOURLY,
5 | interval,
6 | });
7 |
8 | export default computeHourly;
9 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeStartOnDate.js:
--------------------------------------------------------------------------------
1 | const computeStartOnDate = (data, rruleObj) => {
2 | if (!rruleObj.dtstart) {
3 | return data.start.onDate.date;
4 | }
5 |
6 | return rruleObj.dtstart;
7 | };
8 | export default computeStartOnDate;
9 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeYearlyOn.js:
--------------------------------------------------------------------------------
1 | import { MONTHS } from '../../../constants/index';
2 |
3 | const computeYearlyOn = on => ({
4 | bymonth: MONTHS.indexOf(on.month) + 1,
5 | bymonthday: on.day,
6 | });
7 |
8 | export default computeYearlyOn;
9 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeEndOnDate.js:
--------------------------------------------------------------------------------
1 | const computeEndOnDate = (data, rruleObj) => {
2 | if (!rruleObj.until) {
3 | return data.end.onDate.date;
4 | }
5 |
6 | return rruleObj.until;
7 | };
8 |
9 | export default computeEndOnDate;
10 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeWeekStartDay.js:
--------------------------------------------------------------------------------
1 | const computeWeekStartDay = (data, rruleObj) => {
2 | if (!rruleObj.wkst) {
3 | return data.options.weekStartsOnSunday;
4 | }
5 | return rruleObj.wkst === 6;
6 | };
7 |
8 | export default computeWeekStartDay;
9 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeEndAfter.js:
--------------------------------------------------------------------------------
1 | const computeEndAfter = (data, rruleObj) => {
2 | if (!rruleObj.count && rruleObj.count !== 0) {
3 | return data.end.after;
4 | }
5 |
6 | return rruleObj.count;
7 | };
8 |
9 | export default computeEndAfter;
10 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeDailyInterval.js:
--------------------------------------------------------------------------------
1 | const computeDailyInterval = (data, rruleObj) => {
2 | if (rruleObj.freq !== 3) {
3 | return data.repeat.daily.interval;
4 | }
5 |
6 | return rruleObj.interval;
7 | };
8 |
9 | export default computeDailyInterval;
10 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeHourlyInterval.js:
--------------------------------------------------------------------------------
1 | const computeHourlyInterval = (data, rruleObj) => {
2 | if (rruleObj.freq !== 4) {
3 | return data.repeat.daily.interval;
4 | }
5 |
6 | return rruleObj.interval;
7 | };
8 |
9 | export default computeHourlyInterval;
10 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeMonthlyInterval.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyInterval = (data, rruleObj) => {
2 | if (rruleObj.freq !== 1) {
3 | return data.repeat.monthly.interval;
4 | }
5 |
6 | return rruleObj.interval;
7 | };
8 |
9 | export default computeMonthlyInterval;
10 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeWeeklyInterval.js:
--------------------------------------------------------------------------------
1 | const computeWeeklyInterval = (data, rruleObj) => {
2 | if (rruleObj.freq !== 2) {
3 | return data.repeat.weekly.interval;
4 | }
5 |
6 | return rruleObj.interval;
7 | };
8 |
9 | export default computeWeeklyInterval;
10 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeEndMode.js:
--------------------------------------------------------------------------------
1 | const computeEndMode = (data, rruleObj) => {
2 | if (rruleObj.count || rruleObj.count === 0) {
3 | return 'After';
4 | }
5 |
6 | if (rruleObj.until) {
7 | return 'On date';
8 | }
9 |
10 | return 'Never';
11 | };
12 |
13 | export default computeEndMode;
14 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeMonthlyMode.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyMode = (data, rruleObj) => {
2 | if (rruleObj.freq !== 1) {
3 | return data.repeat.monthly.mode;
4 | }
5 |
6 | if (rruleObj.bymonthday) {
7 | return 'on';
8 | }
9 |
10 | return 'on the';
11 | };
12 |
13 | export default computeMonthlyMode;
14 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeYearlyMode.js:
--------------------------------------------------------------------------------
1 | const computeYearlyMode = (data, rruleObj) => {
2 | if (rruleObj.freq !== 0 || !rruleObj.bymonth) {
3 | return data.repeat.yearly.mode;
4 | }
5 |
6 | if (rruleObj.bymonthday) {
7 | return 'on';
8 | }
9 |
10 | return 'on the';
11 | };
12 |
13 | export default computeYearlyMode;
14 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # misc
10 | .DS_Store
11 | .env.local
12 | .env.development.local
13 | .env.test.local
14 | .env.production.local
15 |
16 | npm-debug.log*
17 | yarn-debug.log*
18 | yarn-error.log*
19 |
20 | .idea/
21 | /build/
22 | /build-demo/
23 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeEnd.js:
--------------------------------------------------------------------------------
1 | import moment from 'moment';
2 |
3 | const computeEnd = ({ mode, after, onDate: { date } }) => {
4 | const end = {};
5 |
6 | if (mode === 'After') {
7 | end.count = after;
8 | }
9 |
10 | if (mode === 'On date') {
11 | end.until = moment(date).format();
12 | }
13 |
14 | return end;
15 | };
16 |
17 | export default computeEnd;
18 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeOptions.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 |
3 | const computeOptions = ({ hideStart, weekStartsOnSunday }) => {
4 | const options = {};
5 |
6 | if (hideStart) {
7 | options.dtstart = null;
8 | }
9 |
10 | if (weekStartsOnSunday) {
11 | options.wkst = RRule.SU;
12 | }
13 |
14 | return options;
15 | };
16 |
17 | export default computeOptions;
18 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeYearly.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 |
3 | import computeYearlyOn from './computeYearlyOn';
4 | import computeYearlyOnThe from './computeYearlyOnThe';
5 |
6 | const computeYearly = ({ mode, on, onThe }) => ({
7 | freq: RRule.YEARLY,
8 | ...(mode === 'on' ? computeYearlyOn(on) : computeYearlyOnThe(onThe)),
9 | });
10 |
11 | export default computeYearly;
12 |
13 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeMonthlyOnDay.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyOnDay = (data, rruleObj) => {
2 | if (rruleObj.freq !== 1 || !rruleObj.bymonthday) {
3 | return data.repeat.monthly.on.day;
4 | }
5 |
6 | if (typeof rruleObj.bymonthday === 'number') {
7 | return rruleObj.bymonthday
8 | }
9 |
10 | return rruleObj.bymonthday[0];
11 | };
12 |
13 | export default computeMonthlyOnDay;
14 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeYearlyOnMonthday.js:
--------------------------------------------------------------------------------
1 | const computeYearlyOnMonthday = (data, rruleObj) => {
2 | if (rruleObj.freq !== 0 || !rruleObj.bymonthday) {
3 | return data.repeat.yearly.on.day;
4 | }
5 |
6 | if (typeof rruleObj.bymonthday === 'number') {
7 | return rruleObj.bymonthday
8 | }
9 |
10 | return rruleObj.bymonthday[0];
11 | };
12 |
13 | export default computeYearlyOnMonthday;
14 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeWeekly.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 | import { values } from 'lodash';
3 |
4 | const computeWeekly = ({ interval, days }) => ({
5 | freq: RRule.WEEKLY,
6 | interval,
7 | byweekday: values(days).reduce(
8 | (activeDays, isDayActive, dayIndex) =>
9 | (isDayActive ? [...activeDays, dayIndex] : activeDays),
10 | [],
11 | ),
12 | });
13 |
14 | export default computeWeekly;
15 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": [
4 | "standard",
5 | "standard-react",
6 | "airbnb"
7 | ],
8 | "plugins": [
9 | "react"
10 | ],
11 | "rules": {
12 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
13 | "no-trailing-spaces": ["error", { "skipBlankLines": true }],
14 | "max-len": [2, 120, 2],
15 | "import/no-extraneous-dependencies": 0
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React RRule Generator
8 |
9 |
10 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeMonthly.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 |
3 | import computeMonthlyOn from './computeMonthlyOn';
4 | import computeMonthlyOnThe from './computeMonthlyOnThe';
5 |
6 | const computeMonthly = ({
7 | mode,
8 | interval,
9 | on,
10 | onThe,
11 | }) => ({
12 | freq: RRule.MONTHLY,
13 | interval,
14 | ...(mode === 'on' ? computeMonthlyOn(on) : computeMonthlyOnThe(onThe)),
15 | });
16 |
17 | export default computeMonthly;
18 |
--------------------------------------------------------------------------------
/src/lib/constants/index.js:
--------------------------------------------------------------------------------
1 | export const DATE_TIME_FORMAT = 'YYYY-MM-DD';
2 |
3 | export const MONTHS = [
4 | 'Jan',
5 | 'Feb',
6 | 'Mar',
7 | 'Apr',
8 | 'May',
9 | 'Jun',
10 | 'Jul',
11 | 'Aug',
12 | 'Sep',
13 | 'Oct',
14 | 'Nov',
15 | 'Dec'
16 | ];
17 | export const DAYS = [
18 | 'Monday',
19 | 'Tuesday',
20 | 'Wednesday',
21 | 'Thursday',
22 | 'Friday',
23 | 'Saturday',
24 | 'Sunday',
25 | 'Day',
26 | 'Weekday',
27 | 'Weekend day'
28 | ];
29 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeYearlyOnMonth.js:
--------------------------------------------------------------------------------
1 | import { MONTHS } from '../../../constants/index';
2 |
3 | const computeYearlyOnMonth = (data, rruleObj) => {
4 | if (rruleObj.freq !== 0 || !rruleObj.bymonthday) {
5 | return data.repeat.yearly.on.month;
6 | }
7 |
8 | if (typeof rruleObj.bymonth === 'number') {
9 | return MONTHS[rruleObj.bymonth - 1]
10 | }
11 |
12 | return MONTHS[rruleObj.bymonth[0] - 1];
13 | };
14 |
15 | export default computeYearlyOnMonth;
16 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeYearlyOnTheMonth.js:
--------------------------------------------------------------------------------
1 | import { MONTHS } from '../../../constants/index';
2 |
3 | const computeYearlyOnTheMonth = (data, rruleObj) => {
4 | if (rruleObj.freq !== 0 || !rruleObj.byweekday) {
5 | return data.repeat.yearly.onThe.month;
6 | }
7 |
8 | if (typeof rruleObj.bymonth === 'number') {
9 | return MONTHS[rruleObj.bymonth - 1]
10 | }
11 |
12 | return MONTHS[rruleObj.bymonth[0] - 1];
13 | };
14 |
15 | export default computeYearlyOnTheMonth;
16 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeStart.js:
--------------------------------------------------------------------------------
1 | import moment from 'moment';
2 |
3 | const computeStart = ({ onDate: { date } }) => {
4 | // verify that incoming date is valid
5 | // by seeing if it can be converted into a moment object.
6 | // if not, then create a new date
7 | if (!moment.isMoment(moment(date))) {
8 | date = new Date().setMilliseconds(0);
9 | }
10 |
11 | return {
12 | dtstart: moment(date).toDate(),
13 | };
14 | };
15 |
16 | export default computeStart;
17 |
--------------------------------------------------------------------------------
/src/lib/utils/numericalFieldHandler.js:
--------------------------------------------------------------------------------
1 | import { isNaN } from 'lodash';
2 |
3 | const numericalFieldHandler = callback => (event) => {
4 | // Convert input from a string to a number
5 | const inputNumber = +event.target.value;
6 | // Check if is a number and is less than 1000
7 | if (isNaN(inputNumber) || inputNumber >= 1000) return;
8 |
9 | const editedEvent = { target: { value: inputNumber, name: event.target.name } };
10 | callback(editedEvent);
11 | };
12 |
13 | export default numericalFieldHandler;
14 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeFrequency.js:
--------------------------------------------------------------------------------
1 | const computeFrequency = (data, rruleObj) => {
2 | switch (rruleObj.freq) {
3 | case 0: {
4 | return 'Yearly';
5 | }
6 | case 1: {
7 | return 'Monthly';
8 | }
9 | case 2: {
10 | return 'Weekly';
11 | }
12 | case 3: {
13 | return 'Daily';
14 | }
15 | case 4: {
16 | return 'Hourly';
17 | }
18 | default: {
19 | return data.repeat.frequency;
20 | }
21 | }
22 | };
23 |
24 | export default computeFrequency;
25 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeWeeklyDays.js:
--------------------------------------------------------------------------------
1 | const computeWeeklyDays = (data, rruleObj) => {
2 | let weekdays = [];
3 |
4 | if (rruleObj.freq !== 2) {
5 | return data.repeat.weekly.days;
6 | }
7 |
8 | if (rruleObj.byweekday) {
9 | weekdays = rruleObj.byweekday.map(weekday => weekday.weekday);
10 | }
11 |
12 | return {
13 | mon: weekdays.includes(0),
14 | tue: weekdays.includes(1),
15 | wed: weekdays.includes(2),
16 | thu: weekdays.includes(3),
17 | fri: weekdays.includes(4),
18 | sat: weekdays.includes(5),
19 | sun: weekdays.includes(6),
20 | };
21 | };
22 |
23 | export default computeWeeklyDays;
24 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeRRule.js:
--------------------------------------------------------------------------------
1 | import RRule from 'rrule';
2 |
3 | import computeStart from './computeStart';
4 | import computeRepeat from './computeRepeat';
5 | import computeEnd from './computeEnd';
6 | import computeOptions from './computeOptions';
7 |
8 | const computeRRule = ({
9 | start,
10 | repeat,
11 | end,
12 | options,
13 | }) => {
14 | const rruleObject = {
15 | ...computeStart(start),
16 | ...computeRepeat(repeat),
17 | ...computeEnd(end),
18 | ...computeOptions(options),
19 | };
20 | const rrule = new RRule(rruleObject);
21 | return rrule.toString();
22 | };
23 |
24 | export default computeRRule;
25 |
--------------------------------------------------------------------------------
/config/polyfills.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | if (typeof Promise === 'undefined') {
4 | // Rejection tracking prevents a common issue where React gets into an
5 | // inconsistent state due to an error, but it gets swallowed by a Promise,
6 | // and the user has no idea what causes React's erratic future behavior.
7 | require('promise/lib/rejection-tracking').enable();
8 | window.Promise = require('promise/lib/es6-extensions.js');
9 | }
10 |
11 | // fetch() polyfill for making API calls.
12 | require('whatwg-fetch');
13 |
14 | // Object.assign() is commonly used with React.
15 | // It will use the native implementation if it's present and isn't buggy.
16 | Object.assign = require('object-assign');
17 |
--------------------------------------------------------------------------------
/src/lib/utils/translateLabel.js:
--------------------------------------------------------------------------------
1 | import { each, isFunction, isPlainObject, get } from 'lodash';
2 |
3 | const replacePlaceholder = (text, replacements = {}) => {
4 | each(replacements, (value, key) => {
5 | text = text.replace(`%{${key}}`, value);
6 | });
7 |
8 | return text;
9 | };
10 |
11 | const translateLabel = (translations, key, replacements = {}) => {
12 | if (isFunction(translations)) {
13 | return translations(key, replacements);
14 | } else if (isPlainObject(translations)) {
15 | return replacePlaceholder(
16 | get(translations, key, `[translation missing '${key}']`),
17 | replacements,
18 | );
19 | }
20 |
21 | return null;
22 | };
23 |
24 | export default translateLabel;
25 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeYearlyOnTheWhich.js:
--------------------------------------------------------------------------------
1 | const computeYearlyOnTheWhich = (data, rruleObj) => {
2 | if (rruleObj.freq !== 0 || !rruleObj.byweekday) {
3 | return data.repeat.yearly.onThe.which;
4 | }
5 |
6 | const bysetpos = (typeof rruleObj.bysetpos === 'number') ? rruleObj.bysetpos : rruleObj.bysetpos[0];
7 |
8 | switch (bysetpos) {
9 | case 1: {
10 | return 'First';
11 | }
12 | case 2: {
13 | return 'Second';
14 | }
15 | case 3: {
16 | return 'Third';
17 | }
18 | case 4: {
19 | return 'Fourth';
20 | }
21 | case -1: {
22 | return 'Last';
23 | }
24 | default: {
25 | return data.repeat.yearly.onThe.which;
26 | }
27 | }
28 | };
29 |
30 | export default computeYearlyOnTheWhich;
31 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeMonthlyOnTheWhich.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyOnTheWhich = (data, rruleObj) => {
2 | if (rruleObj.freq !== 1 || !rruleObj.bysetpos) {
3 | return data.repeat.monthly.onThe.which;
4 | }
5 |
6 | const bysetpos = (typeof rruleObj.bysetpos === 'number') ? rruleObj.bysetpos : rruleObj.bysetpos[0];
7 |
8 | switch (bysetpos) {
9 | case 1: {
10 | return 'First';
11 | }
12 | case 2: {
13 | return 'Second';
14 | }
15 | case 3: {
16 | return 'Third';
17 | }
18 | case 4: {
19 | return 'Fourth';
20 | }
21 | case -1: {
22 | return 'Last';
23 | }
24 | default: {
25 | return data.repeat.monthly.onThe.which;
26 | }
27 | }
28 | };
29 |
30 | export default computeMonthlyOnTheWhich;
31 |
--------------------------------------------------------------------------------
/scripts/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Do this as the first thing so that any code reading it knows the right env.
4 | process.env.BABEL_ENV = 'test';
5 | process.env.NODE_ENV = 'test';
6 | process.env.PUBLIC_URL = '';
7 |
8 | // Makes the script crash on unhandled rejections instead of silently
9 | // ignoring them. In the future, promise rejections that are not handled will
10 | // terminate the Node.js process with a non-zero exit code.
11 | process.on('unhandledRejection', err => {
12 | throw err;
13 | });
14 |
15 | // Ensure environment variables are read.
16 | require('../config/env');
17 |
18 | const jest = require('jest');
19 | const argv = process.argv.slice(2);
20 |
21 | // Watch unless on CI or in coverage mode
22 | if (!process.env.CI && argv.indexOf('--coverage') < 0) {
23 | argv.push('--watch');
24 | }
25 |
26 |
27 | jest.run(argv);
28 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeRepeat.js:
--------------------------------------------------------------------------------
1 | import computeYearly from './computeYearly';
2 | import computeMonthly from './computeMonthly';
3 | import computeWeekly from './computeWeekly';
4 | import computeDaily from './computeDaily';
5 | import computeHourly from './computeHourly';
6 |
7 | const computeRepeat = ({
8 | frequency,
9 | yearly,
10 | monthly,
11 | weekly,
12 | daily,
13 | hourly,
14 | }) => {
15 | switch (frequency) {
16 | case 'Yearly': {
17 | return computeYearly(yearly);
18 | }
19 | case 'Monthly': {
20 | return computeMonthly(monthly);
21 | }
22 | case 'Weekly': {
23 | return computeWeekly(weekly);
24 | }
25 | case 'Daily': {
26 | return computeDaily(daily);
27 | }
28 | case 'Hourly': {
29 | return computeHourly(hourly);
30 | }
31 | default:
32 | return {};
33 | }
34 | };
35 |
36 | export default computeRepeat;
37 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeMonthlyOnTheDay.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyOnTheDay = (data, rruleObj) => {
2 | if (rruleObj.freq !== 1 || !rruleObj.byweekday) {
3 | return data.repeat.monthly.onThe.day;
4 | }
5 |
6 | const weekdays = rruleObj.byweekday.map(weekday => weekday.weekday).join(',');
7 |
8 | switch (weekdays) {
9 | case '0': {
10 | return 'Monday';
11 | }
12 | case '1': {
13 | return 'Tuesday';
14 | }
15 | case '2': {
16 | return 'Wednesday';
17 | }
18 | case '3': {
19 | return 'Thursday';
20 | }
21 | case '4': {
22 | return 'Friday';
23 | }
24 | case '5': {
25 | return 'Saturday';
26 | }
27 | case '6': {
28 | return 'Sunday';
29 | }
30 | case '0,1,2,3,4,5,6': {
31 | return 'Day';
32 | }
33 | case '0,1,2,3,4': {
34 | return 'Weekday';
35 | }
36 | case '5,6': {
37 | return 'Weekend day';
38 | }
39 | default: {
40 | return data.repeat.monthly.onThe.day;
41 | }
42 | }
43 | };
44 |
45 | export default computeMonthlyOnTheDay;
46 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/fromString/computeYearlyOnTheMonthday.js:
--------------------------------------------------------------------------------
1 | const computeYearlyOnTheMonthday = (data, rruleObj) => {
2 | if (rruleObj.freq !== 0 || !rruleObj.byweekday) {
3 | return data.repeat.yearly.onThe.day;
4 | }
5 |
6 | const weekdays = rruleObj.byweekday.map(weekday => weekday.weekday).join(',');
7 |
8 | switch (weekdays) {
9 | case '0': {
10 | return 'Monday';
11 | }
12 | case '1': {
13 | return 'Tuesday';
14 | }
15 | case '2': {
16 | return 'Wednesday';
17 | }
18 | case '3': {
19 | return 'Thursday';
20 | }
21 | case '4': {
22 | return 'Friday';
23 | }
24 | case '5': {
25 | return 'Saturday';
26 | }
27 | case '6': {
28 | return 'Sunday';
29 | }
30 | case '0,1,2,3,4,5,6': {
31 | return 'Day';
32 | }
33 | case '0,1,2,3,4': {
34 | return 'Weekday';
35 | }
36 | case '5,6': {
37 | return 'Weekend day';
38 | }
39 | default: {
40 | return data.repeat.yearly.onThe.day;
41 | }
42 | }
43 | };
44 |
45 | export default computeYearlyOnTheMonthday;
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Filip Duczyminski
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/lib/components/Start/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import StartOnDate from './OnDate';
4 |
5 | import translateLabel from '../../utils/translateLabel';
6 |
7 | const Start = ({
8 | id,
9 | start: {
10 | onDate,
11 | },
12 | handleChange,
13 | translations
14 | }) => (
15 |
16 |
17 |
18 |
26 |
27 |
28 |
29 |
30 | );
31 |
32 | Start.propTypes = {
33 | id: PropTypes.string.isRequired,
34 | start: PropTypes.shape({
35 | onDate: PropTypes.object.isRequired,
36 | }).isRequired,
37 | handleChange: PropTypes.func.isRequired,
38 | translations: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
39 | };
40 |
41 | export default Start;
42 |
--------------------------------------------------------------------------------
/src/lib/components/End/After.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import numericalFieldHandler from '../../utils/numericalFieldHandler';
4 | import translateLabel from '../../utils/translateLabel';
5 |
6 | const EndAfter = ({
7 | id,
8 | after,
9 | handleChange,
10 | translations
11 | }) => (
12 |
13 |
14 |
15 |
23 |
24 |
25 | {translateLabel(translations, 'end.executions')}
26 |
27 |
28 |
29 | );
30 |
31 | EndAfter.propTypes = {
32 | id: PropTypes.string.isRequired,
33 | after: PropTypes.number.isRequired,
34 | handleChange: PropTypes.func.isRequired,
35 | translations: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
36 | };
37 |
38 | export default EndAfter;
39 |
--------------------------------------------------------------------------------
/src/lib/components/Repeat/Daily/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import numericalFieldHandler from '../../../utils/numericalFieldHandler';
4 | import translateLabel from '../../../utils/translateLabel';
5 |
6 | const RepeatDaily = ({
7 | id,
8 | daily: {
9 | interval,
10 | },
11 | handleChange,
12 | translations
13 | }) => (
14 |
15 |
16 | {translateLabel(translations, 'repeat.daily.every')}
17 |
18 |
19 |
27 |
28 |
29 | {translateLabel(translations, 'repeat.daily.days')}
30 |
31 |
32 |
33 | );
34 | RepeatDaily.propTypes = {
35 | id: PropTypes.string.isRequired,
36 | daily: PropTypes.shape({
37 | interval: PropTypes.number.isRequired,
38 | }).isRequired,
39 | handleChange: PropTypes.func.isRequired,
40 | translations: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
41 | };
42 |
43 | export default RepeatDaily;
44 |
--------------------------------------------------------------------------------
/src/lib/components/Repeat/Hourly/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import numericalFieldHandler from '../../../utils/numericalFieldHandler';
4 | import translateLabel from '../../../utils/translateLabel';
5 |
6 | const RepeatHourly = ({
7 | id,
8 | hourly: {
9 | interval,
10 | },
11 | handleChange,
12 | translations
13 | }) => (
14 |
15 |
16 | {translateLabel(translations, 'repeat.hourly.every')}
17 |
18 |
19 |
27 |
28 |
29 | {translateLabel(translations, 'repeat.hourly.hours')}
30 |
31 |
32 | );
33 | RepeatHourly.propTypes = {
34 | id: PropTypes.string.isRequired,
35 | hourly: PropTypes.shape({
36 | interval: PropTypes.number.isRequired,
37 | }).isRequired,
38 | handleChange: PropTypes.func.isRequired,
39 | translations: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
40 | };
41 |
42 | export default RepeatHourly;
43 |
--------------------------------------------------------------------------------
/src/demo/index.css:
--------------------------------------------------------------------------------
1 | @import '~bootstrap/dist/css/bootstrap.css';
2 | @import '../lib/styles/index.css';
3 |
4 | .app-navbar {
5 | display: flex;
6 | justify-content: space-between;
7 |
8 | padding: 1rem;
9 |
10 | background: #000;
11 |
12 | vertical-align: middle;
13 | font-size: 0.9rem;
14 | font-weight: 400;
15 | }
16 | @media screen and (max-width: 960px) {
17 | .app-header-github {
18 | margin-bottom: 2rem;
19 | }
20 | }
21 |
22 | .app-navbar a {
23 | opacity: 1;
24 | transition: 0.1s;
25 | color: white;
26 | }
27 | .app-navbar a:hover {
28 | opacity: 0.5;
29 | transition: 0.1s;
30 | text-decoration: none;
31 | }
32 |
33 | .app-navbar-ghlogo {
34 | height: 20px;
35 | width: 20px;
36 | }
37 |
38 | .app-header {
39 | padding: 1rem;
40 | background: #222;
41 | color: white;
42 | text-align: center;
43 | }
44 |
45 | .app-desc {
46 | padding: 1rem;
47 | background: #444;
48 | color: white;
49 | text-align: center;
50 | }
51 |
52 | .app {
53 | margin-top: 3rem;
54 | }
55 |
56 | ::-webkit-scrollbar {
57 | display: none;
58 | }
59 |
60 | .rrule {
61 | background-color: #ffecef;
62 | font-size: 80%;
63 | font-family: SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
64 | }
65 |
66 | .rrule-not-copied {
67 | color: #222;
68 | }
69 |
70 | .rrule-not-copied:focus {
71 | color: #222;
72 | }
73 |
74 | .rrule-copied {
75 | color: #888;
76 | }
77 |
78 | .rrule-copied:focus {
79 | color: #888;
80 | }
81 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeMonthlyOnThe.js:
--------------------------------------------------------------------------------
1 | const computeMonthlyOnThe = (onThe) => {
2 | const repeat = {};
3 |
4 | switch (onThe.which) {
5 | case 'First':
6 | repeat.bysetpos = 1;
7 | break;
8 | case 'Second':
9 | repeat.bysetpos = 2;
10 | break;
11 | case 'Third':
12 | repeat.bysetpos = 3;
13 | break;
14 | case 'Fourth':
15 | repeat.bysetpos = 4;
16 | break;
17 | case 'Last':
18 | repeat.bysetpos = -1;
19 | break;
20 | default:
21 | break;
22 | }
23 |
24 | switch (onThe.day) {
25 | case 'Monday':
26 | repeat.byweekday = [0];
27 | break;
28 | case 'Tuesday':
29 | repeat.byweekday = [1];
30 | break;
31 | case 'Wednesday':
32 | repeat.byweekday = [2];
33 | break;
34 | case 'Thursday':
35 | repeat.byweekday = [3];
36 | break;
37 | case 'Friday':
38 | repeat.byweekday = [4];
39 | break;
40 | case 'Saturday':
41 | repeat.byweekday = [5];
42 | break;
43 | case 'Sunday':
44 | repeat.byweekday = [6];
45 | break;
46 | case 'Day':
47 | repeat.byweekday = [0, 1, 2, 3, 4, 5, 6];
48 | break;
49 | case 'Weekday':
50 | repeat.byweekday = [0, 1, 2, 3, 4];
51 | break;
52 | case 'Weekend day':
53 | repeat.byweekday = [5, 6];
54 | break;
55 | default:
56 | break;
57 | }
58 |
59 | return repeat;
60 | };
61 |
62 | export default computeMonthlyOnThe;
63 |
--------------------------------------------------------------------------------
/src/lib/utils/computeRRule/toString/computeYearlyOnThe.js:
--------------------------------------------------------------------------------
1 | import { MONTHS } from '../../../constants/index';
2 |
3 | const computeYearlyOnThe = (onThe) => {
4 | const repeat = {};
5 |
6 | switch (onThe.which) {
7 | case 'First':
8 | repeat.bysetpos = 1;
9 | break;
10 | case 'Second':
11 | repeat.bysetpos = 2;
12 | break;
13 | case 'Third':
14 | repeat.bysetpos = 3;
15 | break;
16 | case 'Fourth':
17 | repeat.bysetpos = 4;
18 | break;
19 | case 'Last':
20 | repeat.bysetpos = -1;
21 | break;
22 | default:
23 | break;
24 | }
25 |
26 | switch (onThe.day) {
27 | case 'Monday':
28 | repeat.byweekday = [0];
29 | break;
30 | case 'Tuesday':
31 | repeat.byweekday = [1];
32 | break;
33 | case 'Wednesday':
34 | repeat.byweekday = [2];
35 | break;
36 | case 'Thursday':
37 | repeat.byweekday = [3];
38 | break;
39 | case 'Friday':
40 | repeat.byweekday = [4];
41 | break;
42 | case 'Saturday':
43 | repeat.byweekday = [5];
44 | break;
45 | case 'Sunday':
46 | repeat.byweekday = [6];
47 | break;
48 | case 'Day':
49 | repeat.byweekday = [0, 1, 2, 3, 4, 5, 6];
50 | break;
51 | case 'Weekday':
52 | repeat.byweekday = [0, 1, 2, 3, 4];
53 | break;
54 | case 'Weekend day':
55 | repeat.byweekday = [5, 6];
56 | break;
57 | default:
58 | break;
59 | }
60 |
61 | repeat.bymonth = MONTHS.indexOf(onThe.month) + 1;
62 |
63 | return repeat;
64 | };
65 |
66 | export default computeYearlyOnThe;
67 |
--------------------------------------------------------------------------------
/src/lib/components/Repeat/Yearly/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import RepeatYearlyOn from './On';
4 | import RepeatYearlyOnThe from './OnThe';
5 |
6 | const RepeatYearly = ({
7 | id,
8 | yearly: {
9 | mode,
10 | on,
11 | onThe,
12 | options,
13 | },
14 | handleChange,
15 | translations
16 | }) => {
17 | const isTheOnlyOneMode = option => options.modes === option;
18 | const isOptionAvailable = option => !options.modes || isTheOnlyOneMode(option);
19 | return (
20 |
21 | {isOptionAvailable('on') && (
22 |
30 | )}
31 | {isOptionAvailable('on the') && (
32 |
40 | )}
41 |
42 | );
43 | };
44 | RepeatYearly.propTypes = {
45 | id: PropTypes.string.isRequired,
46 | yearly: PropTypes.shape({
47 | mode: PropTypes.oneOf(['on', 'on the']).isRequired,
48 | on: PropTypes.object.isRequired,
49 | onThe: PropTypes.object.isRequired,
50 | options: PropTypes.shape({
51 | modes: PropTypes.oneOf(['on', 'on the']),
52 | }).isRequired,
53 | }).isRequired,
54 | handleChange: PropTypes.func.isRequired,
55 | translations: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
56 | };
57 |
58 | export default RepeatYearly;
59 |
--------------------------------------------------------------------------------
/src/lib/components/Repeat/Monthly/On.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import numericalFieldHandler from '../../../utils/numericalFieldHandler';
4 | import translateLabel from '../../../utils/translateLabel';
5 |
6 | const RepeatMonthlyOn = ({
7 | id,
8 | mode,
9 | on,
10 | hasMoreModes,
11 | handleChange,
12 | translations
13 | }) => {
14 | const isActive = mode === 'on';
15 |
16 | return (
17 |
18 |
19 | {hasMoreModes && (
20 |
29 | )}
30 |
31 |
32 | {translateLabel(translations, 'repeat.monthly.on_day')}
33 |
34 |
35 |
36 |
47 |
48 |
49 | );
50 | };
51 | RepeatMonthlyOn.propTypes = {
52 | id: PropTypes.string.isRequired,
53 | mode: PropTypes.oneOf(['on', 'on the']).isRequired,
54 | on: PropTypes.shape({
55 | day: PropTypes.number.isRequired,
56 | }).isRequired,
57 | hasMoreModes: PropTypes.bool.isRequired,
58 | handleChange: PropTypes.func.isRequired,
59 | translations: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
60 | };
61 |
62 | export default RepeatMonthlyOn;
63 |
--------------------------------------------------------------------------------
/src/lib/translations/english.js:
--------------------------------------------------------------------------------
1 | export default {
2 | locale: 'en-gb',
3 | invalid_rrule: "You provided an invalid RRule value to component. '%{value}' is not a correct RRule string.",
4 | months: {
5 | jan: 'Jan',
6 | feb: 'Feb',
7 | mar: 'Mar',
8 | apr: 'Apr',
9 | may: 'May',
10 | jun: 'Jun',
11 | jul: 'Jul',
12 | aug: 'Aug',
13 | sep: 'Sep',
14 | oct: 'Oct',
15 | nov: 'Nov',
16 | dec: 'Dec',
17 | },
18 | days_short: {
19 | mon: 'Mon',
20 | tue: 'Tue',
21 | wed: 'Wed',
22 | thu: 'Thu',
23 | fri: 'Fri',
24 | sat: 'Sat',
25 | sun: 'Sun',
26 | },
27 | days: {
28 | monday: 'Monday',
29 | tuesday: 'Tuesday',
30 | wednesday: 'Wednesday',
31 | thursday: 'Thursday',
32 | friday: 'Friday',
33 | saturday: 'Saturday',
34 | sunday: 'Sunday',
35 | day: 'Day',
36 | weekday: 'Weekday',
37 | 'weekend day': 'Weekend day',
38 | },
39 | numerals: {
40 | first: 'First',
41 | second: 'Second',
42 | third: 'Third',
43 | fourth: 'Fourth',
44 | last: 'Last',
45 | },
46 | start: {
47 | label: 'Start',
48 | tooltip: 'Datetime picker for start on date',
49 | },
50 | repeat: {
51 | label: 'Repeat',
52 | yearly: {
53 | label: 'Yearly',
54 | on: 'on',
55 | on_the: 'on the',
56 | of: 'of',
57 | },
58 | monthly: {
59 | label: 'Monthly',
60 | every: 'every',
61 | months: 'month(s)',
62 | on_day: 'on day',
63 | on_the: 'on the',
64 | },
65 | weekly: {
66 | label: 'Weekly',
67 | every: 'every',
68 | weeks: 'week(s)',
69 | },
70 | daily: {
71 | label: 'Daily',
72 | every: 'every',
73 | days: 'day(s)',
74 | },
75 | hourly: {
76 | label: 'Hourly',
77 | every: 'every',
78 | hours: 'hour(s)',
79 | },
80 | },
81 | end: {
82 | label: 'End',
83 | tooltip: 'Datetime picker for end on date',
84 | never: 'Never',
85 | after: 'After',
86 | on_date: 'On date',
87 | executions: 'executions.',
88 | },
89 | }
90 |
--------------------------------------------------------------------------------
/src/lib/translations/german.js:
--------------------------------------------------------------------------------
1 | export default {
2 | locale: 'de',
3 | invalid_rrule: "Sie haben eine ungültige RRule an die Komponente übergeben. '%{value}' ist keine gültige RRule.",
4 | months: {
5 | jan: 'Jan',
6 | feb: 'Feb',
7 | mar: 'Mär',
8 | apr: 'Apr',
9 | may: 'Mai',
10 | jun: 'Jun',
11 | jul: 'Jul',
12 | aug: 'Aug',
13 | sep: 'Sep',
14 | oct: 'Okt',
15 | nov: 'Nov',
16 | dec: 'Dez',
17 | },
18 | days_short: {
19 | mon: 'Mo',
20 | tue: 'Di',
21 | wed: 'Mi',
22 | thu: 'Do',
23 | fri: 'Fr',
24 | sat: 'Sa',
25 | sun: 'So',
26 | },
27 | days: {
28 | monday: 'Montag',
29 | tuesday: 'Dienstag',
30 | wednesday: 'Mittwoch',
31 | thursday: 'Donnerstag',
32 | friday: 'Freitag',
33 | saturday: 'Samstag',
34 | sunday: 'Sonntag',
35 | day: 'Tag',
36 | weekday: 'Wochentag',
37 | 'weekend day': 'Wochenende',
38 | },
39 | numerals: {
40 | first: 'Ersten',
41 | second: 'Zweiten',
42 | third: 'Dritten',
43 | fourth: 'Vierten',
44 | last: 'Letzten',
45 | },
46 | start: {
47 | label: 'Start',
48 | tooltip: 'Startdatum des Zeitplans',
49 | },
50 | repeat: {
51 | label: 'Wiederholen',
52 | yearly: {
53 | label: 'Jährlich',
54 | on: 'am',
55 | on_the: 'an dem',
56 | of: 'von',
57 | },
58 | monthly: {
59 | label: 'Monatlich',
60 | every: 'Jeden',
61 | months: 'Monat(e)',
62 | on_day: 'am Tag',
63 | on_the: 'am',
64 | },
65 | weekly: {
66 | label: 'Wöchentlich',
67 | every: 'Jede',
68 | weeks: 'Woche(n)',
69 | },
70 | daily: {
71 | label: 'Täglich',
72 | every: 'Jeden',
73 | days: 'Tag(e)',
74 | },
75 | hourly: {
76 | label: 'Stündlich',
77 | every: 'Jede',
78 | hours: 'Stunde(n)',
79 | },
80 | },
81 | end: {
82 | label: 'Ende',
83 | tooltip: 'Ende des Zeitplans',
84 | never: 'Niemals',
85 | after: 'Nach',
86 | on_date: 'Am',
87 | executions: 'Ausführungen.',
88 | },
89 | };
90 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(path, needsSlash) {
15 | const hasSlash = path.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return path.substr(path, path.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${path}/`;
20 | } else {
21 | return path;
22 | }
23 | }
24 |
25 | const getPublicUrl = appPackageJson =>
26 | envPublicUrl || require(appPackageJson).homepage;
27 |
28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 | // "public path" at which the app is served.
30 | // Webpack needs to know it to put the right