# Oveasoft Planning

The Oveasoft's Planning is an AngularJS based package used to display a planning of appointments.

- [Run it](#run-it)
- [Install it](#install-it)
- [Use it](#use-it)
- [Configure it](#configure-it)
- [Breaking changes](#breaking-changes)
  - [1.1.x](#1.1.x)
  - [1.2.x](#1.2.x)

## <a name="install-it"></a> Install it

```shell
yarn add @oveasoft/planning
```

## <a name="run-it"></a> Run it

- Requires Node 8.4.0+

With yarn:

    yarn build - Webpack build
    yarn test  - Karma test
    yarn demo  - Run the demo

## <a name="use-it"></a> Use it

The module name is : `ovaPlanning`
First, import the module like this :

```javascript
import ovaPlanning from '@ovasoft/planning';

angular.module('myModule', [ovaPlanning]);
```

Then you can use the component like this :

```html
<ova-planning></ova-planning>
```

It will render an empty planning.

To fill the planning with items, you must pass objects as an array through the **appointments** property :

```html
<ova-planning appointments="myItems"></ova-planning>
```



See [https://momentjs.com/docs/#/parsing/](https://momentjs.com/docs/#/parsing/) for valid values.

You can pass a template through the configuration to display an appointment.

```javascript
const myConfiguration = {
    template: $appointment => `<my-appointment-component item="$appointment"></my-appointment-component>`
};
```

And set the config key like this :

```html
<ova-planning config="myConfiguration"></ova-planning>
```

## <a name="configure-it"></a> Configure it

You can also pass a `config` attribute like this :

```javascript
const myConfiguration = {
    'momentLocale': 'en',
    'datePath': 'date',
    'slot': [[6, 20]],
    'slotInterval': 30,
    'currentWeek': new Date()
};
```

```html
<ova-planning config="myConfiguration"></ova-planning>
```

### Available key for configuration

```javascript
let configuration = {
    currentWeek: moment(),      // The day you want to start on.
    datePath: 'date',           // The path to your date on the data.
    dayLabelFormat: 'ddd DD',   // The format of label.
    debug: false,               // Set the debug mode.
    editOnClick: true,          // Set the built-in appointment edition on click.
    excludedDays: [],           // Exclude days from weeks. (0 = First day of the week, Monday or Sunday depending the locale)
    momentLocale: "fr",         // Set the locale of Moment.
    showControls: false,        // Show/Hide the controls to navigate through planning.
    showLabel: true,            // Show/Hide the label of the current week.
    showPause: true,            // Show/Hide breaks line.
    slot: [[8, 18], [14, 18]],  // Define ranges of weeks.
    slotInterval: 45,           // Define the interval of slots.
    theme: 'blue',              // Set the theme.
    onChangeWeek: () => {},     // Executed when controls are used.
    onClick: (data) => {},      // Executed when an appointment is clicked.
    onLoad: () => {},           // Bind data like placed and misplaced events.
    selectSlot: () => {},       // Return slot information when you click it.
    viewer: 'month',            // Set the default viewer.
    views: {
        week: {
            template: () => '<my-week-template></my-week-template>'     // Set the template for week view.
        },
        month: {
            weeksPerView: {
                default: 4, // The default number of week displayed on the month view.
                current: 4, // The current number of week displayed on the month view.
            },
            template: () => '<my-month-template></my-month-template>'   // Set the template for month view.
        }
        trimester: {
            columnType: 'month',
            range: {
                past: 2,
                future: 2
            },
            labels: date => date.format('MMMM YYYY'),
            template: () => `<my-trimester-template data="$appointment"></my-trimester-template>`
        }   
    }
};
```

### Viewers

The list of availables viewers :

- month
- week
- trimester

### Themes

The list of availables themes:

- blue
- brown
- purple
- teal
- green
- navy
- brick

---

## _That's it_

## <a name="breaking-changes"></a> Breaking changes

### <a name="1.1.x">1.1.x</a>

On 1.0.x we used transclude like this to pass the template :

```html
<ova-planning config="myConfiguration">
    <my-appointment-component item="$parent.$parent.$appointment"></my-appointment-component>
</ova-planning>
```

On 1.1.x we now pass the template as a parameter of the configuration.

```javascript
const myConfiguration = {
    momentLocale: 'en',
    slot: [[6, 20]],
    slotInterval: 30,
    currentWeek: new Date(),
    template: $appointment => `<my-appointment-component item="$appointment"></my-appointment-component>`
};
```

And remain :

```html
<ova-planning config="myConfiguration"></ova-planning>
```

## <a name="1.2.x">1.2.x</a>

### Templates

As the 1.2.x introduce a secondary view of the planning, the template is now passed this way :
```javascript
let myConfiguration = {
    momentLocale: 'en',
    slot: [[6, 20]],
    slotInterval: 30,
    currentWeek: new Date(),
    views: {
        week: {
            template: () => '<my-week-template></my-week-template>'
        },
        month: {
            template: () => '<my-month-template></my-month-template>'
        }       
    }
};
```

### Date on items

In <1.1.x, objects in the array **MUST** have a `date` property with a value equal to a MomentJS object or any value that can be parsed and give a valid MomentJS object.

**Example :**

```javascript
let validItems = [
    { date: moment() },
    { date: '2018-11-05' },
    { date: new Date },
    { date: [2018, 1, 14, 15, 25, 50, 125] }
];
```

It's bit different now, you still have to provide a date-like property, but you can choose the path on your data :

Here are some examples :
```javascript
let configuration = { ... };

let data = [{ id: 1, username: 'Foo', details: { birthday: '1990-12-10' } }];
configuration.datePath = 'details.birthday';

let data = [{ id: 1, path: { to: { date: '1990-12-10' } } }];
configuration.datePath = 'path.to.date';
```

By default, datePath is set to 'date' and should not break your project.




## ToDo

- ~~Resolve the scope issue to ommit `$parent.$parent`.~~
- ~~Inject a default template.~~
