WIP converting filesystem templates to new syntax

- basically commiting what the preprocessor currently generates for the client-side
- server-side need to understand new syntax (et2-prefix and camelCase attribute-names) too
- preprocessor can now be called as cli to either echo-out the new template or replace in-place
- for now only modified edit-templates of addressbook, infolog and timesheet
- setting a new (not yet existing) DTD
This commit is contained in:
ralf 2023-01-01 11:49:31 -06:00
parent 9dff888436
commit fefe82162e
18 changed files with 547 additions and 528 deletions

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
<overlay>
<template id="addressbook.editname" template="" lang="" group="0" version="1.9.001">
<grid class="editname">
@ -10,35 +9,28 @@
</columns>
<rows>
<row>
<description for="n_prefix" value="prefix"/>
<textbox id="n_prefix" tabindex="1" onchange="app.addressbook.check_value(widget,'$cont[id]');"
maxlength="64" autocomplete="honorific-prefix"/>
<et2-description for="n_prefix" value="prefix"></et2-description>
<et2-textbox id="n_prefix" tabindex="1" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="64" autocomplete="honorific-prefix"></et2-textbox>
</row>
<row>
<description for="n_given" value="first name"/>
<textbox id="n_given" tabindex="2" onchange="app.addressbook.check_value(widget,'$cont[id]');"
maxlength="64" autocomplete="given-name"/>
<et2-description for="n_given" value="first name"></et2-description>
<et2-textbox id="n_given" tabindex="2" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="64" autocomplete="given-name"></et2-textbox>
</row>
<row>
<description for="n_middle" value="middle name"/>
<textbox id="n_middle" tabindex="3" onchange="app.addressbook.check_value(widget,'$cont[id]');"
maxlength="64" autocomplete="additional-name"/>
<et2-description for="n_middle" value="middle name"></et2-description>
<et2-textbox id="n_middle" tabindex="3" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="64" autocomplete="additional-name"></et2-textbox>
</row>
<row>
<description for="n_family" value="last name"/>
<textbox id="n_family" tabindex="4" onchange="app.addressbook.check_value(widget,'$cont[id]');"
maxlength="64" autocomplete="family-name"/>
<et2-description for="n_family" value="last name"></et2-description>
<et2-textbox id="n_family" tabindex="4" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="64" autocomplete="family-name"></et2-textbox>
</row>
<row>
<description for="n_suffix" value="suffix"/>
<textbox id="n_suffix" tabindex="5" onchange="app.addressbook.check_value(widget,'$cont[id]');"
maxlength="64" autocomplete="honorific-suffix"/>
<et2-description for="n_suffix" value="suffix"></et2-description>
<et2-textbox id="n_suffix" tabindex="5" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="64" autocomplete="honorific-suffix"></et2-textbox>
</row>
<row>
<description/>
<button label="Ok" tabindex="6" id="button[ok]" class="button_ok"
onclick="jQuery('table.editname').css('display','none'); jQuery('#'+form::name('org_name')).focus(); return false;"
image="check" background_image="1"/>
<et2-description></et2-description>
<et2-button label="Ok" tabindex="6" id="button[ok]" class="button_ok" onclick="jQuery('table.editname').css('display','none'); jQuery('#'+form::name('org_name')).focus(); return false;" image="check"></et2-button>
</row>
</rows>
</grid>
@ -54,101 +46,91 @@
</columns>
<rows>
<row>
<description for="role" value="Role"/>
<hbox>
<textbox id="role" tabindex="20" width="60%" maxlength="64" autocomplete="section-one"/>
<textbox id="room" tabindex="21" blur="Room"/>
</hbox>
<description/>
<description for="adr_one_street" value="street"/>
<textbox id="adr_one_street" tabindex="11" maxlength="64" autocomplete="address-line1"/>
<et2-description for="role" value="Role"></et2-description>
<et2-hbox>
<et2-textbox id="role" tabindex="20" width="60%" maxlength="64" autocomplete="section-one"></et2-textbox>
<et2-textbox id="room" tabindex="21" placeholder="Room"></et2-textbox>
</et2-hbox>
<et2-description></et2-description>
<et2-description for="adr_one_street" value="street"></et2-description>
<et2-textbox id="adr_one_street" tabindex="11" maxlength="64" autocomplete="address-line1"></et2-textbox>
</row>
<row>
<description for="assistent" value="Assistent"/>
<textbox id="assistent" tabindex="22"/>
<description/>
<description/>
<textbox statustext="address line 2" id="adr_one_street2" tabindex="12" maxlength="64"
autocomplete="address-line2"/>
<et2-description for="assistent" value="Assistent"></et2-description>
<et2-textbox id="assistent" tabindex="22"></et2-textbox>
<et2-description></et2-description>
<et2-description></et2-description>
<et2-textbox statustext="address line 2" id="adr_one_street2" tabindex="12" maxlength="64" autocomplete="address-line2"></et2-textbox>
</row>
<row disabled="@addr_format=city_state_postcode">
<description for="tel_assistent" value="Assistent phone"/>
<url-phone id="tel_assistent" tabindex="23"/>
<et2-description for="tel_assistent" value="Assistent phone"></et2-description>
<et2-url-phone id="tel_assistent" tabindex="23"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_assistent,&amp;hearts;"/>
<description for="adr_one_locality" value="city"/>
<hbox class="city_state_postcode">
<textbox statustext="ZIP Code" id="adr_one_postalcode" tabindex="13" width="24%" maxlength="64"
autocomplete="postal-code"/>
<textbox statustext="City" id="adr_one_locality" tabindex="14" maxlength="64"
autocomplete="address-level2"/>
</hbox>
set_value="tel_assistent" ro_true="&amp;hearts;" />
<et2-description for="adr_one_locality" value="city"></et2-description>
<et2-hbox class="city_state_postcode">
<et2-textbox statustext="ZIP Code" id="adr_one_postalcode" tabindex="13" width="24%" maxlength="64" autocomplete="postal-code"></et2-textbox>
<et2-textbox statustext="City" id="adr_one_locality" tabindex="14" maxlength="64" autocomplete="address-level2"></et2-textbox>
</et2-hbox>
</row>
<row disabled="@addr_format=city_state_postcode">
<description for="tel_fax" value="fax"/>
<url-fax id="tel_fax" tabindex="24" autocomplete="fax"/>
<et2-description for="tel_fax" value="fax"></et2-description>
<et2-url-fax id="tel_fax" tabindex="24" autocomplete="fax"></et2-url-fax>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_fax,&amp;hearts;"/>
<description for="adr_one_countryname" value="country"/>
<select-country id="adr_one_countrycode" tabindex="15" empty_label="Select one" allowFreeEntries="true" autocomplete="country"
onchange="app.addressbook.regionSetCountry"/>
set_value="tel_fax" ro_true="&amp;hearts;" />
<et2-description for="adr_one_countryname" value="country"></et2-description>
<et2-select-country id="adr_one_countrycode" tabindex="15" allowFreeEntries="true" autocomplete="country" onchange="app.addressbook.regionSetCountry" emptyLabel="Select one"></et2-select-country>
</row>
<row disabled="@addr_format=city_state_postcode">
<description for="tel_other" value="Other phone"/>
<url-phone id="tel_other" tabindex="25" autocomplete="tel"/>
<et2-description for="tel_other" value="Other phone"></et2-description>
<et2-url-phone id="tel_other" tabindex="25" autocomplete="tel"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_other,&amp;hearts;"/>
<description value="Region"/>
<select-state class="city_state_postcode" statustext="State" country_code="$cont[adr_one_countrycode]" allowFreeEntries="true"
empty_label="Select one" id="adr_one_region" tabindex="16" maxlength="64"/>
set_value="tel_other" ro_true="&amp;hearts;" />
<et2-description value="Region"></et2-description>
<et2-select-state class="city_state_postcode" statustext="State" allowFreeEntries="true" id="adr_one_region" tabindex="16" maxlength="64" countryCode="$cont[adr_one_countrycode]" emptyLabel="Select one"></et2-select-state>
</row>
<row disabled="!@addr_format=city_state_postcode">
<description for="tel_assistent" value="Assistent phone"/>
<url-phone id="tel_assistent" tabindex="23"/>
<et2-description for="tel_assistent" value="Assistent phone"></et2-description>
<et2-url-phone id="tel_assistent" tabindex="23"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_assistent,&amp;hearts;"/>
<description value="City"/>
<hbox>
<textbox statustext="City" id="adr_one_locality" maxlength="64" tabindex="13"
autocomplete="address-level2"/>
<select-state statustext="State" country_code="$cont[adr_one_countrycode]" id="adr_one_region" tabindex="14" allowFreeEntries="true"
empty_label="Select one" width="130"/>
<textbox statustext="ZIP Code" id="adr_one_postalcode" size="6" maxlength="64" tabindex="15"
autocomplete="postal-code"/>
</hbox>
set_value="tel_assistent" ro_true="&amp;hearts;" />
<et2-description value="City"></et2-description>
<et2-hbox>
<et2-textbox statustext="City" id="adr_one_locality" maxlength="64" tabindex="13" autocomplete="address-level2"></et2-textbox>
<et2-select-state statustext="State" id="adr_one_region" tabindex="14" allowFreeEntries="true" width="130" countryCode="$cont[adr_one_countrycode]" emptyLabel="Select one"></et2-select-state>
<et2-textbox statustext="ZIP Code" id="adr_one_postalcode" maxlength="64" tabindex="15" autocomplete="postal-code"></et2-textbox>
</et2-hbox>
</row>
<row disabled="!@addr_format=city_state_postcode">
<description for="tel_fax" value="fax"/>
<url-fax id="tel_fax" tabindex="24" autocomplete="fax"/>
<et2-description for="tel_fax" value="fax"></et2-description>
<et2-url-fax id="tel_fax" tabindex="24" autocomplete="fax"></et2-url-fax>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_fax,&amp;hearts;"/>
<description for="adr_one_countryname" value="country"/>
<select-country tabindex="16" id="adr_one_countrycode" allowFreeEntries="true" empty_label="Select one" autocomplete="country"
onchange="app.addressbook.regionSetCountry"/>
set_value="tel_fax" ro_true="&amp;hearts;" />
<et2-description for="adr_one_countryname" value="country"></et2-description>
<et2-select-country tabindex="16" id="adr_one_countrycode" allowFreeEntries="true" autocomplete="country" onchange="app.addressbook.regionSetCountry" emptyLabel="Select one"></et2-select-country>
</row>
<row disabled="!@addr_format=city_state_postcode">
<description for="tel_other" value="Other Phone"/>
<url-phone id="tel_other" tabindex="25" autocomplete="tel"/>
<et2-description for="tel_other" value="Other Phone"></et2-description>
<et2-url-phone id="tel_other" tabindex="25" autocomplete="tel"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_other,&amp;hearts;"/>
<description/>
<description/>
set_value="tel_other" ro_true="&amp;hearts;" />
<et2-description></et2-description>
<et2-description></et2-description>
</row>
<row>
<description for="tel_car" value="car phone"/>
<url-phone id="tel_car" tabindex="26"/>
<et2-description for="tel_car" value="car phone"></et2-description>
<et2-url-phone id="tel_car" tabindex="26"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_car,&amp;hearts;"/>
<description disabled="@no_tid" for="tid" value="Type"/>
<select id="tid" no_lang="1" onchange="1" disabled="@no_tid"/>
set_value="tel_car" ro_true="&amp;hearts;" />
<et2-description disabled="@no_tid" for="tid" value="Type"></et2-description>
<et2-select id="tid" onchange="1" disabled="@no_tid" noLang="1"></et2-select>
</row>
<row disabled="@shared_disabled" valign="top">
<vbox>
<description for="shared" value="Shared with"/>
<checkbox id="shared_writable" label="writable" statustext="Create new shares writable"/>
</vbox>
<taglist-account account_type="both" id="shared_values" multiple="true" span="all"
onchange="app.addressbook.shared_changed" select_options="@shared_options"/>
<et2-vbox>
<et2-description for="shared" value="Shared with"></et2-description>
<et2-checkbox id="shared_writable" label="writable" statustext="Create new shares writable"></et2-checkbox>
</et2-vbox>
<et2-select-account id="shared_values" multiple="true" span="all" onchange="app.addressbook.shared_changed" accountType="both" selectOptions="@shared_options"></et2-select-account>
</row>
</rows>
</grid>
@ -165,8 +147,8 @@
<rows>
<row valign="top">
<tree-cat id="cat_id_tree" options="13,,width:99%"/>
<taglist-cat id="cat_id" empty_label="Category" width="100%" height="195"/>
<description/>
<et2-select-cat id="cat_id" width="100%" height="195" multiple="true" placeholder="Category"></et2-select-cat>
<et2-description></et2-description>
<grid width="100%">
<columns>
<column width="92"/>
@ -174,38 +156,38 @@
</columns>
<rows>
<row valign="top">
<description value="Notes"/>
<textbox multiline="true" id="note" rows="10" height="100"/>
<et2-description value="Notes"></et2-description>
<et2-textarea id="note" rows="10" height="100"></et2-textarea>
</row>
<row disabled="@hidebuttons">
<description value="Last date"/>
<link id="last_link"/>
<et2-description value="Last date"></et2-description>
<et2-link id="last_link" app=""></et2-link>
</row>
<row disabled="@hidebuttons">
<description value="Next date"/>
<link id="next_link"/>
<et2-description value="Next date"></et2-description>
<et2-link id="next_link" app=""></et2-link>
</row>
<row valign="top" class="smime_section_border">
<description value="SMIME key"/>
<et2-description value="SMIME key"></et2-description>
<vfs-upload id="addressbook:$cont[id]:.files/smime-pubkey.crt"
accept=".crt,.pem,application/x-x509-ca-cert,application/x-x509-user-cert"
mime="/application\/(x-x509-(ca|user)|pkix)-cert/"
callback="addressbook.addressbook_ui.pubkey_uploaded"/>
</row>
<row valign="top">
<description value="PGP key"/>
<et2-description value="PGP key"></et2-description>
<vfs-upload id="addressbook:$cont[id]:.files/pgp-pubkey.asc"
accept=".asc,application/pgp-keys"
mime="/(application\/pgp-keys|text\/plain)/"
callback="addressbook.addressbook_ui.pubkey_uploaded"/>
</row>
<row valign="top">
<description for="pubkey" value="Public key"/>
<textbox multiline="true" id="pubkey" rows="4" resize_ratio="0"/>
<et2-description for="pubkey" value="Public key"></et2-description>
<et2-textarea id="pubkey" rows="4" resizeRatio="0"></et2-textarea>
</row>
</rows>
</grid>
<description/>
<et2-description></et2-description>
</row>
</rows>
</grid>
@ -222,99 +204,89 @@
</columns>
<rows>
<row>
<description for="tel_home" value="Home phone"/>
<url-phone id="tel_home" tabindex="27" autocomplete="section-two home tel"/>
<et2-description for="tel_home" value="Home phone"></et2-description>
<et2-url-phone id="tel_home" tabindex="27" autocomplete="section-two home tel"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_home,&amp;hearts;"/>
<description for="adr_two_street" tabindex="32" value="street"/>
<textbox id="adr_two_street" tabindex="33" maxlength="64" autocomplete="section-two address-line1"/>
<description/>
set_value="tel_home" ro_true="&amp;hearts;" />
<et2-description for="adr_two_street" tabindex="32" value="street"></et2-description>
<et2-textbox id="adr_two_street" tabindex="33" maxlength="64" autocomplete="section-two address-line1"></et2-textbox>
<et2-description></et2-description>
</row>
<row>
<description for="tel_cell_private" value="mobile phone"/>
<url-phone id="tel_cell_private" tabindex="28" autocomplete="section-two mobile tel"/>
<et2-description for="tel_cell_private" value="mobile phone"></et2-description>
<et2-url-phone id="tel_cell_private" tabindex="28" autocomplete="section-two mobile tel"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_cell_private,&amp;hearts;"/>
<description/>
<textbox statustext="address line 2" id="adr_two_street2" tabindex="34" maxlength="64"
autocomplete="section-two address-line2"/>
<description/>
set_value="tel_cell_private" ro_true="&amp;hearts;" />
<et2-description></et2-description>
<et2-textbox statustext="address line 2" id="adr_two_street2" tabindex="34" maxlength="64" autocomplete="section-two address-line2"></et2-textbox>
<et2-description></et2-description>
</row>
<row disabled="@addr_format=city_state_postcode">
<description for="tel_fax_home" value="fax"/>
<url-fax id="tel_fax_home" tabindex="29" autocomplete="section-two fax tel"/>
<et2-description for="tel_fax_home" value="fax"></et2-description>
<et2-url-fax id="tel_fax_home" tabindex="29" autocomplete="section-two fax tel"></et2-url-fax>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_fax_home,&amp;hearts;"/>
<description for="adr_two_locality" value="city"/>
<hbox class="city_state_postcode">
<textbox statustext="ZIP Code" id="adr_two_postalcode" tabindex="34" width="24%" maxlength="64"
autocomplete="section-two postal-code"/>
<textbox statustext="City" id="adr_two_locality" maxlength="64" tabindex="36"
autocomplete="section-two address-level2"/>
</hbox>
<description/>
set_value="tel_fax_home" ro_true="&amp;hearts;" />
<et2-description for="adr_two_locality" value="city"></et2-description>
<et2-hbox class="city_state_postcode">
<et2-textbox statustext="ZIP Code" id="adr_two_postalcode" tabindex="34" width="24%" maxlength="64" autocomplete="section-two postal-code"></et2-textbox>
<et2-textbox statustext="City" id="adr_two_locality" maxlength="64" tabindex="36" autocomplete="section-two address-level2"></et2-textbox>
</et2-hbox>
<et2-description></et2-description>
</row>
<row disabled="@addr_format=city_state_postcode">
<description for="tel_pager" value="pager" autocomplete="section-two pager tel"/>
<url-phone id="tel_pager" tabindex="30"/>
<et2-description for="tel_pager" value="pager" autocomplete="section-two pager tel"></et2-description>
<et2-url-phone id="tel_pager" tabindex="30"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_pager,&amp;hearts;"/>
<description for="adr_two_countryname" value="country"/>
<select-country tabindex="37" id="adr_two_countrycode" empty_label="Select one" allowFreeEntries="true" autocomplete="section-two country"
onchange="app.addressbook.regionSetCountry"/>
<description/>
set_value="tel_pager" ro_true="&amp;hearts;" />
<et2-description for="adr_two_countryname" value="country"></et2-description>
<et2-select-country tabindex="37" id="adr_two_countrycode" allowFreeEntries="true" autocomplete="section-two country" onchange="app.addressbook.regionSetCountry" emptyLabel="Select one"></et2-select-country>
<et2-description></et2-description>
</row>
<row disabled="@addr_format=city_state_postcode">
<description for="bday" value="Birthday"/>
<date id="bday" tabindex="31" options="Y-m-d" year_range="c-90:c+2"/>
<description/>
<description value="Region"/>
<select-state statustext="State" country_code="$cont[adr_two_countrycode]" id="adr_two_region" tabindex="38" allowFreeEntries="true"
empty_label="Select one" maxlength="64" class="city_state_postcode"/>
<description/>
<et2-description for="bday" value="Birthday"></et2-description>
<et2-date id="bday" tabindex="31" dataFormat="Y-m-d" yearRange="c-90:c+2"></et2-date>
<et2-description></et2-description>
<et2-description value="Region"></et2-description>
<et2-select-state statustext="State" id="adr_two_region" tabindex="38" allowFreeEntries="true" maxlength="64" class="city_state_postcode" countryCode="$cont[adr_two_countrycode]" emptyLabel="Select one"></et2-select-state>
<et2-description></et2-description>
</row>
<row disabled="!@addr_format=city_state_postcode">
<description for="tel_fax_home" value="fax"/>
<url-fax id="tel_fax_home" autocomplete="fax tel"/>
<et2-description for="tel_fax_home" value="fax"></et2-description>
<et2-url-fax id="tel_fax_home" autocomplete="fax tel"></et2-url-fax>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_fax_home,&amp;hearts;"/>
<description value="City"/>
<hbox>
<textbox statustext="City" id="adr_two_locality" maxlength="64"
autocomplete="section-two address-level2"/>
<select-state country_code="$cont[adr_one_countrycode]" statustext="State" id="adr_two_region" allowFreeEntries="true"
empty_label="Select one" width="130" autocomplete="section-two address-level1"/>
<textbox statustext="ZIP Code" id="adr_two_postalcode" size="6" maxlength="64"
autocomplete="section-two postal-code"/>
</hbox>
<description/>
set_value="tel_fax_home" ro_true="&amp;hearts;" />
<et2-description value="City"></et2-description>
<et2-hbox>
<et2-textbox statustext="City" id="adr_two_locality" maxlength="64" autocomplete="section-two address-level2"></et2-textbox>
<et2-select-state statustext="State" id="adr_two_region" allowFreeEntries="true" width="130" autocomplete="section-two address-level1" countryCode="$cont[adr_one_countrycode]" emptyLabel="Select one"></et2-select-state>
<et2-textbox statustext="ZIP Code" id="adr_two_postalcode" maxlength="64" autocomplete="section-two postal-code"></et2-textbox>
</et2-hbox>
<et2-description></et2-description>
</row>
<row disabled="!@addr_format=city_state_postcode">
<description for="tel_pager" value="pager"/>
<url-phone id="tel_pager"/>
<et2-description for="tel_pager" value="pager"></et2-description>
<et2-url-phone id="tel_pager"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_pager,&amp;hearts;"/>
<description for="adr_two_countryname" value="country"/>
<select-country id="adr_two_countrycode" allowFreeEntries="true" empty_label="Select one" autocomplete="section-two country"
onchange="app.addressbook.regionSetCountry"/>
<description/>
set_value="tel_pager" ro_true="&amp;hearts;" />
<et2-description for="adr_two_countryname" value="country"></et2-description>
<et2-select-country id="adr_two_countrycode" allowFreeEntries="true" autocomplete="section-two country" onchange="app.addressbook.regionSetCountry" emptyLabel="Select one"></et2-select-country>
<et2-description></et2-description>
</row>
<row disabled="!@addr_format=city_state_postcode">
<description for="bday" value="Birthday"/>
<date id="bday" options="Y-m-d"/>
<description/>
<description/>
<description/>
<description/>
<et2-description for="bday" value="Birthday"></et2-description>
<et2-date id="bday" dataFormat="Y-m-d" ></et2-date>
<et2-description></et2-description>
<et2-description></et2-description>
<et2-description></et2-description>
<et2-description></et2-description>
</row>
<row>
<description for="email_home" value="EMail"/>
<url-email id="email_home" tabindex="32" onchange="app.addressbook.check_value(widget,'$cont[id]');"
autocomplete="section-two home email"/>
<description/>
<description for="url_home" value="URL"/>
<url id="url_home" tabindex="39" autocomplete="section-two url"/>
<description/>
<et2-description for="email_home" value="EMail"></et2-description>
<et2-url-email id="email_home" tabindex="32" onchange="app.addressbook.check_value(widget,'$cont[id]');" autocomplete="section-two home email"></et2-url-email>
<et2-description></et2-description>
<et2-description for="url_home" value="URL"></et2-description>
<et2-url id="url_home" tabindex="39" autocomplete="section-two url"></et2-url>
<et2-description></et2-description>
</row>
</rows>
</grid>
@ -326,31 +298,31 @@
</columns>
<rows>
<row>
<link-to id="link_to"/>
<et2-link-to id="link_to"></et2-link-to>
</row>
<row class="th">
<description value="Existing links"/>
<et2-description value="Existing links"></et2-description>
</row>
<row>
<link-list id="link_to"/>
<et2-link-list id="link_to"></et2-link-list>
</row>
</rows>
</grid>
</template>
<template id="addressbook.edit.distribution_list" template="" lang="" group="0" version="1.9.001">
<box width="100%" overflow="auto">
<description id="distrib_lists" span="all"/>
</box>
<et2-box width="100%" overflow="auto">
<et2-description id="distrib_lists" span="all"></et2-description>
</et2-box>
</template>
<template id="addressbook.edit.custom" template="" lang="" group="0" version="1.9.001">
<box width="100%" overflow="auto">
<customfields options=",$cont[no_private_cfs]" type_filter="$cont[tid]"/>
</box>
<et2-box width="100%" overflow="auto">
<customfields use-private="$cont[no_private_cfs]" type_filter="$cont[tid]"/>
</et2-box>
</template>
<template id="addressbook.edit.custom_private" template="" lang="" group="0" version="1.9.001">
<box width="100%" overflow="auto">
<customfields id="private_cfs" options=",1" type_filter="$cont[tid]"/>
</box>
<et2-box width="100%" overflow="auto">
<customfields id="private_cfs" use-private="1" type_filter="$cont[tid]"/>
</et2-box>
</template>
<template id="addressbook.edit.history" template="" lang="" group="0" version="1.9.001">
<historylog id="history" width="100%"/>
@ -368,51 +340,45 @@
</columns>
<rows>
<row class="dialogHeader">
<box align="center">
<hbox disabled="@hidebuttons">
<avatar id="jpegphoto" contactId="$cont[id]" src="$cont[photo]" crop="false"
editable="true"/>
</hbox>
</box>
<textbox id="n_fn" blur="Name" no_lang="1" tabindex="-1" class="cursorHand"
onclick="jQuery('table.editname').css('display','inline'); var focElem = document.getElementById(form::name('n_prefix')); if (!(typeof(focElem) == 'undefined') &amp;&amp; typeof(focElem.focus)=='function') document.getElementById(form::name('n_prefix')).focus();"
autocomplete="name"/>
<description/>
<description for="org_name" value="Organisation"/>
<textbox id="org_name" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="128"
tabindex="7" autocomplete="organization"/>
<appicon/>
<et2-box align="center">
<et2-hbox disabled="@hidebuttons">
<et2-avatar id="jpegphoto" contactId="$cont[id]" src="$cont[photo]" crop="false" editable="true"></et2-avatar>
</et2-hbox>
</et2-box>
<et2-textbox id="n_fn" tabindex="-1" class="cursorHand" onclick="jQuery('table.editname').css('display','inline'); var focElem = document.getElementById(form::name('n_prefix')); if (!(typeof(focElem) == 'undefined') &amp;&amp; typeof(focElem.focus)=='function') document.getElementById(form::name('n_prefix')).focus();" autocomplete="name" placeholder="Name" noLang="1"></et2-textbox>
<et2-description></et2-description>
<et2-description for="org_name" value="Organisation"></et2-description>
<et2-textbox id="org_name" onchange="app.addressbook.check_value(widget,'$cont[id]');" maxlength="128" tabindex="7" autocomplete="organization"></et2-textbox>
<et2-appicon></et2-appicon>
</row>
<row class="dialogHeader2">
<description for="tel_work" value="Business phone"/>
<url-phone id="tel_work" tabindex="17" class="telNumbers" autocomplete="work tel"/>
<et2-description for="tel_work" value="Business phone"></et2-description>
<et2-url-phone id="tel_work" tabindex="17" class="telNumbers" autocomplete="work tel"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_work,&amp;hearts;"/>
<description for="org_unit" value="department"/>
<textbox id="org_unit" onchange="app.addressbook.check_value(widget,'$cont[id]');" tabindex="8"
maxlength="64"/>
<description/>
set_value="tel_work" ro_true="&amp;hearts;" />
<et2-description for="org_unit" value="department"></et2-description>
<et2-textbox id="org_unit" onchange="app.addressbook.check_value(widget,'$cont[id]');" tabindex="8" maxlength="64"></et2-textbox>
<et2-description></et2-description>
</row>
<row class="dialogHeader3">
<description for="tel_cell" value="mobile phone"/>
<url-phone id="tel_cell" tabindex="18" class="telNumbers" autocomplete="mobile tel"/>
<et2-description for="tel_cell" value="mobile phone"></et2-description>
<et2-url-phone id="tel_cell" tabindex="18" class="telNumbers" autocomplete="mobile tel"></et2-url-phone>
<radio statustext="select phone number as prefered way of contact" id="tel_prefer"
options="tel_cell,&amp;hearts;"/>
<description for="title" value="Title"/>
<textbox id="title" maxlength="64" tabindex="9" autocomplete="organization-title"/>
<description/>
set_value="tel_cell" ro_true="&amp;hearts;" />
<et2-description for="title" value="Title"></et2-description>
<et2-textbox id="title" maxlength="64" tabindex="9" autocomplete="organization-title"></et2-textbox>
<et2-description></et2-description>
</row>
<row class="dialogHeader4">
<description for="email" value="email"/>
<url-email id="email" onchange="app.addressbook.check_value(widget,'$cont[id]');" tabindex="19"
autocomplete="work email"/>
<description/>
<description for="url" value="url"/>
<url id="url" tabindex="10" autocomplete="url"/>
<description/>
<et2-description for="email" value="email"></et2-description>
<et2-url-email id="email" onchange="app.addressbook.check_value(widget,'$cont[id]');" tabindex="19" autocomplete="work email"></et2-url-email>
<et2-description></et2-description>
<et2-description for="url" value="url"></et2-description>
<et2-url id="url" tabindex="10" autocomplete="url"></et2-url>
<et2-description></et2-description>
</row>
<row>
<tabbox id="tabs" span="all" width="100%" tab_height="320">
<et2-tabbox id="tabs" span="all" width="100%" tabHeight="320">
<tabs>
<tab id="general" label="Organisation"/>
<tab id="home" label="Private" statustext="Home address, Birthday, ..."/>
@ -434,63 +400,51 @@
<template id="addressbook.edit.custom_private"/>
<template id="addressbook.edit.history"/>
</tabpanels>
</tabbox>
</et2-tabbox>
</row>
<row class="dialogOperators">
<description value="Addressbook"/>
<select class="owner" statustext="Addressbook the contact should be saved to"
id="owner" no_lang="1"
onchange="widget.getInstanceManager().submit(null,false,true); return false;"/>
<description/>
<description value="own sorting"/>
<menulist>
<menupopup blur="Name" id="fileas_type" no_lang="1" class="fileas"/>
</menulist>
<description/>
<et2-description value="Addressbook"></et2-description>
<et2-select class="owner" statustext="Addressbook the contact should be saved to" id="owner" onchange="widget.getInstanceManager().submit(null,false,true); return false;" noLang="1"></et2-select>
<et2-description></et2-description>
<et2-description value="own sorting"></et2-description>
<et2-select id="fileas_type" class="fileas" placeholder="Name" noLang="1"></et2-select>
<et2-description></et2-description>
</row>
<row class="dialogOperators">
<description value="Created"/>
<hbox width="100%">
<menulist>
<menupopup type="select-account" id="creator" readonly="true"/>
</menulist>
<date-time id="created" readonly="true" align="right"/>
</hbox>
<description/>
<description value="Last modified"/>
<hbox width="100%">
<menulist>
<menupopup type="select-account" id="modifier" readonly="true"/>
</menulist>
<date-time id="modified" readonly="true" align="right"/>
</hbox>
<description/>
<et2-description value="Created"></et2-description>
<et2-hbox width="100%">
<et2-select-account id="creator" readonly="true"></et2-select-account>
<et2-date-time id="created" readonly="true" align="right"></et2-date-time>
</et2-hbox>
<et2-description></et2-description>
<et2-description value="Last modified"></et2-description>
<et2-hbox width="100%">
<et2-select-account id="modifier" readonly="true"></et2-select-account>
<et2-date-time id="modified" readonly="true" align="right"></et2-date-time>
</et2-hbox>
<et2-description></et2-description>
</row>
<row disabled="@hidebuttons" class="dialogFooterToolbar">
<hbox span="all" width="100%">
<button accesskey="s" label="Save" id="button[save]" class="button_save" image="save" background_image="1"/>
<button label="Apply" id="button[apply]" class="button_apply" image="apply" background_image="1"/>
<button label="Cancel" id="button[cancel]" class="button_cancel" onclick="if($cont[view] || false) return true; window.close(); return false;" image="cancel" background_image="1"/>
<checkbox statustext="Apply changes to all members, whose fields have the same previous content" label="change all organisation members" id="change_org" span="all" disabled="@hide_change_org"/>
<button align="right" label="Delete" id="button[delete]" class="button_delete" onclick="et2_dialog.confirm(widget,'Do you really want to delete this contact?','Delete')" image="delete" background_image="1"/>
</hbox>
<et2-hbox span="all" width="100%">
<et2-button accesskey="s" label="Save" id="button[save]" class="button_save" image="save"></et2-button>
<et2-button label="Apply" id="button[apply]" class="button_apply" image="apply"></et2-button>
<et2-button label="Cancel" id="button[cancel]" class="button_cancel" onclick="if($cont[view] || false) return true; window.close(); return false;" image="cancel"></et2-button>
<et2-checkbox statustext="Apply changes to all members, whose fields have the same previous content" label="change all organisation members" id="change_org" span="all" disabled="@hide_change_org"></et2-checkbox>
<et2-button align="right" label="Delete" id="button[delete]" class="button_delete" onclick="et2_dialog.confirm(widget,'Do you really want to delete this contact?','Delete')" image="delete"></et2-button>
</et2-hbox>
</row>
<row disabled="!@showsearchbuttons" class="dialogOperators">
<hbox span="all">
<menulist>
<menupopup label="Operator" id="operator" no_lang="1"/>
</menulist>
<menulist>
<menupopup id="meth_select" no_lang="1"/>
</menulist>
</hbox>
<et2-hbox span="all">
<et2-select label="Operator" id="operator" noLang="1"></et2-select>
<et2-select id="meth_select" noLang="1"></et2-select>
</et2-hbox>
</row>
<row disabled="!@showsearchbuttons" class="dialogFooterToolbar">
<hbox span="all">
<button label="Search" id="button[search]" image="search" background_image="1"/>
<button label="Cancel" id="button[cancelsearch]" image="cancel" background_image="1"/>
</hbox>
<et2-hbox span="all">
<et2-button label="Search" id="button[search]" image="search"></et2-button>
<et2-button label="Cancel" id="button[cancelsearch]" image="cancel"></et2-button>
</et2-hbox>
</row>
</rows>
</grid>

View File

@ -34,31 +34,80 @@ $GLOBALS['egw_info'] = array(
);
$start = microtime(true);
include '../header.inc.php';
include dirname(__DIR__).'/header.inc.php';
send_template();
/**
* Give usage plus option error and exit
*
* @param string $prog
* @param string? $err
* @return void
*/
function usage($prog, $err=null)
{
error_log("Usage: $prog [(-i|--in-place)] <xet-file>\n");
error_log("\t convert <xet-file> to new syntax and output or replace it in-place.\n\n");
if ($err) error_log("$err\n\n");
exit;
}
function send_template()
{
$header_include = microtime(true);
if (PHP_SAPI === 'cli')
{
$in_place = false;
$args = $_SERVER['argv'];
$prog = array_shift($args);
while($args[0][0] === '-')
{
switch($arg = array_shift($args))
{
case '-i':
case '--in-place':
$in_place = true;
break;
default:
usage($prog, "Invalid argument '$arg'!");
}
if (count($args) !== 1)
{
usage($prog);
}
}
$fspath = array_shift($args);
if ($fspath[0] !== '/') $fspath = '/'.$fspath;
}
else
{
// release session, as we don't need it and it blocks parallel requests
$GLOBALS['egw']->session->commit_session();
header('Content-Type: application/xml; charset=UTF-8');
//$path = EGW_SERVER_ROOT.$_SERVER['PATH_INFO'];
$fspath = $_SERVER['PATH_INFO'];
}
// check for customized template in VFS
list(, $app, , $template, $name) = explode('/', $_SERVER['PATH_INFO']);
list(, $app, , $template, $name) = explode('/', $fspath);
$path = Api\Etemplate::rel2path(Api\Etemplate::relPath($app . '.' . basename($name, '.xet'), $template));
if(empty($path) || !file_exists($path) || !is_readable($path))
{
if (PHP_SAPI === 'cli')
{
usage("Path '$path' NOT found!");
}
else
{
http_response_code(404);
}
exit;
}
$cache = $GLOBALS['egw_info']['server']['temp_dir'].'/egw_cache/eT2-Cache-'.
$GLOBALS['egw_info']['server']['install_id'].'-'.str_replace('/', '-', $_SERVER['PATH_INFO']);
if (file_exists($cache) && filemtime($cache) > max(filemtime($path), filemtime(__FILE__)) &&
if (PHP_SAPI !== 'cli' && file_exists($cache) && filemtime($cache) > max(filemtime($path), filemtime(__FILE__)) &&
($str = file_get_contents($cache)) !== false)
{
$cache_read = microtime(true);
@ -452,8 +501,38 @@ function send_template()
}
// stop here for not existing file or path-traversal for both file and cache here
if(empty($str) || strpos($path, '..') !== false)
{
if (PHP_SAPI === 'cli')
{
usage("Path '$path' NOT found!");
}
else
{
http_response_code(404);
}
exit;
}
// remove old CSV Id
$str = trim(str_replace("<!-- \$Id$ -->\n", '', $str))."\n";
// replace DTD
$str = preg_replace('/^<!DOCTYPE.*>$/m',
'<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">', $str);
// cli just echos or updates the file
if (PHP_SAPI === 'cli')
{
if (!$in_place)
{
echo $str;
}
elseif (!is_writable($path) ||
!rename($path, dirname($path).'/'.basename($path, '.xet').'.old.xet') ||
file_put_contents($path, $str) !== strlen($str))
{
error_log("Error writing file '$path'!\n");
}
exit;
}

View File

@ -18,6 +18,8 @@ use ReflectionMethod;
/**
* eTemplate widget baseclass
*
* @property-read string $required check $attrs['required'] ?? $attrs['needed']
*/
class Widget
{
@ -50,10 +52,13 @@ class Widget
public $bool_attr_default = array(
'disabled' => null, // null = no default
'statustext_html' => false,
'statustextHtml' => false,
'no_lang' => false,
'noLang' => false,
// strictly speeding only for input widgets, but server-side input-widgets have a validation method, but no shared parent
'readonly' => null, // null = no default
'needed' => false,
'required' => false,
);
/**
@ -801,6 +806,21 @@ class Widget
}
}
/**
* Implement some (readonly) attributes
*
* @param $name
* @return void
*/
public function __get($name)
{
switch($name)
{
case 'required':
return $this->attrs['required'] ?? $this->attrs['needed'] ?? false;
}
}
/**
* Convert widget (incl. children) to xml
*

View File

@ -59,7 +59,7 @@ class Checkbox extends Etemplate\Widget
if (!isset($value)) return; // value not transmitted --> nothing to validate
$valid =& self::get_array($validated, $form_name, true);
if (!$value && $this->attrs['needed'])
if (!$value && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!'),'');
}
@ -75,9 +75,9 @@ class Checkbox extends Etemplate\Widget
// Expand any content stuff
$selected_value = self::expand_name($this->attrs[$value_attr], $expand['c'], $expand['row'], $expand['c_'], $expand['row_'],$expand['cont']);
}
if(array_key_exists('unselected_value',$this->attrs))
if(array_key_exists('unselectedValue',$this->attrs) || array_key_exists('unselected_value',$this->attrs))
{
$unselected_value = self::expand_name($this->attrs['unselected_value'], $expand['c'], $expand['row'], $expand['c_'], $expand['row_'],$expand['cont']);
$unselected_value = self::expand_name($this->attrs['unselectedValue'] ?? $this->attrs['unselected_value'], $expand['c'], $expand['row'], $expand['c_'], $expand['row_'],$expand['cont']);
}
}
if ($type == 'radio')

View File

@ -70,7 +70,7 @@ class Date extends Transformer
$form_name = self::form_name($cname, $this->id, $expand);
$value =& self::get_array(self::$request->content, $form_name, false, true);
if($this->type != 'date-duration' && $value)
if(!in_array($this->type, ['et2-date-duration', 'date-duration']) && $value)
{
$value = $this->format_date($value);
}
@ -115,14 +115,15 @@ class Date extends Transformer
return $value;
} // otherwise we will get current date or 1970-01-01 instead of an empty value
$format = $this->attrs['dataFormat'] ?? $this->attrs['data_format'];
// for DateTime objects (regular PHP and Api\DateTime ones), set user timezone
if($value instanceof \DateTime)
{
$date = Api\DateTime::server2user($value);
}
// if data_format given, try that first, before leaving it to Api\DateTime to figure it out
elseif (!empty($this->attrs['data_format']) && $this->attrs['data_format'] !== 'object' &&
($date = Api\DateTime::createFromFormat($this->attrs['data_format'], $value, Api\DateTime::$user_timezone)))
elseif (!empty($format) && $format !== 'object' &&
($date = Api\DateTime::createFromFormat($format, $value, Api\DateTime::$user_timezone)))
{
// set AND checked above
}
@ -130,7 +131,7 @@ class Date extends Transformer
{
$date = new Api\DateTime($value);
}
if($this->type === 'date-timeonly' && $date)
if (in_array($this->type, ['et2-date-timeonly', 'date-timeonly']) && $date)
{
$date->setDate(1970, 1, 1);
}
@ -185,7 +186,7 @@ class Date extends Transformer
}
}
if((string)$value === '' && $this->attrs['needed'])
if((string)$value === '' && $this->required)
{
self::set_validation_error($form_name, lang('Field must not be empty !!!'));
}
@ -265,12 +266,12 @@ class Date extends Transformer
// Not null, blank
$value = '';
}
elseif($date && empty($this->attrs['data_format'])) // integer timestamp
elseif($date && empty($this->attrs['data_format']) && empty($this->attrs['dataFormat'])) // integer timestamp
{
$valid = $date->format('ts');
}
// string with formatting letters like for php's date() method
elseif($date && ($valid = $date->format($this->attrs['data_format'])))
elseif($date && ($valid = $date->format($this->attrs['dataFormat'] ?? $this->attrs['data_format'])))
{
// Nothing to do here
}

View File

@ -42,7 +42,7 @@ class Description extends Etemplate\Widget
*/
public function beforeSendToClient($cname, array $expand=null)
{
if (!empty($this->attrs['activate_links']))
if (!empty($this->attrs['activate_links']) && !empty($this->attrs['activateLinks']))
{
$form_name = self::form_name($cname, $this->id, $expand);
$value =& self::get_array(self::$request->content, $form_name);

View File

@ -156,7 +156,7 @@ class HtmlArea extends Etemplate\Widget
{
$value = Api\Html\HtmLawed::purify(
self::get_array($content, $form_name),
$this->attrs['validation_rules']
$this->attrs['validationRules'] ?? $this->attrs['validation_rules']
);
}
$valid =& self::get_array($validated, $form_name, true);

View File

@ -69,7 +69,7 @@ class Link extends Etemplate\Widget
$form_name = self::form_name($cname, $this->id, $expand);
$value =& self::get_array(self::$request->content, $form_name, true);
if($value && !is_array($value) && !$this->attrs['only_app'])
if($value && !is_array($value) && !($this->attrs['onlyApp'] ?? $this->attrs['only_app']))
{
// Try to explode
if(count(explode(':',$value)) < 2)

View File

@ -60,7 +60,7 @@ class Customfilter extends Widget\Transformer
}
$form_name = self::form_name($cname, $this->id, $expand);
self::setElementAttribute($form_name, 'options', trim($this->attrs['widget_options']) != '' ? $this->attrs['widget_options'] : '');
self::setElementAttribute($form_name, 'options', trim($this->attrs['widgetOptions'] ?? $this->attrs['widget_options']) != '' ? ($this->attrs['widgetOptions'] ?? $this->attrs['widget_options']) : '');
self::setElementAttribute($form_name, 'type', $this->attrs['type']);
if($widget_type)

View File

@ -107,7 +107,7 @@ class Password extends Etemplate\Widget\Textbox
$value = Credentials::encrypt($value_in, 0, $encryption);
}
if ((string)$value === '' && $this->attrs['needed'])
if ((string)$value === '' && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!'),'');
}
@ -148,4 +148,4 @@ class Password extends Etemplate\Widget\Textbox
$response->data($decrypted);
}
}
Etemplate\Widget::registerWidget(__NAMESPACE__.'\\Password', array('passwd'));
Etemplate\Widget::registerWidget(__NAMESPACE__.'\\Password', ['et2-password', 'passwd']);

View File

@ -198,7 +198,7 @@ class Select extends Etemplate\Widget
if(count($allowed) > 0 && in_array($val, $allowed)) continue 2; // +1 for switch
// validate accounts independent of options know to server
$account_type = $this->attrs['account_type'] ? $this->attrs['account_type'] : 'accounts';
$account_type = $this->attrs['accountType'] ?? $this->attrs['account_type'] ?? 'accounts';
$type = $GLOBALS['egw']->accounts->exists($val);
//error_log(__METHOD__."($cname,...) form_name=$form_name, widget_type=$widget_type, account_type=$account_type, type=$type");
if (!$type || $type == 1 && in_array($account_type, array('groups', 'owngroups', 'memberships')) ||
@ -242,7 +242,7 @@ class Select extends Etemplate\Widget
}
}
}
if ($ok && $value === '' && $this->attrs['needed'])
if ($ok && $value === '' && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!',$value),'');
}
@ -378,9 +378,10 @@ class Select extends Etemplate\Widget
self::$request->sel_options[$form_name] = array_merge(self::$request->sel_options[$form_name], $type_options);
// if no_lang was modified, forward modification to the client
if ($no_lang != $this->attrs['no_lang'])
if ($no_lang != ($this->attrs['noLang'] ?? $this->attrs['no_lang']))
{
self::setElementAttribute($form_name, 'no_lang', $no_lang);
self::setElementAttribute($form_name, 'noLang', $no_lang);
}
}
$form_names_done[$form_name] = true;

View File

@ -61,7 +61,7 @@ class Tabbox extends Etemplate\Widget
$this->tabs_attr_evaluated = true; // we must not evaluate tabs attribte more then once!
// add_tabs toggles replacing or adding to existing tabs
if(!$this->attrs['add_tabs'])
if(!($this->attrs['addTabs'] ?? $this->attrs['add_tabs']))
{
$this->children[1]->children = array();
}

View File

@ -153,7 +153,7 @@ class Taglist extends Etemplate\Widget
// If in allowed options, skip account check to support app-specific options
if(count($allowed) > 0 && in_array($val, $allowed)) continue;
// validate accounts independent of options know to server
$account_type = $this->attrs['account_type'] ? $this->attrs['account_type'] : 'accounts';
$account_type = $this->attrs['accountType'] ?? $this->attrs['account_type'] ?? 'accounts';
$type = $GLOBALS['egw']->accounts->exists($val);
//error_log(__METHOD__."($cname,...) form_name=$form_name, widget_type=$widget_type, account_type=$account_type, type=$type");
if (!$type || $type == 1 && in_array($account_type, array('groups', 'owngroups', 'memberships')) ||
@ -179,7 +179,7 @@ class Taglist extends Etemplate\Widget
self::set_validation_error($form_name, lang("'%1' is NOT allowed ('%2')!", $val, implode("','", array_keys($allowed))), '');
unset($value[$key]);
}
if(str_contains($this->type, 'email') && $this->attrs['include_lists'] && is_numeric($val))
if(str_contains($this->type, 'email') && ($this->attrs['includeLists'] ?? $this->attrs['include_lists']) && is_numeric($val))
{
$lists = $GLOBALS['egw']->contacts->get_lists(Api\Acl::READ);
if(!array_key_exists($val, $lists))
@ -199,7 +199,7 @@ class Taglist extends Etemplate\Widget
}
}
}
if ($ok && $value === '' && $this->attrs['needed'])
if ($ok && $value === '' && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!',$value),'');
}

View File

@ -126,7 +126,7 @@ class Textbox extends Etemplate\Widget
$value = $value_in = self::get_array($content, $form_name);
if ((string)$value === '' && $this->attrs['needed'])
if ((string)$value === '' && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!'),'');
}
@ -153,7 +153,7 @@ class Textbox extends Etemplate\Widget
}
elseif ($this->attrs['type'] == 'integer' || $this->attrs['type'] == 'float') // cast int and float and check range
{
if ((string)$value !== '' || $this->attrs['needed']) // empty values are Ok if needed is not set
if ((string)$value !== '' || $this->required) // empty values are Ok if needed is not set
{
$value = $this->attrs['type'] == 'integer' ? (int) $value : (float) str_replace(',','.',$value); // allow for german (and maybe other) format

View File

@ -278,7 +278,7 @@ class Tree extends Etemplate\Widget
}
$value = implode(',',$value);
}
if ($ok && $value === '' && $this->attrs['needed'])
if ($ok && $value === '' && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!',$value),'');
}
@ -297,8 +297,9 @@ class Tree extends Etemplate\Widget
{
$form_name = self::form_name($cname, $this->id);
if (($templated_path = self::templateImagePath($this->attrs['image_path'] ?? null)) !== ($this->attrs['image_path'] ?? null))
if (($templated_path = self::templateImagePath($this->attrs['imagePath'] ?? $this->attrs['image_path'] ?? null)) !== ($this->attrs['imagePath'] ?? $this->attrs['image_path'] ?? null))
{
self::setElementAttribute($form_name, 'imagePath', $this->attrs['imagePath'] = $templated_path);
self::setElementAttribute($form_name, 'image_path', $this->attrs['image_path'] = $templated_path);
//error_log(__METHOD__."() setting templated image-path for $form_name: $templated_path");
}

View File

@ -73,7 +73,7 @@ class Url extends Etemplate\Widget
{
$value = $value_in = self::get_array($content, $form_name);
if ((string)$value === '' && $this->attrs['needed'])
if ((string)$value === '' && $this->required)
{
self::set_validation_error($form_name,lang('Field must not be empty !!!'),'');
return;
@ -85,7 +85,7 @@ class Url extends Etemplate\Widget
{
case 'url':
$this->attrs['preg'] = self::URL_PREG;
if($this->attrs['allow_path'])
if($this->attrs['allowPath'] ?? $this->attrs['allow_path'])
{
$url_valid = $value[0] === '/';
@ -103,10 +103,10 @@ class Url extends Etemplate\Widget
// Remove intl chars & check again, but if it passes we'll keep the original
filter_var(preg_replace('/[^[:print:]]/','',$value), FILTER_VALIDATE_URL);
}
if(array_key_exists('trailing_slash', $this->attrs))
if(array_key_exists('trailing_slash', $this->attrs) || array_key_exists('trailingSlash', $this->attrs))
{
$trailing_slash = substr($value, -1) === '/';
$url_valid = (($this->attrs['trailing_slash'] == 'true') == $trailing_slash);
$url_valid = ((($this->attrs['trailingSlash'] ?? $this->attrs['trailing_slash']) == 'true') == $trailing_slash);
}
//error_log(__METHOD__."() filter_var(value=".array2string($value).", FILTER_VALIDATE_URL)=".array2string(filter_var($value, FILTER_VALIDATE_URL))." --> url_valid=".array2string($url_valid));
// remove http:// validation prefix again

View File

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
<overlay>
<template id="infolog.edit.description" template="" lang="" group="0" version="1.6.001">
<textbox id="info_des" no_lang="1" multiline="true"/>
<checkbox id="clean_history"/>
<et2-textarea id="info_des" noLang="1"></et2-textarea>
<et2-checkbox id="clean_history"></et2-checkbox>
</template>
<template id="infolog.edit.links" template="" lang="" group="0" version="1.3.001">
<grid width="100%" overflow="auto">
@ -14,13 +13,13 @@
</columns>
<rows>
<row class="row" disabled="@status_only">
<link-to id="link_to" span="all"/>
<et2-link-to id="link_to" span="all"></et2-link-to>
</row>
<row class="th">
<description value="Existing links" span="all"/>
<et2-description value="Existing links" span="all"></et2-description>
</row>
<row class="row_off" valign="top">
<link-list id="link_to" span="all"/>
<et2-link-list id="link_to" span="all"></et2-link-list>
</row>
</rows>
</grid>
@ -35,32 +34,32 @@
</columns>
<rows>
<row class="row">
<description value="Project"/>
<link-entry span="2" id="pm_id" only_app="projectmanager" onchange="app.infolog.submit_if_not_empty" blur="None" class="infolog_projectName"/>
<description/>
<et2-description value="Project"></et2-description>
<et2-link-entry span="2" id="pm_id" onchange="app.infolog.submit_if_not_empty" class="infolog_projectName" onlyApp="projectmanager" placeholder="None"></et2-link-entry>
<et2-description></et2-description>
</row>
<row class="row">
<description value="Price"/>
<et2-description value="Price"></et2-description>
<projectmanager-pricelist id="pl_id"
onchange="window.app.infolog.et2.getWidgetById('info_price').set_value(this.options[this.selectedIndex].text.lastIndexOf('(') &lt; 0 ? '' : this.options[this.selectedIndex].text.slice(this.options[this.selectedIndex].text.lastIndexOf('(')+1,-1));"
emptyLabel="None" class="et2_fullWidth"/>
<textbox type="float" id="info_price" class="et2_fullWidth"/>
<description/>
<et2-number id="info_price"></et2-number>
<et2-description></et2-description>
</row>
<row class="row">
<description value="planned time" for="info_planned_time"/>
<date-duration span="2" id="info_planned_time" display_format="$cont[duration_format]" class="infolog_date_duration et2_fullWidth" hours_per_day="$cont[hours_per_workday]"/>
<description/>
<et2-description value="planned time" for="info_planned_time"></et2-description>
<et2-date-duration span="2" id="info_planned_time" class="infolog_date_duration" displayFormat="$cont[duration_format]" hoursPerDay="$cont[hours_per_workday]"></et2-date-duration>
<et2-description></et2-description>
</row>
<row class="row">
<description value="Re-planned time" for="info_replanned_time"/>
<date-duration span="2" id="info_replanned_time" display_format="$cont[duration_format]" class="infolog_date_duration et2_fullWidth" hours_per_day="$cont[hours_per_workday]"/>
<description/>
<et2-description value="Re-planned time" for="info_replanned_time"></et2-description>
<et2-date-duration span="2" id="info_replanned_time" class="infolog_date_duration" displayFormat="$cont[duration_format]" hoursPerDay="$cont[hours_per_workday]"></et2-date-duration>
<et2-description></et2-description>
</row>
<row class="row" valign="top" height="60%">
<description statustext="Leave blank to get the used time calculated by timesheet entries" value="used time" for="info_used_time"/>
<date-duration span="2" id="info_used_time" display_format="$cont[duration_format]" class="infolog_date_duration et2_fullWidth" hours_per_day="$cont[hours_per_workday]"/>
<description/>
<et2-description statustext="Leave blank to get the used time calculated by timesheet entries" value="used time" for="info_used_time"></et2-description>
<et2-date-duration span="2" id="info_used_time" class="infolog_date_duration" displayFormat="$cont[duration_format]" hoursPerDay="$cont[hours_per_workday]"></et2-date-duration>
<et2-description></et2-description>
</row>
</rows>
</grid>
@ -80,22 +79,17 @@
</columns>
<rows>
<row height="20" class="th">
<description value="Delegation" class="et2_fullWidth"/>
<description/>
<description value="Details" class="et2_fullWidth"/>
<et2-description value="Delegation"></et2-description>
<et2-description></et2-description>
<et2-description value="Details"></et2-description>
</row>
<row valign="top">
<vbox>
<taglist-email id="info_cc" class="et2-label-fixed" label="CC"/>
<et2-vbox>
<et2-select-email id="info_cc" class="et2-label-fixed" label="CC" multiple="true" searchUrl="EGroupware\Api\Etemplate\Widget\Taglist::ajax_email"></et2-select-email>
<taglist-account label="Responsible"
statustext="select a responsible user: a person you want to delegate this task"
id="info_responsible" rows="6" multiple="true" no_lang="1"
class="et2-label-fixed" account_type="both"
empty_label="Select users or groups"
onchange="app.infolog.onchangeResponsible"/>
</vbox>
<description/>
<et2-select-account label="Responsible" statustext="select a responsible user: a person you want to delegate this task" id="info_responsible" rows="6" multiple="1" class="et2-label-fixed" onchange="app.infolog.onchangeResponsible" placeholder="Select users or groups" noLang="1" accountType="both"></et2-select-account>
</et2-vbox>
<et2-description></et2-description>
<grid>
<columns>
<column width="120"/>
@ -103,40 +97,29 @@
</columns>
<rows>
<row>
<description value="Category" for="info_cat"/>
<menulist class="et2_fullWidth">
<menupopup type="select-cat" statustext="select a category for this entry"
id="info_cat" options="None"/>
</menulist>
<et2-description value="Category" for="info_cat"></et2-description>
<et2-select-cat statustext="select a category for this entry" id="info_cat" emptyLabel="None"></et2-select-cat>
</row>
<row>
<description value="Parent" font_style="1"/>
<link-entry id="info_id_parent"
onchange="if(egw &amp;&amp; widget) { if(widget._oldValue) window.opener.egw.dataStoreUID(egw.appName+&quot;::&quot;+widget._oldValue,false);window.opener.egw.dataStoreUID(egw.appName+&quot;::&quot;+widget.getValue(),false);}"
options="infolog" class="et2_fullWidth" query="app.infolog.parent_query"/>
<et2-description value="Parent" fontStyle="1"></et2-description>
<et2-link-entry id="info_id_parent" onchange="if(egw &amp;&amp; widget) { if(widget._oldValue) window.opener.egw.dataStoreUID(egw.appName+&quot;::&quot;+widget._oldValue,false);window.opener.egw.dataStoreUID(egw.appName+&quot;::&quot;+widget.getValue(),false);}" query="app.infolog.parent_query" onlyApp="infolog"></et2-link-entry>
</row>
<row class="row">
<description value="Priority" for="info_priority"/>
<menulist class="et2_fullWidth">
<menupopup statustext="select a priority for this task" id="info_priority"/>
</menulist>
<et2-description value="Priority" for="info_priority"></et2-description>
<et2-select statustext="select a priority for this task" id="info_priority"></et2-select>
</row>
<row>
<description value="Date completed" for="info_datecompleted"/>
<date-time
statustext="Date completed (leave it empty to have it automatic set if status is done or billed)"
id="info_datecompleted" onchange="app.infolog.statusChanged"
class="et2_fullWidth"/>
<et2-description value="Date completed" for="info_datecompleted"></et2-description>
<et2-date-time statustext="Date completed (leave it empty to have it automatic set if status is done or billed)" id="info_datecompleted" onchange="app.infolog.statusChanged"></et2-date-time>
</row>
<row class="row">
<description value="Location" for="info_location"/>
<textbox id="info_location" maxlength="255" class="et2_fullWidth"/>
<et2-description value="Location" for="info_location"></et2-description>
<et2-textbox id="info_location" maxlength="255"></et2-textbox>
</row>
<row>
<description value="Private" for="info_access"/>
<checkbox
statustext="should this entry only be visible to you and people you grant privat access via the ACL"
id="info_access" options="private,public"/>
<et2-description value="Private" for="info_access"></et2-description>
<et2-checkbox
statustext="should this entry only be visible to you and people you grant privat access via the ACL" id="info_access" selectedValue="private" unselectedValue="public" ></et2-checkbox>
</row>
</rows>
</grid>
@ -156,45 +139,39 @@
</columns>
<rows>
<row class="dialogHeader">
<description value="Title" for="info_subject"/>
<hbox span="4">
<textbox statustext="a short subject for the entry" id="info_subject" class="et2_fullWidth et2_required" maxlength="255" tabindex="1"></textbox>
<description id="info_id" readonly="true" width="5em"/>
</hbox>
<appicon src="infolog" for="info_id"/>
<et2-description value="Title" for="info_subject"></et2-description>
<et2-hbox span="4">
<et2-textbox statustext="a short subject for the entry" id="info_subject" class="et2_required" maxlength="255" tabindex="1"></et2-textbox>
<et2-description id="info_id" readonly="true" width="5em"></et2-description>
</et2-hbox>
<et2-appicon src="infolog" for="info_id"></et2-appicon>
</row>
<row class="dialogHeader2">
<description value="Type" for="info_type"/>
<select statustext="Type of the log-entry: Note, Phonecall or ToDo" id="info_type" no_lang="1" onchange="widget.getInstanceManager().submit(null,false,true); return false;" />
<description/>
<description value="Startdate" for="info_startdate"/>
<date-time id="info_startdate" class="et2_fullWidth"
statustext="when should the ToDo or Phonecall be started, it shows up from that date in the filter open or own open (startpage)"/>
<description/>
<et2-description value="Type" for="info_type"></et2-description>
<et2-select statustext="Type of the log-entry: Note, Phonecall or ToDo" id="info_type" onchange="widget.getInstanceManager().submit(null,false,true); return false;" noLang="1"></et2-select>
<et2-description></et2-description>
<et2-description value="Startdate" for="info_startdate"></et2-description>
<et2-date-time id="info_startdate" statustext="when should the ToDo or Phonecall be started, it shows up from that date in the filter open or own open (startpage)"></et2-date-time>
<et2-description></et2-description>
</row>
<row class="dialogHeader3">
<description value="Contact"/>
<link-entry id="info_contact" app_icons="true"/>
<description/>
<description value="Enddate" for="info_enddate"/>
<date-time statustext="til when should the ToDo or Phonecall be finished" id="info_enddate" class="et2_fullWidth"/>
<description/>
<et2-description value="Contact"></et2-description>
<et2-link-entry id="info_contact" appIcons="true"></et2-link-entry>
<et2-description></et2-description>
<et2-description value="Enddate" for="info_enddate"></et2-description>
<et2-date-time statustext="til when should the ToDo or Phonecall be finished" id="info_enddate"></et2-date-time>
<et2-description></et2-description>
</row>
<row class="et2_toolbar">
<description id="spacer" span="5"/>
<hbox class="tab_toolbar">
<et2-description id="spacer" span="5"></et2-description>
<et2-hbox class="tab_toolbar">
<timestamper parentId="infolog-edit_tabs" slot="nav"
statustext="Insert timestamp into description field" id="timestamp"
class="infologExtraButton infologTimestamp" target="info_des"/>
<buttononly parentId="infolog-edit_tabs" slot="nav" statustext="Encrypt description"
id="encrypt"
class="infologExtraButton infologEncrypt" background_image="1" image="lock"
onclick="app.infolog.toggleEncrypt"/>
</hbox>
<et2-button-timestamp parentId="infolog-edit_tabs" slot="nav" statustext="Insert timestamp into description field" id="timestamp" class="infologExtraButton infologTimestamp" target="info_des"></et2-button-timestamp>
<et2-button parentId="infolog-edit_tabs" slot="nav" statustext="Encrypt description" id="encrypt" class="infologExtraButton infologEncrypt" image="lock" onclick="app.infolog.toggleEncrypt" noSubmit="true"></et2-button>
</et2-hbox>
</row>
<row>
<tabbox id="tabs" span="all" width="100%" tab_height="350px">
<et2-tabbox id="tabs" span="all" width="100%" tabHeight="350px">
<tabs>
<tab id="description" label="Description" statustext="longer textual description"/>
<tab id="details" label="Details" statustext="Location, priority , ..."/>
@ -211,46 +188,39 @@
<template id="infolog.edit.customfields"/>
<template id="infolog.edit.history"/>
</tabpanels>
</tabbox>
</et2-tabbox>
</row>
<row class="dialogOperators">
<description value="Status" for="info_status"/>
<select class="et2_fullWidth" statustext="@status_help" id="info_status" onchange="app.infolog.statusChanged"/>
<description/>
<description value="Completed" for="info_percent"/>
<select-percent class="et2_fullWidth" statustext="Percent completed" id="info_percent" onchange="app.infolog.statusChanged"/>
<description/>
<et2-description value="Status" for="info_status"></et2-description>
<et2-select statustext="@status_help" id="info_status" onchange="app.infolog.statusChanged"></et2-select>
<et2-description></et2-description>
<et2-description value="Completed" for="info_percent"></et2-description>
<et2-select-percent statustext="Percent completed" id="info_percent" onchange="app.infolog.statusChanged"></et2-select-percent>
<et2-description></et2-description>
</row>
<row disabled="!@info_owner" class="dialogOperators">
<description value="Owner"/>
<hbox>
<select-account id="info_owner" readonly="true"/>
<date-time id="info_created" readonly="true" align="right"/>
</hbox>
<description/>
<description value="Last modified"/>
<hbox>
<select-account id="info_modifier" readonly="true"/>
<date-time id="info_datemodified" readonly="true" align="right"/>
</hbox>
<description/>
<et2-description value="Owner"></et2-description>
<et2-hbox>
<et2-select-account id="info_owner" readonly="true"></et2-select-account>
<et2-date-time id="info_created" readonly="true" align="right"></et2-date-time>
</et2-hbox>
<et2-description></et2-description>
<et2-description value="Last modified"></et2-description>
<et2-hbox>
<et2-select-account id="info_modifier" readonly="true"></et2-select-account>
<et2-date-time id="info_datemodified" readonly="true" align="right"></et2-date-time>
</et2-hbox>
<et2-description></et2-description>
</row>
<row class="dialogFooterToolbar">
<hbox span="all">
<button statustext="Saves this entry" label="Save" id="button[save]" image="save"
background_image="1"/>
<button statustext="Apply the changes" label="Apply" id="button[apply]" image="apply"
background_image="1"></button>
<button statustext="leave without saveing the entry" label="Cancel" id="button[cancel]"
onclick="window.close();" image="cancel" background_image="1"/>
<select statustext="Execute a further action for this entry" id="action"
onchange="app.infolog.edit_actions()" empty_label="Actions..."/>
<checkbox label="Do not notify" id="no_notifications"
statustext="Do not notify of these changes"/>
<button align="right" statustext="delete this entry" label="Delete" id="button[delete]"
onclick="if($cont[info_anz_subs]) return $cont[info_anz_subs]; et2_dialog.confirm(widget,'Delete this entry','Delete');"
image="delete" background_image="1"/>
</hbox>
<et2-hbox span="all">
<et2-button statustext="Saves this entry" label="Save" id="button[save]" image="save"></et2-button>
<et2-button statustext="Apply the changes" label="Apply" id="button[apply]" image="apply"></et2-button>
<et2-button statustext="leave without saveing the entry" label="Cancel" id="button[cancel]" onclick="window.close();" image="cancel"></et2-button>
<et2-select statustext="Execute a further action for this entry" id="action" onchange="app.infolog.edit_actions()" emptyLabel="Actions..."></et2-select>
<et2-checkbox label="Do not notify" id="no_notifications" statustext="Do not notify of these changes"></et2-checkbox>
<et2-button align="right" statustext="delete this entry" label="Delete" id="button[delete]" onclick="if($cont[info_anz_subs]) return $cont[info_anz_subs]; et2_dialog.confirm(widget,'Delete this entry','Delete');" image="delete"></et2-button>
</et2-hbox>
</row>
</rows>
</grid>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
<overlay>
<template id="timesheet.edit.general" template="" lang="" group="0" version="1.7.002">
<grid width="100%" >
@ -15,48 +14,46 @@
</columns>
<rows>
<row>
<description value="Project" for="ts_project"/>
<hbox disabled="@pm_integration=none">
<link-entry id="pm_id" onchange="app.timesheet.pm_id_changed" only_app='projectmanager' blur='None' class="et2_fullWidth" width="99%"/>
</hbox>
<description/>
<hbox disabled="@pm_integration=full" span="all">
<textbox blur="@ts_project_blur" id="ts_project" size="65" maxlength="80" class="et2_fullWidth"/>
</hbox>
<et2-description value="Project" for="ts_project"></et2-description>
<et2-hbox disabled="@pm_integration=none">
<et2-link-entry id="pm_id" onchange="app.timesheet.pm_id_changed" width="99%" onlyApp="projectmanager" placeholder="None"></et2-link-entry>
</et2-hbox>
<et2-description></et2-description>
<et2-hbox disabled="@pm_integration=full" span="all">
<et2-textbox id="ts_project" maxlength="80" placeholder="@ts_project_blur"></et2-textbox>
</et2-hbox>
</row>
<row disabled="@ts_viewtype">
<description value="Unitprice" for="ts_unitprice"/>
<hbox disabled="@pm_integration=none" >
<et2-description value="Unitprice" for="ts_unitprice"></et2-description>
<et2-hbox disabled="@pm_integration=none" >
<projectmanager-pricelist id="pl_id" class="et2_fullWidth"
onchange="window.app.timesheet.et2.getWidgetById('ts_unitprice').set_value(this.options[this.selectedIndex].text.lastIndexOf('(') &lt; 0 ? '' : this.options[this.selectedIndex].text.slice(this.options[this.selectedIndex].text.lastIndexOf('(')+1,-1));"
emptyLabel="None"/>
</hbox>
<description/>
<hbox disabled="@pm_integration=none">
<textbox type="float" id="ts_unitprice" span="all" class="et2_fullWidth"/>
</hbox>
</et2-hbox>
<et2-description></et2-description>
<et2-hbox disabled="@pm_integration=none">
<et2-number id="ts_unitprice" span="all"></et2-number>
</et2-hbox>
</row>
<row class="row" disabled="!@ts_viewtype">
<description value="comment"/>
<textbox multiline="true" id="ts_description_short" rows="5" cols="50" class="et2_fullWidth"/>
<description/>
<description/>
<description/>
<et2-description value="comment"></et2-description>
<et2-textarea id="ts_description_short" rows="5" cols="50"></et2-textarea>
<et2-description></et2-description>
<et2-description></et2-description>
<et2-description></et2-description>
</row>
<row class="row" disabled="@ts_viewtype">
<description value="Quantity" for="ts_quantity"/>
<textbox type="float" blur="@ts_quantity_blur" statustext="empty if identical to duration" id="ts_quantity" precision="3" class="et2_fullWidth"/>
<description/>
<description value="Category" for="cat_id"/>
<menulist span="all">
<menupopup type="select-cat" id="cat_id" options="None,,,timesheet" class="et2_fullWidth"/>
</menulist>
<et2-description value="Quantity" for="ts_quantity"></et2-description>
<et2-number statustext="empty if identical to duration" id="ts_quantity" precision="3" placeholder="@ts_quantity_blur"></et2-number>
<et2-description></et2-description>
<et2-description value="Category" for="cat_id"></et2-description>
<et2-select-cat span="all" id="cat_id" application="timesheet" emptyLabel="None"></et2-select-cat>
</row>
</rows>
</grid>
</template>
<template id="timesheet.edit.notes" template="" lang="" group="0" version="1.5.001">
<textbox multiline="true" id="ts_description" rows="9" cols="70" class="et2_fullWidth"/>
<et2-textarea id="ts_description" rows="9" cols="70"></et2-textarea>
</template>
<template id="timesheet.edit.links" template="" lang="" group="0" version="0.1.001">
<grid width="100%" overflow="auto">
@ -65,21 +62,21 @@
</columns>
<rows>
<row class="row" disabled="@status_only">
<link-to id="link_to"/>
<et2-link-to id="link_to"></et2-link-to>
</row>
<row class="th">
<description value="Existing links"/>
<et2-description value="Existing links"></et2-description>
</row>
<row class="row_off" >
<link-list id="link_to"/>
<et2-link-list id="link_to"></et2-link-list>
</row>
</rows>
</grid>
</template>
<template id="timesheet.edit.customfields" template="" lang="" group="0" version="1.5.001">
<box width="100%" overflow="auto">
<et2-box width="100%" overflow="auto">
<customfields class="et2_fullWidth"/>
</box>
</et2-box>
</template>
<template id="timesheet.edit.history" template="" lang="" group="0" version="1.7.001">
<historylog id="history"/>
@ -95,18 +92,18 @@
</columns>
<rows>
<row class="th">
<description value="Time"/>
<description value="Recorded"/>
<description value="Type"/>
<description value="Duration"/>
<description value="Sum"/>
<et2-description value="Time"></et2-description>
<et2-description value="Recorded"></et2-description>
<et2-description value="Type"></et2-description>
<et2-description value="Duration"></et2-description>
<et2-description value="Sum"></et2-description>
</row>
<row>
<date-time id="${row}[tse_time]" readonly="true"/>
<date-time id="${row}[tse_timestamp]" readonly="true"/>
<select id="${row}[tse_type]" readonly="true"/>
<date-duration display_format="h:m" data_format="s" id="${row}[time]" readonly="true"/>
<date-duration display_format="h:m" data_format="s" id="${row}[total]" readonly="true"/>
<et2-date-time id="${row}[tse_time]" readonly="true"></et2-date-time>
<et2-date-time id="${row}[tse_timestamp]" readonly="true"></et2-date-time>
<et2-select id="${row}[tse_type]" readonly="true"></et2-select>
<et2-date-duration id="${row}[time]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
<et2-date-duration id="${row}[total]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
</row>
</rows>
</grid>
@ -124,27 +121,27 @@
</columns>
<rows>
<row disabled="@ts_viewtype" class="dialogHeader">
<description value="Title" for="ts_title"/>
<textbox blur="@ts_title_blur" id="ts_title" maxlength="255" class="et2_fullWidth et2_required" tabindex="1" span="4"/>
<textbox type="integer" id="ts_id" readonly="true"/>
<appicon src="timesheet"/>
<et2-description value="Title" for="ts_title"></et2-description>
<et2-textbox id="ts_title" maxlength="255" class="et2_required" tabindex="1" span="4" placeholder="@ts_title_blur"></et2-textbox>
<et2-number id="ts_id" readonly="true" precision="0"></et2-number>
<et2-appicon src="timesheet"></et2-appicon>
</row>
<row class="dialogHeader2">
<description value="Date" for="ts_start"/>
<date id="ts_start" needed="1" class="et2_fullWidth"/>
<description/>
<description value="Starttime"/>
<date-timeonly id="start_time" class="et2_fullWidth"/>
<et2-description value="Date" for="ts_start"></et2-description>
<et2-date id="ts_start" required="1"></et2-date>
<et2-description></et2-description>
<et2-description value="Starttime"></et2-description>
<et2-date-timeonly id="start_time"></et2-date-timeonly>
</row>
<row class="row dialogHeader3">
<description value="Duration" for="ts_duration"/>
<date-duration id="ts_duration" display_format="hm" class="et2_fullWidth"/>
<description/>
<description value="or endtime" class="et2_noWrap"/>
<date-timeonly id="end_time" class="et2_fullWidth"/>
<et2-description value="Duration" for="ts_duration"></et2-description>
<et2-date-duration id="ts_duration" displayFormat="hm"></et2-date-duration>
<et2-description></et2-description>
<et2-description value="or endtime" class="et2_noWrap"></et2-description>
<et2-date-timeonly id="end_time"></et2-date-timeonly>
</row>
<row>
<tabbox id="tabs" class="et2_nowrap" width="100%" span="all" tab_height="200">
<et2-tabbox id="tabs" class="et2_nowrap" width="100%" span="all" tabHeight="200">
<tabs>
<tab id="notes" label="Description"/>
<tab id="general" label="Details"/>
@ -161,42 +158,38 @@
<template id="timesheet.edit.history"/>
<template id="timesheet.edit.events"/>
</tabpanels>
</tabbox>
</et2-tabbox>
</row>
<row class="dialogOperators">
<description value="User" for="ts_owner"/>
<select id="ts_owner" no_lang="1" span="2"/>
<description value="Status" disabled="@no_ts_status"/>
<menulist span="3">
<menupopup statustext="select a status of the timesheet" id="ts_status" class="et2_fullWidth" empty_label="please select" disabled="@no_ts_status"/>
</menulist>
<et2-description value="User" for="ts_owner"></et2-description>
<et2-select id="ts_owner" span="2" noLang="1"></et2-select>
<et2-description value="Status" disabled="@no_ts_status"></et2-description>
<et2-select span="3" statustext="select a status of the timesheet" id="ts_status" disabled="@no_ts_status" emptyLabel="please select"></et2-select>
</row>
<row class="dialogOperators">
<description value="Last modified"/>
<hbox span="3" class="et2_fullWidth">
<menulist>
<menupopup type="select-account" id="ts_modifier" readonly="true"/>
</menulist>
<date-time id="ts_modified" readonly="true" align="left" disabled="!@ts_modified"/>
</hbox>
<hbox>
<description value="Created"/>
<date-time id="ts_created" readonly="true" align="left"/>
</hbox>
<et2-description value="Last modified"></et2-description>
<et2-hbox span="3">
<et2-select-account id="ts_modifier" readonly="true"></et2-select-account>
<et2-date-time id="ts_modified" readonly="true" align="left" disabled="!@ts_modified"></et2-date-time>
</et2-hbox>
<et2-hbox>
<et2-description value="Created"></et2-description>
<et2-date-time id="ts_created" readonly="true" align="left"></et2-date-time>
</et2-hbox>
</row>
<row class="dialogFooterToolbar">
<hbox orient="0" span="all">
<hbox>
<button hideOnReadonly="true" statustext="Edit this entry" label="Edit" id="button[edit]" image="edit" background_image="1"/>
<button hideOnReadonly="true" statustext="Saves this entry and add a new one" label="Save &amp; New" id="button[save_new]" image="save_new" background_image="1"/>
<button hideOnReadonly="true" statustext="Saves the changes made" label="Save" id="button[save]" image="save" background_image="1"/>
<button hideOnReadonly="true" statustext="Applies the changes made" label="Apply" id="button[apply]" image="apply" background_image="1"/>
<button statustext="closes the window without saving the changes" label="Cancel" id="button[cancel]" onclick="window.close();" image="cancel" background_image="1"/>
<et2-hbox orient="0" span="all">
<et2-hbox>
<et2-button hideOnReadonly="true" statustext="Edit this entry" label="Edit" id="button[edit]" image="edit"></et2-button>
<et2-button hideOnReadonly="true" statustext="Saves this entry and add a new one" label="Save &amp; New" id="button[save_new]" image="save_new"></et2-button>
<et2-button hideOnReadonly="true" statustext="Saves the changes made" label="Save" id="button[save]" image="save"></et2-button>
<et2-button hideOnReadonly="true" statustext="Applies the changes made" label="Apply" id="button[apply]" image="apply"></et2-button>
<et2-button statustext="closes the window without saving the changes" label="Cancel" id="button[cancel]" onclick="window.close();" image="cancel"></et2-button>
<html id="js"/>
</hbox>
<button hideOnReadonly="true" align="right" statustext="Delete this entry" label="Delete" id="button[delete]" onclick="et2_dialog.confirm(widget,'Delete this entry','Delete')" image="delete" background_image="1"/>
<button hideOnReadonly="true" align="right" statustext="Restore this entry" label="Undelete" id="button[undelete]" image="undelete" background_image="1"/>
</hbox>
</et2-hbox>
<et2-button hideOnReadonly="true" align="right" statustext="Delete this entry" label="Delete" id="button[delete]" onclick="et2_dialog.confirm(widget,'Delete this entry','Delete')" image="delete"></et2-button>
<et2-button hideOnReadonly="true" align="right" statustext="Restore this entry" label="Undelete" id="button[undelete]" image="undelete"></et2-button>
</et2-hbox>
</row>
</rows>
</grid>