mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-04 12:58:50 +00:00
Initial recurrence editor for appointments
This commit is contained in:
@@ -128,6 +128,8 @@
|
||||
"Attach" = "Attach";
|
||||
"Update" = "Update";
|
||||
"Cancel" = "Cancel";
|
||||
"Reset" = "Reset";
|
||||
"Save" = "Save";
|
||||
"show_rejected_apts" = "Show rejected appointments";
|
||||
"hide_rejected_apts" = "Hide rejected appointments";
|
||||
|
||||
@@ -337,6 +339,11 @@
|
||||
"appointment(s)" = "appointment(s)";
|
||||
"Repeat until" = "Repeat until";
|
||||
|
||||
"End Repeat" = "End Repeat";
|
||||
"Never" = "Never";
|
||||
"After" = "After";
|
||||
"On Date" = "On Date";
|
||||
|
||||
"First" = "First";
|
||||
"Second" = "Second";
|
||||
"Third" = "Third";
|
||||
|
||||
@@ -359,10 +359,9 @@
|
||||
|
||||
if (!repeatItems)
|
||||
{
|
||||
repeatItems = [NSArray arrayWithObjects: @"daily",
|
||||
repeatItems = [NSArray arrayWithObjects: @"never",
|
||||
@"daily",
|
||||
@"weekly",
|
||||
@"bi-weekly",
|
||||
@"every_weekday",
|
||||
@"monthly",
|
||||
@"yearly",
|
||||
nil];
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
@interface UIxComponentEditor : UIxComponent
|
||||
{
|
||||
id item;
|
||||
iCalRepeatableEntityObject *component;
|
||||
SOGoAppointmentFolder *componentCalendar;
|
||||
}
|
||||
|
||||
@@ -242,59 +242,6 @@ static NSArray *reminderValues = nil;
|
||||
// return [comment stringByReplacingString: @"\n" withString: @"\r\n"];
|
||||
//}
|
||||
|
||||
// TODO: Expose this method to the JSON API or centralize in UIxPreferences
|
||||
- (NSArray *) categoryList
|
||||
{
|
||||
NSMutableArray *categoryList;
|
||||
NSArray *categoryLabels;
|
||||
SOGoUserDefaults *defaults;
|
||||
|
||||
defaults = [[context activeUser] userDefaults];
|
||||
categoryLabels = [defaults calendarCategories];
|
||||
if (!categoryLabels)
|
||||
categoryLabels = [[self labelForKey: @"category_labels"]
|
||||
componentsSeparatedByString: @","];
|
||||
categoryList = [NSMutableArray arrayWithCapacity: [categoryLabels count] + 1];
|
||||
[categoryList addObjectsFromArray:
|
||||
[categoryLabels sortedArrayUsingSelector:
|
||||
@selector (localizedCaseInsensitiveCompare:)]];
|
||||
|
||||
return categoryList;
|
||||
}
|
||||
|
||||
//- (NSArray *) repeatList
|
||||
//{
|
||||
// static NSArray *repeatItems = nil;
|
||||
//
|
||||
// if (!repeatItems)
|
||||
// {
|
||||
// repeatItems = [NSArray arrayWithObjects: @"DAILY",
|
||||
// @"WEEKLY",
|
||||
// @"BI-WEEKLY",
|
||||
// @"EVERY WEEKDAY",
|
||||
// @"MONTHLY",
|
||||
// @"YEARLY",
|
||||
// @"-",
|
||||
// @"CUSTOM",
|
||||
// nil];
|
||||
// [repeatItems retain];
|
||||
// }
|
||||
//
|
||||
// return repeatItems;
|
||||
//}
|
||||
|
||||
//- (NSString *) repeatLabel
|
||||
//{
|
||||
// NSString *rc;
|
||||
//
|
||||
// if ([self repeat])
|
||||
// rc = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", [self repeat]]];
|
||||
// else
|
||||
// rc = [self labelForKey: @"repeat_NEVER"];
|
||||
//
|
||||
// return rc;
|
||||
//}
|
||||
|
||||
//- (NSString *) reminder
|
||||
//{
|
||||
// if ([[self clientObject] isNew])
|
||||
@@ -394,20 +341,6 @@ static NSArray *reminderValues = nil;
|
||||
// return priorities;
|
||||
//}
|
||||
|
||||
//- (NSArray *) classificationClasses
|
||||
//{
|
||||
// static NSArray *classes = nil;
|
||||
//
|
||||
// if (!classes)
|
||||
// {
|
||||
// classes = [NSArray arrayWithObjects: @"PUBLIC",
|
||||
// @"CONFIDENTIAL", @"PRIVATE", nil];
|
||||
// [classes retain];
|
||||
// }
|
||||
//
|
||||
// return classes;
|
||||
//}
|
||||
|
||||
/* helpers */
|
||||
|
||||
//- (BOOL) isWriteableClientObject
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* UIxRecurrenceEditor.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
*
|
||||
* Author: Ludovic Marcotte <ludovic@inverse.ca>
|
||||
* Copyright (C) 2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,11 +19,14 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h> /* for locale string constants */
|
||||
|
||||
#import <Common/UIxPageFrame.h>
|
||||
|
||||
#import <SOPE/NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import "UIxRecurrenceEditor.h"
|
||||
|
||||
@implementation UIxRecurrenceEditor
|
||||
@@ -64,7 +65,7 @@
|
||||
if (!monthlyDayList)
|
||||
{
|
||||
monthlyDayList = [NSMutableArray arrayWithArray: [locale objectForKey: NSWeekDayNameArray]];
|
||||
[monthlyDayList addObject: @"DayOfTheMonth"];
|
||||
[monthlyDayList addObject: [self labelForKey: @"DayOfTheMonth"]];
|
||||
[monthlyDayList retain];
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@
|
||||
|
||||
if (!yearlyMonthList)
|
||||
{
|
||||
yearlyMonthList = [locale objectForKey: NSMonthNameArray];
|
||||
yearlyMonthList = [locale objectForKey: NSShortMonthNameArray];
|
||||
[yearlyMonthList retain];
|
||||
}
|
||||
|
||||
@@ -102,18 +103,27 @@
|
||||
//
|
||||
- (NSArray *) repeatList
|
||||
{
|
||||
static NSArray *repeatList = nil;
|
||||
static NSArray *repeatItems = nil;
|
||||
|
||||
if (!repeatList)
|
||||
if (!repeatItems)
|
||||
{
|
||||
repeatList = [NSArray arrayWithObjects: @"Daily", @"Weekly",
|
||||
@"Monthly", @"Yearly", nil];
|
||||
[repeatList retain];
|
||||
repeatItems = [NSArray arrayWithObjects: @"daily",
|
||||
@"weekly",
|
||||
@"bi-weekly",
|
||||
@"every_weekday",
|
||||
@"monthly",
|
||||
@"yearly",
|
||||
nil];
|
||||
[repeatItems retain];
|
||||
}
|
||||
|
||||
return repeatList;
|
||||
return repeatItems;
|
||||
}
|
||||
|
||||
- (NSString *) itemRepeatText
|
||||
{
|
||||
return [self labelForKey: [NSString stringWithFormat: @"repeat_%@", [item uppercaseString]]];
|
||||
}
|
||||
|
||||
//
|
||||
// Accessors
|
||||
@@ -158,4 +168,54 @@
|
||||
return item;
|
||||
}
|
||||
|
||||
- (NSString *) valueForWeekDay
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
i = [[self shortWeekDaysList] indexOfObject: item];
|
||||
|
||||
return iCalWeekDayString[i];
|
||||
}
|
||||
|
||||
- (NSString *) valueForMonthlyRepeat
|
||||
{
|
||||
static NSArray *monthlyRepeatValues = nil;
|
||||
unsigned int i;
|
||||
|
||||
if (!monthlyRepeatValues)
|
||||
{
|
||||
monthlyRepeatValues = [NSArray arrayWithObjects: @"1", @"2", @"3",
|
||||
@"4", @"5", @"-1", nil];
|
||||
[monthlyRepeatValues retain];
|
||||
}
|
||||
i = [[self monthlyRepeatList] indexOfObject: item];
|
||||
|
||||
return [monthlyRepeatValues objectAtIndex: i];
|
||||
}
|
||||
|
||||
- (NSString *) valueForMonthlyDay
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
i = [[self monthlyDayList] indexOfObject: item];
|
||||
if (i % 7 != i)
|
||||
return @"";
|
||||
else
|
||||
return iCalWeekDayString[i];
|
||||
}
|
||||
|
||||
- (unsigned int) valueForYearlyMonth
|
||||
{
|
||||
return [[self yearlyMonthList] indexOfObject: item] + 1;
|
||||
}
|
||||
|
||||
- (NSString *) valueForYearlyDay
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
i = [[self yearlyDayList] indexOfObject: item];
|
||||
|
||||
return iCalWeekDayString[i];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,28 +1,136 @@
|
||||
<?xml version='1.0' standalone='yes'?>
|
||||
<!DOCTYPE var:component>
|
||||
<var:component
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:uix="OGo:uix"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
const:toolbar="none"
|
||||
const:popup="YES"
|
||||
const:cssFiles="datepicker.css"
|
||||
const:jsFiles="datepicker.js">
|
||||
<container
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:label="OGo:label"
|
||||
>
|
||||
<!-- daily -->
|
||||
<div layout="row" layout-align="start center"
|
||||
ng-show="editor.event.repeat.frequency == 'daily'">
|
||||
<var:string label:value="Every"/>
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="Every" ng-model="editor.event.repeat.interval"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="Days"/>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var dayFieldInvalid = '<var:string label:value="dayFieldInvalid"/>';
|
||||
var weekFieldInvalid = '<var:string label:value="weekFieldInvalid"/>';
|
||||
var monthFieldInvalid = '<var:string label:value="monthFieldInvalid"/>';
|
||||
var monthDayFieldInvalid = '<var:string label:value="monthDayFieldInvalid"/>';
|
||||
var yearFieldInvalid = '<var:string label:value="yearFieldInvalid"/>';
|
||||
var appointmentFieldInvalid = '<var:string label:value="appointmentFieldInvalid"/>';
|
||||
var recurrenceUnsupported = '<var:string label:value="recurrenceUnsupported"/>';
|
||||
</script>
|
||||
<form name="recurrence_form" id="recurrence_form" href="editRecurrence">
|
||||
<!-- weekly -->
|
||||
<div ng-show="editor.event.repeat.frequency == 'weekly'">
|
||||
<div layout="row" layout-align="start center">
|
||||
<var:string label:value="Every"/>
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="Every" ng-model="editor.event.repeat.interval"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="Week(s)"/> <var:string label:value="On"/>
|
||||
</div>
|
||||
<md-grid-list md-cols="7" md-row-height="1:1" md-gutter="0.5em"
|
||||
sg-toggle-grid="editor.event.repeat.days"
|
||||
sg-toggle-grid-attr="day">
|
||||
<var:foreach list="shortWeekDaysList" item="item">
|
||||
<md-grid-tile var:value="valueForWeekDay"><var:string value="labelForWeekDay"/></md-grid-tile>
|
||||
</var:foreach>
|
||||
</md-grid-list>
|
||||
</div>
|
||||
|
||||
<!-- monthly -->
|
||||
<div ng-show="editor.event.repeat.frequency == 'monthly'">
|
||||
<div layout="row" layout-align="start center">
|
||||
<var:string label:value="Every"/>
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="Every" ng-model="editor.event.repeat.interval"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="Month(s)"/>
|
||||
</div>
|
||||
<md-radio-group ng-model="editor.event.repeat.month.type">
|
||||
<md-radio-button value="bymonthday">
|
||||
<var:string label:value="Recur on day(s)"/>
|
||||
</md-radio-button>
|
||||
<md-grid-list md-cols="7" md-row-height="1:1" md-gutter="0.5em"
|
||||
sg-toggle-grid="editor.event.repeat.monthdays">
|
||||
<md-grid-tile value="1">1</md-grid-tile>
|
||||
<md-grid-tile value="2">2</md-grid-tile>
|
||||
<md-grid-tile value="3">3</md-grid-tile>
|
||||
<md-grid-tile value="4">4</md-grid-tile>
|
||||
<md-grid-tile value="5">5</md-grid-tile>
|
||||
<md-grid-tile value="6">6</md-grid-tile>
|
||||
<md-grid-tile value="7">7</md-grid-tile>
|
||||
<md-grid-tile value="8">8</md-grid-tile>
|
||||
<md-grid-tile value="9">9</md-grid-tile>
|
||||
<md-grid-tile value="10">10</md-grid-tile>
|
||||
<md-grid-tile value="11">11</md-grid-tile>
|
||||
<md-grid-tile value="12">12</md-grid-tile>
|
||||
<md-grid-tile value="13">13</md-grid-tile>
|
||||
<md-grid-tile value="14">14</md-grid-tile>
|
||||
<md-grid-tile value="15">15</md-grid-tile>
|
||||
<md-grid-tile value="16">16</md-grid-tile>
|
||||
<md-grid-tile value="17">17</md-grid-tile>
|
||||
<md-grid-tile value="18">18</md-grid-tile>
|
||||
<md-grid-tile value="19">19</md-grid-tile>
|
||||
<md-grid-tile value="20">20</md-grid-tile>
|
||||
<md-grid-tile value="21">21</md-grid-tile>
|
||||
<md-grid-tile value="22">22</md-grid-tile>
|
||||
<md-grid-tile value="23">23</md-grid-tile>
|
||||
<md-grid-tile value="24">24</md-grid-tile>
|
||||
<md-grid-tile value="25">25</md-grid-tile>
|
||||
<md-grid-tile value="26">26</md-grid-tile>
|
||||
<md-grid-tile value="27">27</md-grid-tile>
|
||||
<md-grid-tile value="28">28</md-grid-tile>
|
||||
<md-grid-tile value="29">29</md-grid-tile>
|
||||
<md-grid-tile value="30">30</md-grid-tile>
|
||||
<md-grid-tile value="31">31</md-grid-tile>
|
||||
</md-grid-list>
|
||||
<div layout="row" layout-align="start center">
|
||||
<md-radio-button value="byday">
|
||||
<var:string label:value="The"/>
|
||||
</md-radio-button>
|
||||
<md-select ng-model="editor.event.repeat.month.occurrence">
|
||||
<var:foreach list="monthlyRepeatList" item="item">
|
||||
<md-option var:value="valueForMonthlyRepeat"><var:string value="itemText"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
<md-select ng-model="editor.event.repeat.month.day">
|
||||
<var:foreach list="monthlyDayList" item="item">
|
||||
<md-option var:value="valueForMonthlyDay"><var:string value="item"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</div>
|
||||
</md-radio-group>
|
||||
</div>
|
||||
|
||||
<!-- yearly -->
|
||||
<div ng-show="editor.event.repeat.frequency == 'yearly'">
|
||||
<div layout="row" layout-align="start center">
|
||||
<var:string label:value="Every"/>
|
||||
<md-input-container class="md-input-number">
|
||||
<input type="number" label:aria-label="Every" ng-model="editor.event.repeat.interval"/>
|
||||
</md-input-container>
|
||||
<var:string label:value="Year(s)"/>
|
||||
</div>
|
||||
<md-grid-list md-cols="6" md-row-height="1:1" md-gutter="0.5em"
|
||||
sg-toggle-grid="editor.event.repeat.months">
|
||||
<var:foreach list="yearlyMonthList" item="item">
|
||||
<md-grid-tile var:value="valueForYearlyMonth"><var:string value="item"/></md-grid-tile>
|
||||
</var:foreach>
|
||||
</md-grid-list>
|
||||
<div layout="row" layout-align="start center">
|
||||
<md-checkbox ng-model="editor.event.repeat.year.byday">
|
||||
<var:string label:value="The"/>
|
||||
</md-checkbox>
|
||||
<md-select ng-model="editor.event.repeat.month.occurrence">
|
||||
<var:foreach list="monthlyRepeatList" item="item">
|
||||
<md-option var:value="valueForMonthlyRepeat"><var:string value="itemText"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
<md-select ng-model="editor.event.repeat.month.day">
|
||||
<var:foreach list="yearlyDayList" item="item">
|
||||
<md-option var:value="valueForYearlyDay"><var:string value="item"/></md-option>
|
||||
</var:foreach>
|
||||
</md-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form name="recurrence_form" id="recurrence_form" href="editRecurrence" class="ng-hide">
|
||||
<div id="recurrence_pattern" style="display: none;">
|
||||
<span class="caption"><var:string label:value="Recurrence pattern"/></span>
|
||||
<table class="frame">
|
||||
@@ -242,13 +350,6 @@
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="windowButtons">
|
||||
<a id="okButton" href="#" class="button actionButton"
|
||||
><span><var:string label:value="OK"/></span></a>
|
||||
<a id="cancelButton" href="#" class="button"
|
||||
><span><var:string label:value="Cancel"/></span></a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</var:component>
|
||||
</container>
|
||||
|
||||
@@ -48,14 +48,13 @@
|
||||
* @desc Factory registration of Component in Angular module.
|
||||
*/
|
||||
angular.module('SOGo.SchedulerUI')
|
||||
/* Factory registration in Angular module */
|
||||
.factory('Component', Component.$factory);
|
||||
|
||||
/**
|
||||
* @function $filter
|
||||
* @memberof Component.prototype
|
||||
* @desc Search for components matching some criterias
|
||||
* @param {string} type - Either 'events' or 'tasks'
|
||||
* @param {string} type - either 'events' or 'tasks'
|
||||
* @param {object} [options] - additional options to the query
|
||||
* @returns a collection of Components instances
|
||||
*/
|
||||
@@ -82,11 +81,11 @@
|
||||
};
|
||||
|
||||
/**
|
||||
* @memberof Card
|
||||
* @desc Fetch a card from a specific addressbook.
|
||||
* @param {string} addressbook_id - the addressbook ID
|
||||
* @param {string} card_id - the card ID
|
||||
* @see {@link AddressBook.$getCard}
|
||||
* @function $find
|
||||
* @desc Fetch a component from a specific calendar.
|
||||
* @param {string} calendarId - the calendar ID
|
||||
* @param {string} componentId - the component ID
|
||||
* @see {@link Calendar.$getComponent}
|
||||
*/
|
||||
Component.$find = function(calendarId, componentId) {
|
||||
var futureComponentData = this.$$resource.fetch([calendarId, componentId].join('/'), 'view');
|
||||
@@ -96,7 +95,6 @@
|
||||
|
||||
/**
|
||||
* @function filterCategories
|
||||
* @memberof Component.prototype
|
||||
* @desc Search for categories matching some criterias
|
||||
* @param {string} search - the search string to match
|
||||
* @returns a collection of strings
|
||||
@@ -110,7 +108,6 @@
|
||||
|
||||
/**
|
||||
* @function $eventsBlocksForView
|
||||
* @memberof Component.prototype
|
||||
* @desc Events blocks for a specific week
|
||||
* @param {string} view - Either 'day' or 'week'
|
||||
* @param {Date} type - Date of any day of the desired period
|
||||
@@ -146,7 +143,6 @@
|
||||
|
||||
/**
|
||||
* @function $eventsBlocks
|
||||
* @memberof Component.prototype
|
||||
* @desc Events blocks for a specific view and period
|
||||
* @param {string} view - Either 'day' or 'week'
|
||||
* @param {Date} startDate - period's start date
|
||||
@@ -197,9 +193,9 @@
|
||||
};
|
||||
|
||||
/**
|
||||
* @function $unwrap
|
||||
* @memberof Comonent.prototype
|
||||
* @function $unwrapCollection
|
||||
* @desc Unwrap a promise and instanciate new Component objects using received data.
|
||||
* @param {string} type - either 'events' or 'tasks'
|
||||
* @param {promise} futureComponentData - a promise of the components' metadata
|
||||
* @returns a promise of the HTTP operation
|
||||
*/
|
||||
@@ -241,10 +237,59 @@
|
||||
*/
|
||||
Component.prototype.init = function(data) {
|
||||
this.categories = [];
|
||||
this.repeat = {};
|
||||
angular.extend(this, data);
|
||||
|
||||
// Parse recurrence rule definition and initialize default values
|
||||
if (this.repeat.days) {
|
||||
var byDayMask = _.find(this.repeat.days, function(o) {
|
||||
return angular.isDefined(o.occurrence);
|
||||
});
|
||||
if (byDayMask)
|
||||
if (this.repeat.frequency == 'yearly')
|
||||
this.repeat.year = { byday: true };
|
||||
this.repeat.month = {
|
||||
type: 'byday',
|
||||
occurrence: byDayMask.occurrence.toString(),
|
||||
day: byDayMask.day
|
||||
};
|
||||
}
|
||||
else {
|
||||
this.repeat.days = [];
|
||||
}
|
||||
if (angular.isUndefined(this.repeat.interval))
|
||||
this.repeat.interval = 1;
|
||||
if (angular.isUndefined(this.repeat.month))
|
||||
this.repeat.month = { occurrence: '1', day: 'SU', type: 'bymonthday' };
|
||||
if (angular.isUndefined(this.repeat.monthdays))
|
||||
this.repeat.monthdays = [];
|
||||
if (angular.isUndefined(this.repeat.months))
|
||||
this.repeat.months = [];
|
||||
if (angular.isUndefined(this.repeat.year))
|
||||
this.repeat.year = {};
|
||||
if (this.repeat.count)
|
||||
this.repeat.end = 'count';
|
||||
else if (this.repeat.until) {
|
||||
this.repeat.end = 'until';
|
||||
this.repeat.until = this.repeat.until.substring(0,10).asDate();
|
||||
}
|
||||
else
|
||||
this.repeat.end = 'never';
|
||||
this.$hasCustomRepeat = this.hasCustomRepeat();
|
||||
|
||||
// Allow the event to be moved to a different calendar
|
||||
this.destinationCalendar = this.pid;
|
||||
};
|
||||
|
||||
Component.prototype.hasCustomRepeat = function() {
|
||||
var b = angular.isDefined(this.repeat) &&
|
||||
(this.repeat.interval > 1 ||
|
||||
this.repeat.days && this.repeat.days.length > 0 ||
|
||||
this.repeat.monthdays && this.repeat.monthdays.length > 0 ||
|
||||
this.repeat.months && this.repeat.months.length > 0);
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* @function getClassName
|
||||
* @memberof Component.prototype
|
||||
@@ -260,8 +305,8 @@
|
||||
|
||||
/**
|
||||
* @function $reset
|
||||
* @memberof Card.prototype
|
||||
* @desc Reset the original state the card's data.
|
||||
* @memberof Component.prototype
|
||||
* @desc Reset the original state the component's data.
|
||||
*/
|
||||
Component.prototype.$reset = function() {
|
||||
var _this = this;
|
||||
@@ -300,29 +345,21 @@
|
||||
* @param {promise} futureComponentData - a promise of some of the Component's data
|
||||
*/
|
||||
Component.prototype.$unwrap = function(futureComponentData) {
|
||||
var _this = this,
|
||||
deferred = Component.$q.defer();
|
||||
var _this = this;
|
||||
|
||||
// Expose the promise
|
||||
this.$futureComponentData = futureComponentData;
|
||||
|
||||
// Resolve the promise
|
||||
this.$futureComponentData.then(function(data) {
|
||||
// Calling $timeout will force Angular to refresh the view
|
||||
Component.$timeout(function() {
|
||||
_this.init(data);
|
||||
// Make a copy of the data for an eventual reset
|
||||
_this.$shadowData = _this.$omit();
|
||||
deferred.resolve(_this);
|
||||
});
|
||||
_this.init(data);
|
||||
// Make a copy of the data for an eventual reset
|
||||
_this.$shadowData = _this.$omit();
|
||||
}, function(data) {
|
||||
angular.extend(_this, data);
|
||||
_this.isError = true;
|
||||
Component.$log.error(_this.error);
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -335,13 +372,39 @@
|
||||
var component = {}, date;
|
||||
angular.forEach(this, function(value, key) {
|
||||
if (key != 'constructor' && key[0] != '$') {
|
||||
component[key] = value;
|
||||
component[key] = angular.copy(value);
|
||||
}
|
||||
});
|
||||
|
||||
// Format times
|
||||
component.startTime = component.startDate ? formatTime(component.startDate) : '';
|
||||
component.endTime = component.endDate ? formatTime(component.endDate) : '';
|
||||
|
||||
// Update recurrence definition depending on selections
|
||||
if (this.$hasCustomRepeat) {
|
||||
if (this.repeat.frequency == 'monthly' && this.repeat.month.type && this.repeat.month.type == 'byday'
|
||||
|| this.repeat.frequency == 'yearly' && this.repeat.year.byday) {
|
||||
// BYDAY mask for a monthly or yearly recurrence
|
||||
delete component.repeat.monthdays;
|
||||
component.repeat.days = [{ day: this.repeat.month.day, occurrence: this.repeat.month.occurrence.toString() }];
|
||||
}
|
||||
else if (this.repeat.month.type) {
|
||||
// montly recurrence by month days or yearly by month
|
||||
delete component.repeat.days;
|
||||
}
|
||||
}
|
||||
else {
|
||||
component.repeat = { frequency: this.repeat.frequency };
|
||||
}
|
||||
if (this.repeat.end == 'until' && this.repeat.until)
|
||||
component.repeat.until = this.repeat.until.stringWithSeparator('-');
|
||||
else if (this.repeat.end == 'count' && this.repeat.count)
|
||||
component.repeat.count = this.repeat.count;
|
||||
else {
|
||||
delete component.repeat.until;
|
||||
delete component.repeat.count;
|
||||
}
|
||||
|
||||
function formatTime(dateString) {
|
||||
// YYYY-MM-DDTHH:MM-05:00
|
||||
var date = new Date(dateString.substring(0,10) + ' ' + dateString.substring(11,16)),
|
||||
@@ -353,7 +416,6 @@
|
||||
|
||||
return hours + ':' + minutes;
|
||||
}
|
||||
|
||||
|
||||
return component;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
vm.calendars = stateCalendars;
|
||||
vm.event = stateComponent;
|
||||
vm.categories = {};
|
||||
vm.editRecurrence = editRecurrence;
|
||||
vm.showRecurrenceEditor = vm.event.$hasCustomRepeat;
|
||||
vm.toggleRecurrenceEditor = toggleRecurrenceEditor;
|
||||
vm.cancel = cancel;
|
||||
vm.save = save;
|
||||
|
||||
@@ -35,14 +36,9 @@
|
||||
}, 100); // don't ask why
|
||||
});
|
||||
|
||||
function editRecurrence($event) {
|
||||
$mdDialog.show({
|
||||
templateUrl: 'editRecurrence', // UI/Templates/SchedulerUI/UIxRecurrenceEditor.wox
|
||||
controller: RecurrenceController
|
||||
});
|
||||
function RecurrenceController() {
|
||||
|
||||
}
|
||||
function toggleRecurrenceEditor() {
|
||||
vm.showRecurrenceEditor = !vm.showRecurrenceEditor;
|
||||
vm.event.$hasCustomRepeat = vm.showRecurrenceEditor;
|
||||
}
|
||||
|
||||
function save(form) {
|
||||
|
||||
@@ -32,3 +32,9 @@ md-content {
|
||||
padding: $mg;
|
||||
}
|
||||
}
|
||||
|
||||
.sg-subcontent {
|
||||
border-left: $baseline-grid solid sg-color($sogoGreen, 100);
|
||||
margin-left: ($baseline-grid / 2);
|
||||
padding-left: $baseline-grid;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/*! input/_extends.scss - */
|
||||
@import '../../../angular-material/src/components/input/input.scss';
|
||||
@@ -1,97 +1,14 @@
|
||||
/// input.scss -*- Mode: text; indent-tabs-mode: nil; basic-offset: 2 -*-
|
||||
$input-container-padding: 2px !default;
|
||||
/// input.scss -*- Mode: scss; indent-tabs-mode: nil; basic-offset: 2 -*-
|
||||
@import 'extends';
|
||||
|
||||
$input-label-default-offset: 24px !default;
|
||||
$input-label-default-scale: 1.0 !default;
|
||||
$input-label-float-offset: 4px !default;
|
||||
$input-label-float-scale: 0.75 !default;
|
||||
|
||||
$input-border-width-default: 1px !default;
|
||||
$input-border-width-focused: 2px !default;
|
||||
$input-line-height: 26px !default;
|
||||
$input-padding-top: 2px !default;
|
||||
|
||||
md-input-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
padding: $input-container-padding;
|
||||
|
||||
textarea,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"],
|
||||
input[type="date"],
|
||||
input[type="month"],
|
||||
input[type="time"],
|
||||
input[type="week"],
|
||||
input[type="number"],
|
||||
input[type="email"],
|
||||
input[type="url"],
|
||||
input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="color"] {
|
||||
/* remove default appearance from all input/textarea */
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
textarea {
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
label {
|
||||
order: 1;
|
||||
pointer-events: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
z-index: 1;
|
||||
transform: translate3d(0, $input-label-default-offset, 0) scale($input-label-default-scale);
|
||||
transform-origin: left top;
|
||||
transition: all $swift-ease-out-timing-function 0.2s;
|
||||
}
|
||||
|
||||
/*
|
||||
* The .md-input class is added to the input/textarea
|
||||
*/
|
||||
.md-input {
|
||||
flex: 1;
|
||||
order: 2;
|
||||
display: block;
|
||||
|
||||
background: none;
|
||||
padding-top: $input-padding-top;
|
||||
padding-bottom: $input-border-width-focused - $input-border-width-default;
|
||||
border-width: 0 0 $input-border-width-default 0;
|
||||
line-height: $input-line-height;
|
||||
-ms-flex-preferred-size: $input-line-height; //IE fix
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.md-input-focused,
|
||||
&.md-input-has-value {
|
||||
label {
|
||||
transform: translate3d(0,$input-label-float-offset,0) scale($input-label-float-scale);
|
||||
}
|
||||
}
|
||||
&.md-input-focused {
|
||||
.md-input {
|
||||
padding-bottom: 0px; // Increase border width by 1px, decrease padding by 1
|
||||
border-width: 0 0 $input-border-width-focused 0;
|
||||
}
|
||||
}
|
||||
|
||||
.md-input[disabled] {
|
||||
background-position: 0 bottom;
|
||||
// This background-size is coordinated with a linear-gradient set in input-theme.scss
|
||||
// to create a dotted line under the input.
|
||||
background-size: 3px 1px;
|
||||
background-repeat: repeat-x;
|
||||
md-input-container.md-input-number {
|
||||
flex-grow: 0;
|
||||
width: 4em;
|
||||
input {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
md-input-container .bgroup {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -68,10 +68,6 @@ $input-padding-top: 2px !default;
|
||||
|
||||
.pseudo-input-field {
|
||||
display: block;
|
||||
margin-bottom: $line;
|
||||
padding: $line 0 0 0;
|
||||
font-size: sg-size(subhead);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.pseudo-input-field--underline {
|
||||
|
||||
@@ -5,6 +5,13 @@ md-select {
|
||||
margin-right: $bl;
|
||||
}
|
||||
|
||||
// Try to align select labels with other input components
|
||||
[layout="row"] {
|
||||
.md-select-label {
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
// angular material overqualifies, so we are
|
||||
md-select.md-default-theme.sg-toolbar-sort {
|
||||
margin: 0 $bl 4px 0;
|
||||
|
||||
Reference in New Issue
Block a user