diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/xml | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web/static/src/xml')
20 files changed, 3231 insertions, 0 deletions
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml new file mode 100644 index 00000000..e18890ac --- /dev/null +++ b/addons/web/static/src/xml/base.xml @@ -0,0 +1,1867 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<!-- Owl Templates --> + +<t t-name="web.ControlPanel" owl="1"> + <div class="o_control_panel"> + <div class="o_cp_top"> + <div class="o_cp_top_left"> + <ol t-if="props.withBreadcrumbs" class="breadcrumb" role="navigation"> + <li t-foreach="props.breadcrumbs" t-as="bc" t-key="bc.controllerID" + class="breadcrumb-item" + t-att-class="{ o_back_button: bc_index === props.breadcrumbs.length - 1 }" + t-att-accesskey="bc_last and 'b'" + t-on-click.prevent="trigger('breadcrumb-clicked', { controllerID: bc.controllerID })" + > + <a t-if="bc.title" href="#" t-esc="bc.title"/> + <em t-else="" class="text-warning">Unnamed</em> + </li> + <li class="breadcrumb-item active"> + <t t-if="props.title" t-esc="props.title"/> + <em t-else="" class="text-warning">Unnamed</em> + </li> + </ol> + </div> + <div class="o_cp_top_right"> + <div class="o_cp_searchview" + role="search" + t-ref="searchView" + > + <div t-if="props.withSearchBar" class="o_searchview" role="search" aria-autocomplete="list" > + <i class="o_searchview_icon fa fa-search" + title="Search..." + role="img" + aria-label="Search..." + /> + <SearchBar t-if="props.withSearchBar" fields="fields"/> + </div> + </div> + </div> + </div> + <div class="o_cp_bottom"> + <div class="o_cp_bottom_left"> + <div class="o_cp_buttons" role="toolbar" aria-label="Control panel buttons" t-ref="buttons"> + <t t-slot="buttons"/> + </div> + <ActionMenus t-if="props.actionMenus and props.actionMenus.items" + t-props="props.actionMenus" + /> + </div> + <div class="o_cp_bottom_right"> + <div class="btn-group o_search_options position-static" + role="search" + t-ref="searchViewButtons" + > + <t t-if="props.withSearchBar"> + <FilterMenu t-if="props.searchMenuTypes.includes('filter')" + class="o_filter_menu" + fields="fields" + /> + <GroupByMenu t-if="props.searchMenuTypes.includes('groupBy')" + class="o_group_by_menu" + fields="fields" + /> + <ComparisonMenu t-if="props.searchMenuTypes.includes('comparison') and model.get('filters', f => f.type === 'comparison').length" + class="o_comparison_menu" + /> + <FavoriteMenu t-if="props.searchMenuTypes.includes('favorite')" + class="o_favorite_menu" + /> + </t> + </div> + <div class="o_cp_pager" role="search" t-ref="pager"> + <Pager t-if="props.pager and props.pager.limit" t-props="props.pager"/> + </div> + <nav t-if="props.views.length gt 1" class="btn-group o_cp_switch_buttons" role="toolbar" aria-label="View switcher"> + <t t-foreach="props.views" t-as="view" t-key="view.type"> + <t t-call="web.ViewSwitcherButton"/> + </t> + </nav> + </div> + </div> + </div> +</t> + +<t t-name="web.ControlPanelX2Many" owl="1"> + <div class="o_x2m_control_panel"> + <div class="o_cp_buttons" role="toolbar" aria-label="Control panel buttons" t-ref="buttons"> + <t t-slot="buttons"/> + </div> + <div class="o_cp_pager" role="search" t-ref="pager"> + <Pager t-if="_shouldShowPager()" t-props="props.pager"/> + </div> + </div> +</t> + +<t t-name="web.CustomCheckbox" owl="1"> + <div class="custom-control custom-checkbox"> + <input + t-att-id="props.id or _id" + type="checkbox" + class="custom-control-input" + t-att-disabled="props.disabled" + t-att-checked="props.value" + /> + <label t-att-for="props.id or _id" class="custom-control-label"> + <t t-esc="props.text or '​'"/> + </label> + </div> +</t> + +<t t-name="web.CustomFileInput" owl="1"> + <span class="o_file_input" aria-atomic="true"> + <span class="o_file_input_trigger" t-on-click.prevent="_onTriggerClicked"> + <t t-slot="default"> + <button class="btn btn-primary">Choose File</button> + </t> + </span> + <input type="file" name="ufile" class="o_input_file d-none" + t-att="{multiple: props.multi_upload, accept: props.accepted_file_extensions}" + t-ref="file-input" + t-on-change="_onFileInputChange" + /> + </span> +</t> + +<t t-name="web.DatePicker" owl="1"> + <div class="o_datepicker" aria-atomic="true" t-att-id="datePickerId" data-target-input="nearest"> + <input type="text" class="o_datepicker_input o_input datetimepicker-input" autofocus="" + t-att-name="props.name" + t-att-placeholder="props.placeholder" + t-attf-data-target="#{{ datePickerId }}" + t-att-readonly="props.readonly" + t-ref="input" + t-on-change="_onInputChange" + t-on-click="_onInputClick" + /> + <span t-if="props.warn_future and state.warning" class="fa fa-exclamation-triangle o_tz_warning o_datepicker_warning"> + <t>This date is on the future. Make sure it is what you expected.</t> + </span> + <span class="o_datepicker_button"/> + </div> +</t> + +<t t-name="web.DialogButton.tooltip" owl="1"> + <div class="oe_tooltip_string" role="tooltip"> + <div class="tooltip-inner"> + <t>Hit ENTER to <t t-esc="title"/></t> + </div> + </div> +</t> + +<t t-name="web.DropdownMenu" owl="1"> + <div class="btn-group o_dropdown" t-att-class="{ show: state.open }"> + <button type="button" + class="o_dropdown_toggler_btn btn btn-secondary" + t-att-aria-expanded="state.open ? 'true' : 'false'" + tabindex="-1" + t-on-click="state.open = !state.open" + t-on-keydown="_onButtonKeydown" + > + <i t-if="icon" t-att-class="icon"/> + <span class="o_dropdown_title" t-esc="title"/> + <i t-if="displayCaret" t-attf-class="o_dropdown_caret fa fa-caret-{{ state.open ? 'down' : 'right' }}"/> + <i t-elif="displayChevron" t-attf-class="fa fa-chevron-{{ state.open ? 'down' : 'right' }} float-right mt4"/> + </button> + <ul t-if="state.open" class="o_dropdown_menu dropdown-menu show" role="menu" + t-on-item-selected="_onItemSelected" + > + <t t-set="currentGroup" t-value="null"/> + <t t-foreach="items" t-as="item" t-key="item.key || item.id || ('item-' + item_index)"> + <li t-if="currentGroup !== null and currentGroup !== item.groupNumber" class="dropdown-divider" role="separator"/> + <t t-if="item.Component" t-component="item.Component" t-props="item.props"/> + <DropdownMenuItem t-else="" t-props="item"/> + <t t-set="currentGroup" t-value="item.groupNumber"/> + </t> + </ul> + </div> +</t> + +<t t-name="web.FavoriteMenu" t-inherit="web.DropdownMenu" t-inherit-mode="primary" owl="1"> + <xpath expr="//DropdownMenuItem" position="attributes"> + <attribute name="t-on-remove-item.stop">_onItemRemoved</attribute> + </xpath> + <xpath expr="//div[1]" position="inside"> + <Dialog t-if="state.deletedFavorite" + title="'Warning'" + size="'medium'" + t-on-dialog-closed="state.deletedFavorite = false" + > + <t t-if="state.deletedFavorite.userId">Are you sure that you want to remove this filter?</t> + <t t-else="">This filter is global and will be removed for everybody if you continue.</t> + <t t-set="buttons"> + <button type="button" class="btn btn-primary" t-on-click="_onRemoveFavorite"> + <t>Ok</t> + </button> + <button type="button" class="btn btn-secondary" t-on-click.stop="state.deletedFavorite = false"> + <t>Cancel</t> + </button> + </t> + </Dialog> + </xpath> +</t> + +<t t-name="web.FilterMenu" t-inherit="web.DropdownMenu" t-inherit-mode="primary" owl="1"> + <xpath expr="//ul[@role='menu']" position="inside"> + <li t-if="items.length" class="dropdown-divider" role="separator"/> + <CustomFilterItem fields="props.fields"/> + </xpath> +</t> + +<t t-name="web.GroupByMenu" t-inherit="web.DropdownMenu" t-inherit-mode="primary" owl="1"> + <xpath expr="//ul[@role='menu']" position="inside"> + <t t-if="fields.length"> + <li t-if="items.length" class="dropdown-divider" role="separator"/> + <CustomGroupByItem fields="fields"/> + </t> + </xpath> +</t> + +<t t-name="web.DropdownMenuItem" owl="1"> + <li class="o_menu_item" role="menuitem" t-on-keydown="_onKeydown"> + <t t-if="canBeOpened"> + <a class="o_menu_item_parent dropdown-item" + t-att-class="{ selected: props.isActive }" + t-att-aria-checked="props.isActive ? 'true' : 'false'" + role="menuitemcheckbox" + href="#" + t-ref="fallback-focus" + t-on-click.prevent="state.open = !state.open" + > + <t t-esc="props.description"/> + <i t-attf-class="o_icon_right fa fa-caret-{{ state.open ? 'down' : 'right' }}"/> + </a> + <ul t-if="state.open" class="o_menu_item_options"> + <t t-set="currentGroup" t-value="null"/> + <t t-foreach="props.options" t-as="option" t-key="option_index"> + <li t-if="currentGroup !== null and currentGroup !== option.groupNumber" + class="dropdown-divider" + role="separator" + /> + <li class="o_item_option" role="menuitem"> + <a class="dropdown-item pl-5" + t-att-class="{ selected: option.isActive }" + t-att-aria-checked="option.isActive ? 'true' : 'false'" + role="menuitemcheckbox" + t-att-href="option.url or '#'" + t-esc="option.description" + t-on-click.prevent="trigger('item-selected', { item: props, option: option })" + /> + </li> + <t t-set="currentGroup" t-value="option.groupNumber"/> + </t> + </ul> + </t> + <a t-else="" class="dropdown-item" + t-att-class="{ selected: props.isActive, [props.className]: props.className }" + t-att-aria-checked="props.isActive ? 'true' : 'false'" + role="menuitemcheckbox" + t-att-href="props.url or '#'" + t-on-click.prevent="trigger('item-selected', { item: props })" + > + <t t-esc="props.description"/> + <i t-if="props.removable" + class="o_icon_right fa fa-trash-o" + title="Delete item" + t-on-click.stop.prevent="trigger('remove-item', { item: props })" + /> + </a> + </li> +</t> + +<t t-name="web.CustomFavoriteItem" owl="1"> + <li class="o_menu_item o_add_favorite" role="menuitem"> + <button type="button" + class="dropdown-item" + t-ref="fallback-focus" + t-on-click="state.open = !state.open" + > + <t>Save current search</t> + </button> + <div t-if="state.open" class="dropdown-item-text"> + <div role="menuitem" class="dropdown-item-text"> + <input type="text" + class="o_input" + autofocus="" + t-ref="description" + t-model.trim="state.description" + t-on-keydown="_onInputKeydown" + /> + </div> + <div class="custom-control custom-checkbox"> + <input type="checkbox" + t-att-id="useByDefaultId" + class="custom-control-input" + t-att-checked="state.isDefault" + t-on-change="_onCheckboxChange" + /> + <label class="custom-control-label" t-att-for="useByDefaultId"> + <t>Use by default</t> + </label> + </div> + <div class="custom-control custom-checkbox"> + <input type="checkbox" + t-att-id="shareAllUsersId" + class="custom-control-input" + t-att-checked="state.isShared" + t-on-change="_onCheckboxChange" + /> + <label class="custom-control-label" t-att-for="shareAllUsersId"> + <t>Share with all users</t> + <i class="fa fa-users" role="img" aria-label="Users" title="Users"/> + </label> + </div> + <div class="dropdown-item-text"> + <button type="button" class="o_save_favorite btn btn-primary" t-on-click="_saveFavorite">Save</button> + </div> + </div> + </li> +</t> + +<t t-name="web.CustomFilterItem" owl="1"> + <div class="o_generator_menu"> + <button type="button" + class="o_add_custom_filter dropdown-item" + aria-expanded="false" + t-ref="fallback-focus" + t-on-click="state.open = !state.open" + t-on-keydown="_onKeydown" + > + <t>Add Custom Filter</t> + </button> + <t t-if="state.open"> + <div t-foreach="state.conditions" t-as="condition" t-key="condition_index" + class=" o_filter_condition dropdown-item-text" + > + <t t-set="fieldType" t-value="fields[condition.field].type"/> + <t t-set="selectedOperator" t-value="OPERATORS[FIELD_TYPES[fieldType]][condition.operator]"/> + <span t-if="!condition_first" class="o_or_filter">or</span> + <select class="o_input o_generator_menu_field" + t-on-change="_onFieldSelect(condition)" + > + <option t-foreach="fields" t-as="field" t-key="field_index" + t-att-value="field.name" + t-att-selected="field_index === condition.field" + t-esc="field.string" + /> + </select> + <select class="o_input o_generator_menu_operator" + t-on-change="_onOperatorSelect(condition)" + > + <option t-foreach="OPERATORS[FIELD_TYPES[fieldType]]" t-as="operator" t-key="operator_index" + t-att-value="operator.symbol" + t-att-selected="operator_index === condition.operator" + t-esc="operator.description" + /> + </select> + <span t-if="!('value' in selectedOperator)" class="o_generator_menu_value"> + <t t-if="fieldType === 'date'"> + <DatePicker + date="condition.value[0]" + t-on-datetime-changed="_onDateChanged(condition, 0)" + /> + <DatePicker t-if="selectedOperator.symbol === 'between'" + date="condition.value[1]" + t-on-datetime-changed="_onDateChanged(condition, 1)" + /> + </t> + <t t-elif="fieldType === 'datetime'"> + <DateTimePicker + date="condition.value[0]" + t-on-datetime-changed="_onDateChanged(condition, 0)" + /> + <DateTimePicker t-if="selectedOperator.symbol === 'between'" + date="condition.value[1]" + t-on-datetime-changed="_onDateChanged(condition, 1)" + /> + </t> + <select t-elif="fieldType === 'selection'" class="o_input" + t-on-change="_onValueInput(condition)" + > + <option t-foreach="fields[condition.field].selection" t-as="option" t-key="option_index" + t-att-value="option[0]" + t-esc="option[1]" + /> + </select> + <input t-elif="fieldType === 'float'" + class="o_input" + step="0.01" + t-att-type="DECIMAL_POINT === '.' ? 'number' : 'text'" + t-attf-title="Number using {{ DECIMAL_POINT }} as decimal separator." + t-attf-pattern="[0-9]+([\\{{ DECIMAL_POINT }}][0-9]+)?" + t-att-value="condition.displayedValue" + t-on-input="_onValueInput(condition)" + /> + <input t-elif="['integer', 'id'].includes(fieldType)" + class="o_input" + step="1" + type="number" + t-att-value="condition.displayedValue" + t-on-input="_onValueInput(condition)" + /> + <input t-else="" + type="text" + class="o_input" + t-att-value="condition.displayedValue" + t-on-input="_onValueInput(condition)" + /> + </span> + <i t-if="state.conditions.length gt 1" + class="fa fa-trash-o o_generator_menu_delete" + role="image" + aria-label="Delete" + title="Delete" + t-on-click="_onRemoveCondition(condition_index)" + /> + </div> + <div class="o_add_filter_menu dropdown-item-text"> + <button type="button" class="btn btn-primary o_apply_filter" t-on-click="_onApply"> + <t>Apply</t> + </button> + <button type="button" + class="btn btn-secondary o_add_condition" + t-on-click="_addDefaultCondition" + > + <i class="fa fa-plus-circle"/> + <t>Add a condition</t> + </button> + </div> + </t> + </div> +</t> + +<t t-name="web.CustomGroupByItem" owl="1"> + <div class="o_generator_menu"> + <button type="button" + class="o_add_custom_group_by dropdown-item" + aria-expanded="false" + t-ref="fallback-focus" + t-on-click="state.open = !state.open" + t-on-keydown="_onKeydown" + > + <t>Add Custom Group</t> + </button> + <div t-if="state.open" class="dropdown-item-text"> + <select class="w-auto o_input o_group_by_selector" t-model="state.fieldName"> + <option t-foreach="props.fields" t-as="field" t-key="field.name" + t-att-value="field.name" + t-esc="field.string" + /> + </select> + </div> + <div t-if="state.open" class="o_add_group_by_menu dropdown-item-text"> + <button type="button" class="btn btn-primary o_apply_group_by" t-on-click="_onApply"> + <t>Apply</t> + </button> + </div> + </div> +</t> + +<t t-name="web.OwlDialog" owl="1"> + <Portal target="'body'"> + <div class="o_dialog" t-on-focus="_onFocus" t-on-click="_onClick"> + <div role="dialog" class="modal" + tabindex="-1" + t-att-class="{ o_technical_modal: props.technical, o_modal_full: props.fullscreen }" + t-att-data-backdrop="'' + props.backdrop" + t-ref="modal" + t-on-close_dialog.stop="_close" + t-on-click="_onBackdropClick" + > + <div class="modal-dialog" t-att-class="size"> + <div class="modal-content" t-att-class="props.contentClass"> + <header t-if="props.renderHeader" class="modal-header"> + <h4 class="modal-title"> + <t t-esc="props.title"/> + <span t-if="props.subtitle" class="o_subtitle text-muted small" t-esc="props.subtitle"/> + </h4> + <button type="button" class="close" aria-label="Close" tabindex="-1" t-on-click="_close">×</button> + </header> + <main class="modal-body"> + <t t-slot="default"/> + </main> + <footer t-if="props.renderFooter" class="modal-footer" t-ref="modal-footer"> + <t t-slot="buttons"> + <button class="btn btn-primary" t-on-click.prevent="_close"> + <t>Ok</t> + </button> + </t> + </footer> + </div> + </div> + </div> + </div> + </Portal> +</t> + +<t t-name="Popover" owl="1"> + <div t-att-class="{ 'o_is_open': state.displayed }" t-on-click="_onClick" t-on-o-popover-compute="_onPopoverCompute" t-on-o-popover-close="_onPopoverClose"> + <t t-slot="default"/> + <Portal t-if="state.displayed" target="'body'"> + <div role="tooltip" class="o_popover" t-ref="popover"> + <div class="arrow"/> + <h3 t-if="props.title" class="o_popover_header"><t t-esc="props.title"/></h3> + <div class="popover-body"> + <t t-slot="opened"/> + </div> + </div> + </Portal> + </div> +</t> + +<t t-name="web.Pager" owl="1"> + <nav class="o_pager" aria-label="Pager"> + <span class="o_pager_counter" t-on-click.stop=""> + <input t-if="state.editing" type="text" + class="o_pager_value o_input" + autofocus="" + t-att-value="value" + t-on-blur="state.editing = false" + t-on-change="_onValueChange" + t-on-keydown.stop="_onValueKeydown" + /> + <span t-else="" + class="o_pager_value" + t-esc="value" + t-on-click="_onEdit" + /> + <span> / </span> + <span class="o_pager_limit" t-esc="props.size"/> + </span> + <span class="btn-group" aria-atomic="true"> + <!-- accesskeys not wanted in X2Many widgets --> + <button type="button" + class="fa fa-chevron-left btn btn-secondary o_pager_previous" + t-att-disabled="state.disabled || singlePage" + t-att-accesskey="props.withAccessKey ? 'p' : false" + aria-label="Previous" + title="Previous" + tabindex="-1" + t-on-click="_changeSelection(-1)" + /> + <button type="button" + class="fa fa-chevron-right btn btn-secondary o_pager_next" + t-att-disabled="state.disabled || singlePage" + t-att-accesskey="props.withAccessKey ? 'n' : false" + aria-label="Next" + title="Next" + tabindex="-1" + t-on-click="_changeSelection(1)" + /> + </span> + </nav> +</t> + +<t t-name="web.SearchBar" owl="1"> + <div class="o_searchview_input_container"> + <div t-foreach="model.get('facets')" t-as="facet" t-key="facet_index" + tabindex="0" + class="o_searchview_facet" + role="img" + aria-label="search" + t-on-keydown="_onFacetKeydown(facet, facet_index)" + > + <span t-if="facet.icon" t-attf-class="o_searchview_facet_label {{ facet.icon }}"/> + <span t-else="" class="o_searchview_facet_label" t-esc="facet.title"/> + <div class="o_facet_values"> + <t t-foreach="facet.values" t-as="facetValue" t-key="facetValue_index"> + <span t-if="!facetValue_first" class="o_facet_values_sep" t-esc="facet.separator"/> + <span class="o_facet_value" t-esc="facetValue"/> + </t> + </div> + <i class="fa fa-sm fa-remove o_facet_remove" + role="img" + aria-label="Remove" + title="Remove" + t-on-click="_onFacetRemove(facet)" + /> + </div> + <input type="text" + class="o_searchview_input" + autofocus="" + accesskey="Q" + placeholder="Search..." + role="searchbox" + t-ref="search-input" + t-on-keydown="_onSearchKeydown" + t-on-input="_onSearchInput" + /> + <ul t-if="state.sources.length" class="o_dropdown_menu o_searchview_autocomplete dropdown-menu show" role="menu"> + <li t-foreach="state.sources" t-as="src" t-key="src.id" + t-att-id="src.id" + class="o_menu_item" + t-att-class="{ o_indent: src.parent, o_selection_focus: src_index === state.focusedItem }" + t-on-click="_selectSource(src)" + t-on-mousemove="_onSourceMousemove(src_index)" + > + <a t-if="src.expand" + href="#" + class="o_expand" + t-on-click.stop.prevent="_expandSource(src, !src.expanded)" + > + <i t-attf-class="fa fa-caret-{{ src.expanded ? 'down' : 'right' }}"/> + </a> + <a href="#" t-on-click.prevent=""> + <t t-if="src.label" t-esc="src.label"/> + <t t-elif="['date', 'datetime'].includes(src.type)"> + <t>Search <em t-esc="src.description"/> at: <strong t-esc="state.inputValue"/></t> + </t> + <t t-else="">Search <em t-esc="src.description"/> for: <strong t-esc="state.inputValue"/></t> + </a> + </li> + </ul> + </div> +</t> + +<t t-name="web.ActionMenus" owl="1"> + <div class="o_cp_action_menus" t-on-item-selected.stop="_onItemSelected"> + <DropdownMenu t-if="printItems.length" + title="env._t('Print')" + items="printItems" + icon="'fa fa-print'" + /> + <DropdownMenu t-if="actionItems.length" + title="env._t('Action')" + items="actionItems" + icon="'fa fa-cog'" + closeOnSelected="true" + /> + </div> +</t> + +<t t-name="web.ViewSwitcherButton" owl="1"> + <t t-set="buttonLabel">View %s</t> + <button type="button" + t-att-accesskey="view.accessKey" + t-attf-class="btn btn-secondary fa fa-lg o_switch_view o_{{ view.type }} {{ view.icon }}" + t-att-class="{ active: env.view.type === view.type }" + t-att-aria-label="sprintf(buttonLabel.toString(), view.type)" + t-att-title="sprintf(buttonLabel.toString(), view.type)" + data-toggle="tooltip" + tabindex="-1" + t-on-click="trigger('switch-view', { view_type: view.type })" + /> +</t> + +<!-- Legacy Templates --> + +<div t-name="EmptyComponent"/> + +<div t-name="Loading" class="o_loading"/> + +<t t-name="WidgetLabel.tooltip"> + <div class="oe_tooltip_string" t-if="widget.string" role="tooltip"> + <t t-esc="widget.string"/> <t t-if="debug and widget.nolabel">(nolabel)</t> + </div> + <p t-if="help" class="oe_tooltip_help" role="tooltip"> + <t t-esc="help"/> + </p> + <ul t-if="debug" class="oe_tooltip_technical" role="tooltip"> + <li data-item="field" t-if="widget.name"> + <span class="oe_tooltip_technical_title">Field:</span> + <t t-esc="widget.name"/> + </li> + <li data-item="object"> + <span class="oe_tooltip_technical_title">Object:</span> + <t t-esc="widget.model"/> + </li> + <li data-item="type"> + <span class="oe_tooltip_technical_title">Type:</span> + <t t-esc="widget.field.type"/> + </li> + <li t-if="widget.attrs.widget" data-item="widget"> + <span class="oe_tooltip_technical_title">Widget:</span> + <t t-set="description" t-value="widget.attrs.Widget.prototype.description"/> + <t t-if="description"> + <t t-esc="description"/> (<t t-esc="widget.attrs.widget"/>) + </t> + <t t-else="1"> + <t t-esc="widget.attrs.widget"/> + </t> + </li> + <li t-if="widget.attrs.size || widget.field.size" data-item="size"> + <span class="oe_tooltip_technical_title">Size:</span> + <t t-esc="widget.attrs.size || widget.field.size"/> + </li> + <li t-if="widget.attrs.context || widget.field.context" data-item="context"> + <span class="oe_tooltip_technical_title">Context:</span> + <t t-esc="widget.attrs.context || JSON.stringify(widget.field.context)"/> + </li> + <li t-if="widget.attrs.domain || widget.field.domain" data-item="domain"> + <span class="oe_tooltip_technical_title">Domain:</span> + <t t-esc="widget.attrs.domain || JSON.stringify(widget.field.domain)"/> + </li> + <li t-if="widget.attrs.modifiers and !_.isEmpty(widget.attrs.modifiers)" data-item="modifiers"> + <span class="oe_tooltip_technical_title">Modifiers:</span> + <t t-esc="JSON.stringify(widget.attrs.modifiers)"/> + </li> + <li t-if="widget.field and widget.field.change_default" data-item="change_default"> + <span class="oe_tooltip_technical_title">Change default:</span> + Yes + </li> + <li t-if="widget.attrs.on_change" data-item="on_change"> + <span class="oe_tooltip_technical_title">On change:</span> + <t t-esc="widget.attrs.on_change"/> + </li> + <li t-if="widget.field and widget.field.relation" data-item="relation"> + <span class="oe_tooltip_technical_title">Relation:</span> + <t t-esc="widget.field.relation"/> + </li> + <li t-if="widget.field and widget.field.selection" data-item="selection"> + <span class="oe_tooltip_technical_title">Selection:</span> + <ul class="oe_tooltip_technical"> + <li t-foreach="widget.field.selection" t-as="option"> + [<t t-esc="option[0]"/>] + <t t-if="option[1]"> - </t> + <t t-esc="option[1]"/> + </li> + </ul> + </li> + </ul> +</t> +<t t-name="WidgetButton.tooltip"> + <div class="oe_tooltip_string" t-if="debug || node.attrs.string" role="tooltip"> + <t t-if="debug"> + Button + <t t-if="node.attrs.string">: </t> + <t t-if="!node.attrs.string"> (no string)</t> + </t> + <t t-esc="node.attrs.string"/> + </div> + <p t-if="node.attrs.help" class="oe_tooltip_help" role="tooltip"> + <t t-esc="node.attrs.help"/> + </p> + <ul t-if="debug" class="oe_tooltip_technical" role="tooltip"> + <li data-item="object"> + <span class="oe_tooltip_technical_title">Object:</span> + <t t-esc="state.model"/> + </li> + <li t-if="node.attrs.context" data-item="context"> + <span class="oe_tooltip_technical_title">Context:</span> + <t t-esc="node.attrs.context || widget.field.context"/> + </li> + <li t-if="node.attrs.modifiers and !_.isEmpty(node.attrs.modifiers)" data-item="modifiers"> + <span class="oe_tooltip_technical_title">Modifiers:</span> + <t t-esc="JSON.stringify(node.attrs.modifiers)"/> + </li> + <li t-if="node.attrs.special" data-item="special"> + <span class="oe_tooltip_technical_title">Special:</span> + <t t-esc="node.attrs.special"/> + </li> + <t t-set="button_type" t-value="node.attrs.type"/> + <li t-if="button_type" data-item="button_type"> + <span class="oe_tooltip_technical_title">Button Type:</span> + <t t-esc="button_type"/> + </li> + <li t-if="button_type === 'object'" data-item="button_method"> + <span class="oe_tooltip_technical_title">Method:</span> + <t t-esc="node.attrs.name"/> + </li> + <li t-if="button_type === 'action'" data-item="button_action"> + <span class="oe_tooltip_technical_title">Action ID:</span> + <t t-esc="node.attrs.name"/> + </li> + </ul> +</t> + +<form t-name="ChangePassword" name="change_password_form" method="POST" aria-atomic="true"> + <div class="o_form_view"> + <table class="o_group o_inner_group o_label_nowrap"> + <tr> + <td class="o_td_label"><label for="old_pwd" class="o_form_label">Old Password</label></td> + <td width="100%"><input type="password" class="o_field_widget o_input" name="old_pwd" minlength="1" autofocus="autofocus" autocomplete="current-password"/></td> + </tr> + <tr> + <td class="o_td_label"><label for="new_password" class="o_form_label">New Password</label></td> + <td width="100%"><input type="password" class="o_field_widget o_input" name="new_password" minlength="1" autocomplete="new-password"/></td> + </tr> + <tr> + <td class="o_td_label"><label for="confirm_pwd" class="o_form_label">Confirm New Password</label></td> + <td width="100%"><input type="password" class="o_field_widget o_input" name="confirm_pwd" minlength="1" autocomplete="new-password"/></td> + </tr> + </table> + </div> + <button type="button" class="btn btn-primary oe_form_button">Change Password</button> + <button type="button" class="btn btn-secondary oe_form_button oe_form_button_cancel" href="javascript:void(0)">Cancel</button> +</form> + +<div t-name="Action" class="o_action"> + <div class="o_content"/> +</div> + +<div t-name="web.NoContentHelper" class="o_view_nocontent" role="alert" owl="1"> + <div class="o_nocontent_help"> + <p class="o_view_nocontent_empty_folder"> + <t t-if="title" t-esc="title"/> + <t t-else="1">No data to display</t> + </p> + <p> + <t t-if="description" t-esc="description"/> + <t t-else="1">Try to add some records, or make sure that there is no + active filter in the search bar.</t> + </p> + </div> +</div> + +<div t-name="web.ActionHelper" class="o_view_nocontent" owl="1"> + <div class="o_nocontent_help"> + <t t-raw="noContentHelp"/> + </div> +</div> + +<t t-name="ListView.buttons"> + <div class="o_list_buttons" role="toolbar" aria-label="Main actions"> + <button type="button" class="btn btn-primary o_list_button_save" accesskey="s"> + Save + </button> + <button type="button" class="btn btn-secondary o_list_button_discard" accesskey="j"> + Discard + </button> + <t t-if="widget.is_action_enabled('create')"> + <button type="button" class="btn btn-primary o_list_button_add" accesskey="c"> + Create + </button> + </t> + <t t-if="widget.is_action_enabled('export_xlsx') and widget.isExportEnable"> + <button type="button" class="btn btn-secondary fa fa-download o_list_export_xlsx" title="Export All" aria-label="Export All"/> + </t> + </div> +</t> + +<t t-name="ListView.selection"> + <div class="o_list_selection_box"> + <t t-if="isDomainSelected">All <t t-esc="nbTotal"/> selected</t> + <t t-else=""> + <t t-esc="nbSelected"/> selected + <a t-if="isPageSelected and nbTotal > nbSelected" href="#" class="o_list_select_domain"> + <i class="fa fa-arrow-right"/> Select all <t t-esc="nbTotal"/> + </a> + </t> + </div> +</t> + +<t t-name="ListView.confirmModal"> + <main role="alert"> + <p> + <t t-if="changes.isDomainSelected">This update will only consider the records of the current page.<br/><br/></t> + <t t-if="changes.nbRecords != changes.nbValidRecords"> + Among the <t t-esc="changes.nbRecords"/> selected records, + <t t-esc="changes.nbValidRecords"/> are valid for this update.<br/> + </t> + Are you sure you want to perform the following update on those <t t-esc="changes.nbValidRecords"/> records ? + </p> + <div class="table-responsive"> + <table class="o_modal_changes"> + <tbody> + <tr> + <td>Field:</td> + <td><t t-esc="changes.fieldLabel"/></td> + </tr> + <tr> + <td>Update to:</td> + <td> + <div class="o_changes_widget"/> + </td> + </tr> + </tbody> + </table> + </div> + </main> +</t> + +<t t-name="FormView.buttons"> + <div class="o_form_buttons_view" role="toolbar" aria-label="Main actions"> + <button t-if="widget.is_action_enabled('edit')" type="button" + class="btn btn-primary o_form_button_edit" accesskey="a"> + Edit + </button> + <button t-if="widget.is_action_enabled('create')" type="button" + class="btn btn-secondary o_form_button_create" accesskey="c"> + Create + </button> + </div> + <div class="o_form_buttons_edit" role="toolbar" aria-label="Main actions"> + <button type="button" + class="btn btn-primary o_form_button_save" accesskey="s"> + Save + </button> + <button type="button" + class="btn btn-secondary o_form_button_cancel" accesskey="j"> + Discard + </button> + </div> +</t> +<t t-name="SaveCancelButton.tooltip"> + <div class="oe_tooltip_string" role="alert"> + <div class="tooltip-inner"> + Hit ENTER to SAVE<br/> + Hit ESCAPE to DISCARD + </div> + </div> +</t> +<t t-name="CreateButton.tooltip"> + <div class="oe_tooltip_string" role="tooltip"> + <div class="tooltip-inner"> + Hit ENTER to CREATE<br/> + Hit DOWN to navigate to the list below + </div> + </div> +</t> +<t t-name="FormButton.tooltip"> + <div class="oe_tooltip_string" role="tooltip"> + <div class="tooltip-inner"> + Hit ENTER to + <t t-esc="title"></t> + </div> + </div> +</t> +<form t-name="FormView.set_default" aria-atomic="true"> + <t t-set="args" t-value="widget.args"/> + <table style="width: 100%"> + <tr> + <td> + <label for="formview_default_fields" + class="oe_label oe_align_right"> + Default: + </label> + </td> + <td class="oe_form_required"> + <select id="formview_default_fields" class="o_input"> + <option value=""/> + <option t-foreach="args.fields" t-as="field" + t-att-value="field.name"> + <t t-esc="field.string"/> = <t t-esc="field.displayed"/> + </option> + </select> + </td> + </tr> + <tr t-if="args.conditions.length"> + <td> + <label for="formview_default_conditions" + class="oe_label oe_align_right"> + Condition: + </label> + </td> + <td> + <select id="formview_default_conditions" class="o_input"> + <option value=""/> + <option t-foreach="args.conditions" t-as="cond" + t-att-value="cond.name + '=' + cond.value"> + <t t-esc="cond.string"/>=<t t-esc="cond.displayed"/> + </option> + </select> + </td> + </tr> + <tr> + <td colspan="2"> + <input type="radio" id="formview_default_self" + value="self" name="scope" checked="checked"/> + <label for="formview_default_self" class="oe_label" + style="display: inline;"> + Only you + </label> + <br/> + <input type="radio" id="formview_default_all" + value="all" name="scope"/> + <label for="formview_default_all" class="oe_label" + style="display: inline;"> + All users + </label> + </td> + </tr> + </table> +</form> +<t t-name="GraphView.buttons"> + <div class="btn-group" role="toolbar" aria-label="Main actions"/> + <div class="btn-group" role="toolbar" aria-label="Change graph"> + <button class="btn btn-secondary fa fa-bar-chart-o o_graph_button" title="Bar Chart" aria-label="Bar Chart" data-mode="bar"/> + <button class="btn btn-secondary fa fa-area-chart o_graph_button" title="Line Chart" aria-label="Line Chart" data-mode="line"/> + <button class="btn btn-secondary fa fa-pie-chart o_graph_button" title="Pie Chart" aria-label="Pie Chart" data-mode="pie"/> + </div> + <div class="btn-group" role="toolbar" aria-label="Change graph"> + <button class="btn btn-secondary fa fa-database o_graph_button" title="Stacked" aria-label="Stacked" data-mode="stack"/> + </div> + <div class="btn-group" role="toolbar" aria-label="Sort graph"> + <button class="btn btn-secondary fa fa-sort-amount-desc o_graph_button" title="Descending" aria-label="Descending" data-order="desc"/> + <button class="btn btn-secondary fa fa-sort-amount-asc o_graph_button" title="Ascending" aria-label="Ascending" data-order="asc"/> + </div> +</t> + +<div t-name="GraphView.CustomTooltip" class="o_graph_custom_tooltip"> + <table> + <thead> + <tr> + <th class="o_measure"><t t-esc="measure"/></th> + </tr> + </thead> + <tbody> + <tr t-foreach="tooltipItems" t-as="tooltipItem"> + <td> + <span class="o_square" t-att-style="'background-color: ' + tooltipItem.boxColor"/> + <span class="o_label" t-att-style="'max-width: ' + maxWidth"> <t t-esc="tooltipItem.label" /> </span> + </td> + <td class="o_value"> + <t t-esc="tooltipItem.value"/> + </td> + </tr> + </tbody> + </table> +</div> + +<t t-name="PivotView.buttons"> + <div class="btn-group" role="toolbar" aria-label="Main actions"> + <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> + Measures + </button> + <div class="dropdown-menu o_pivot_measures_list" role="menu"> + <t t-foreach="measures" t-as="measure"> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-field="measure[0]"><t t-esc="measure[1].string"/><t t-if="measure[1].type === 'many2one'"> (count)</t></a> + </t> + <div role="separator" class="dropdown-divider"/> + <a role="menuitem" href="#" class="dropdown-item" data-field="__count">Count</a> + </div> + </div> + <div class="btn-group" role="toolbar" aria-label="Pivot settings"> + <button class="btn btn-secondary fa fa-exchange o_pivot_flip_button" title="Flip axis" aria-label="Flip axis"/> + <button class="btn btn-secondary fa fa-arrows o_pivot_expand_button" title="Expand all" aria-label="Expand all"/> + <button class="btn btn-secondary fa fa-download o_pivot_download" title="Download xlsx" aria-label="Download xlsx"/> + </div> +</t> + +<t t-name="FormSelection"> + <div class="btn-group o_selection" aria-atomic="true"> + <a href="#" data-toggle="dropdown" aria-expanded="false" role="button" title="Dropdown menu"><span class="o_status"/></a> + <div class="dropdown-menu state" role="menu"/> + </div> +</t> +<t t-name="FormSelection.items"> + <t t-foreach="states" t-as="rec"> + <a role="menuitem" href="#" class="dropdown-item" t-att-data-value="rec.name"> + <span t-att-class="'o_status ' + (rec.state_class && rec.state_class || '')"/> + <t t-raw="rec.state_name"/> + </a> + </t> +</t> +<t t-name="FieldDomain.content"> + <div t-if="hasModel" class="o_field_domain_panel"> + <i class="fa fa-arrow-right" role="img" aria-label="Domain" title="Domain"/> + + <button t-if="isValid" class="btn btn-sm btn-secondary o_domain_show_selection_button" type="button"> + <t t-esc="nbRecords"/> record(s) + </button> + <span t-else="" class="text-warning" role="alert"><i class="fa fa-exclamation-triangle" role="img" aria-label="Warning" title="Warning"/> Invalid domain</span> + + <button t-if="inDialogEdit" class="btn btn-sm btn-primary o_field_domain_dialog_button">Edit Domain</button> + </div> + <div t-else="">Select a model to add a filter.</div> +</t> + +<t t-name="DomainNode.ControlPanel"> + <div t-if="!widget.readonly && !widget.noControlPanel" class="o_domain_node_control_panel" role="toolbar" aria-label="Domain node"> + <button class="btn o_domain_delete_node_button" title="Delete node" aria-label="Delete node"><i class="fa fa-times"/></button> + <button class="btn o_domain_add_node_button" title="Add node" aria-label="Add node"><i class="fa fa-plus-circle"/></button> + <button class="btn o_domain_add_node_button" title="Add branch" aria-label="Add branch" data-branch="1"><i class="fa fa-ellipsis-h"/></button> + </div> +</t> +<t t-name="DomainTree.OperatorSelector"> + <div t-if="!widget.readonly" class="btn-group o_domain_tree_operator_selector" aria-atomic="true"> + <button class="btn btn-sm btn-primary o_domain_tree_operator_caret" data-toggle="dropdown"> + <t t-if="widget.operator === '&'">All</t> + <t t-if="widget.operator === '|'">Any</t> + <t t-if="widget.operator === '!'">None</t> + </button> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" href="#" class="dropdown-item" data-operator="&">All</a> + <a role="menuitem" href="#" class="dropdown-item" data-operator="|">Any</a> + </div> + </div> + <strong t-else=""> + <t t-if="widget.operator === '&'">ALL</t> + <t t-if="widget.operator === '|'">ANY</t> + <t t-if="widget.operator === '!'">NONE</t> + </strong> +</t> +<div aria-atomic="true" t-name="DomainSelector" t-attf-class="o_domain_node o_domain_tree o_domain_selector #{widget.readonly ? 'o_read_mode' : 'o_edit_mode'}"> + <t t-if="widget.children.length === 0"> + <span>Match <strong>all records</strong></span> + <button t-if="!widget.readonly" class="btn btn-sm btn-primary o_domain_add_first_node_button"><i class="fa fa-plus"/> Add filter</button> + </t> + <t t-else=""> + <div class="o_domain_tree_header"> + <t t-if="widget.children.length === 1">Match records with the following rule:</t> + <t t-else=""> + <span>Match records with</span> + <t t-call="DomainTree.OperatorSelector"/> + <span>of the following rules:</span> + </t> + </div> + + <div class="o_domain_node_children_container"/> + </t> + <label t-if="widget.debug && !widget.readonly" class="o_domain_debug_container"> + <span class="small"># Code editor</span> + <input type="text" class="o_domain_debug_input"/> + </label> +</div> +<div t-name="DomainTree" class="o_domain_node o_domain_tree"> + <div class="o_domain_tree_header o_domain_selector_row"> + <t t-call="DomainNode.ControlPanel"/> + <t t-call="DomainTree.OperatorSelector"/> + <span class="ml4">of:</span> + </div> + + <div class="o_domain_node_children_container"/> +</div> +<div t-name="DomainLeaf" t-attf-class="o_domain_node o_domain_leaf o_domain_selector_row #{widget.readonly ? 'o_read_mode' : 'o_edit_mode'}"> + <t t-call="DomainNode.ControlPanel"/> + + <div t-if="!widget.readonly" class="o_domain_leaf_edition"> + <!-- field selector will be instantiated here --> + <div> <!-- used for flex stretching --> + <select class="o_domain_leaf_operator_select o_input"> + <option t-foreach="widget.operators" t-as="key" + t-att-value="key" + t-att-selected="widget.displayOperator === key ? 'selected' : None"> + <t t-esc="key_value"/> + </option> + </select> + </div> + <div t-attf-class="o_ds_value_cell#{_.contains(['set', 'not set'], widget.displayOperator) ? ' d-none' : ''}"> + <t t-if="widget.selectionChoices !== null"> + <select class="o_domain_leaf_value_input o_input"> + <option t-foreach="widget.selectionChoices" t-as="val" + t-att-value="val[0]" + t-att-selected="_.contains(val, widget.displayValue) ? 'selected' : None"> + <t t-esc="val[1]"/> + </option> + </select> + </t> + <t t-else=""> + <t t-if="_.contains(['in', 'not in'], widget.operator)"> + <div class="o_domain_leaf_value_input"> + <span class="badge badge-pill" t-foreach="widget.displayValue" t-as="val"> + <t t-esc="val"/> <i class="o_domain_leaf_value_remove_tag_button fa fa-times" t-att-data-value="val" role="img" aria-label="Remove tag" title="Remove tag"/> + </span> + </div> + <div class="o_domain_leaf_value_tags"> + <input placeholder="Add new value" type="text" class="o_input"/> + <button class="btn btn-sm btn-primary fa fa-plus o_domain_leaf_value_add_tag_button" aria-label="Add tag" title="Add tag"/> + </div> + </t> + <t t-else=""> + <input class="o_domain_leaf_value_input o_input" type="text" t-att-value="widget.displayValue"/> + </t> + </t> + </div> + </div> + <div t-else="" class="o_domain_leaf_info"> + <!-- field selector will be instantiated here --> + <t t-if="_.isString(widget.value)"> + <span class="o_domain_leaf_operator"><t t-esc="widget.operator_mapping[widget.operator]"/></span> + <span class="o_domain_leaf_value text-primary">"<t t-esc="widget.value"/>"</span> + </t> + <t t-if="_.isArray(widget.value)"> + <span class="o_domain_leaf_operator"><t t-esc="widget.operator_mapping[widget.operator]"/></span> + <t t-foreach="widget.value" t-as="v"> + <span class="o_domain_leaf_value text-primary">"<t t-esc="v"/>"</span> + <t t-if="!v_last"> or </t> + </t> + </t> + <t t-if="_.isNumber(widget.value)"> + <span class="o_domain_leaf_operator"><t t-esc="widget.operator_mapping[widget.operator]"/></span> + <span class="o_domain_leaf_value text-primary"><t t-esc="widget.value"></t></span> + </t> + <t t-if="_.isBoolean(widget.value)"> + is + <t t-if="widget.operator === '=' && widget.value === false || widget.operator === '!=' && widget.value === true">not</t> + set + </t> + </div> +</div> +<div aria-atomic="true" t-name="ModelFieldSelector" t-attf-class="o_field_selector#{!widget.options.readonly ? ' o_edit_mode o_input' : ''}"> + <div class="o_field_selector_value" tabindex="0"/> + <div class="o_field_selector_controls" tabindex="0"> + <i role="alert" class="fa fa-exclamation-triangle o_field_selector_warning d-none" title="Invalid field chain" aria-label="Invalid field chain"/> + </div> + <div t-if="!widget.options.readonly" class="o_field_selector_popover d-none" tabindex="0"> + <div class="o_field_selector_popover_header text-center"> + <i class="fa fa-arrow-left o_field_selector_popover_option o_field_selector_prev_page" title="Previous" role="img" aria-label="Previous"/> + <div class="o_field_selector_title"/> + <i class="fa fa-times o_field_selector_popover_option o_field_selector_close" title="Close" role="img" aria-label="Close"/> + <div t-if="widget.options.showSearchInput" class="o_field_selector_search mt-2"> + <input type="text" placeholder='Search...' class="o_input"/> + </div> + </div> + <div class="o_field_selector_popover_body"> + <ul class="o_field_selector_page"/> + </div> + <div t-if="widget.options.debugMode" class="o_field_selector_popover_footer"> + <input type="text" class="o_input o_field_selector_debug"/> + </div> + </div> +</div> +<t t-name="ModelFieldSelector.value"> + <t t-foreach="chain" t-as="fieldName"> + <t t-if="fieldName_index > 0"> + <i class="fa fa-chevron-right" role="img" aria-label="Followed by" title="Followed by"/> + </t> + <span class="o_field_selector_chain_part"> + <t t-if="fieldName === '1'"> + <t t-esc="fieldName"/> + </t> + <t t-elif="fieldName === '0'"> + <t t-esc="fieldName"/> + </t> + <t t-else=""> + <t t-set="fieldInfo" t-value="_.findWhere(pages[fieldName_index], {'name': fieldName})"/> + <t t-esc="fieldInfo && fieldInfo.string || '?'"/> + </t> + </span> + </t> +</t> +<ul t-name="ModelFieldSelector.page" class="o_field_selector_page"> + <t t-foreach="lines" t-as="line"> + <t t-set="relationToFollow" t-value="followRelations(line) && line.relation"/> + <li t-attf-class="o_field_selector_item #{relationToFollow and 'o_field_selector_next_page' or 'o_field_selector_select_button'}#{line_index == 0 and ' active' or ''}" + t-att-data-name="line.name"> + <t t-esc="line.string"/> + <div t-if="debug" class="text-muted o_field_selector_item_title"><t t-esc="line.name"/> (<t t-esc="line.type"/>)</div> + <i t-if="relationToFollow" class="fa fa-chevron-right o_field_selector_relation_icon" role="img" aria-label="Relation to follow" title="Relation to follow"/> + </li> + </t> +</ul> + +<t t-name="web.datepicker"> + <t t-set="placeholder" t-value="widget.getParent().node and widget.getParent().node.attrs.placeholder"/> + <t t-set="datepickerID" t-value="_.uniqueId('datepicker')"/> + <div class="o_datepicker" aria-atomic="true" t-att-id="datepickerID" data-target-input="nearest"> + <input type="text" + class="o_datepicker_input o_input datetimepicker-input" + t-att-name="widget.name" + t-att-placeholder="placeholder" + t-attf-data-target="##{datepickerID}" + autocomplete="off"/> + <span class="o_datepicker_button"/> + </div> +</t> +<t t-name="FieldSelection"> + <span t-if="widget.mode === 'readonly'"/> + + <select t-if="widget.mode !== 'readonly'" + class="o_input" + t-att-name="widget.name" + t-att-tabindex="widget.attrs.tabindex" + t-att-autofocus="widget.attrs.autofocus" + t-att-id="widget.idForLabel"/> +</t> +<t t-name="FieldRadio.button"> + <div class="custom-control custom-radio o_radio_item" aria-atomic="true"> + <input type="radio" class="custom-control-input o_radio_input" t-att-checked="checked ? true : undefined" + t-att-name="name" t-att-data-value="value[0]" t-att-data-index="index" t-att-id="id"/> + <label class="custom-control-label o_form_label" t-att-for="id"><t t-esc="value[1]"/></label> + </div> +</t> + +<t t-name="FieldSelectionBadge"> + <span t-foreach="values" t-as="value" t-attf-class="o_selection_badge #{value[0] == current_value ? 'active' : ''}" t-att-data-index="value_index"> + <t t-esc="value[1]"/> + </span> +</t> + +<t t-name="FieldMany2One"> + <t t-if="widget.mode === 'readonly'"> + <a t-if="!widget.noOpen" t-att-tabindex="widget.attrs.tabindex" class="o_form_uri" href="#"/> + <span t-if="widget.noOpen"/> + </t> + <div t-if="widget.mode === 'edit'" class="o_field_widget o_field_many2one" aria-atomic="true"> + <div class="o_input_dropdown"> + <input type="text" class="o_input" + t-att-barcode_events="widget.nodeOptions.barcode_events" + t-att-tabindex="widget.attrs.tabindex" + t-att-autofocus="widget.attrs.autofocus" + t-att-placeholder="widget.attrs.placeholder" + t-att-id="widget.idForLabel"/> + <a role="button" class="o_dropdown_button" draggable="false"/> + </div> + <button type="button" t-if="!widget.noOpen" class="fa fa-external-link btn btn-secondary o_external_button" tabindex="-1" draggable="false" aria-label="External link" title="External link"/> + </div> +</t> + +<t t-name="web.Many2OneAvatar"> + <img t-att-src="url" t-att-alt="value" class="o_m2o_avatar"/> + <span t-esc="value"/> +</t> + +<t t-name="FieldReference" t-extend="FieldMany2One"> + <t t-jquery=".o_input_dropdown" t-operation="before"> + <select t-att-class="'o_input o_field_widget' + (widget.nodeOptions.hide_model and ' d-none' or '')"> + <option/> + <option t-foreach="widget.field.selection" t-as="model" t-att-value="model[0]"><t t-esc="model[1]"/></option> + </select> + </t> +</t> +<t t-name="FieldMany2ManyTag"> + <t t-foreach="elements" t-as="el"> + <t t-set="color" t-value="el[colorField] || 0"/> + <t t-set="colornames" t-value="['No color', 'Red', 'Orange', 'Yellow', 'Light blue', 'Dark purple', 'Salmon pink', 'Medium blue', 'Dark blue', 'Fushia', 'Green', 'Purple']"/> + <div t-attf-class="badge badge-pill #{hasDropdown ? 'dropdown' : ''} o_tag_color_#{color}" t-att-data-color="color" t-att-data-index="el_index" t-att-data-id="el.id" t-attf-title="Tag color: #{colornames[color]}"> + <t t-set="_badge_text"> + <span class="o_badge_text" t-att-title="el.display_name"><span role="img" t-attf-aria-label="Tag color: #{colornames[color]}"/><t t-esc="el.display_name"/></span> + </t> + <t t-if="hasDropdown"> + <a role="button" href="#" class="dropdown-toggle o-no-caret" data-toggle="dropdown" aria-expanded="false"> + <t t-raw="_badge_text"/> + </a> + </t> + <t t-else=""> + <t t-raw="_badge_text"/> + </t> + <a t-if="!readonly" href="#" class="fa fa-times o_delete" title="Delete" aria-label="Delete"/> + </div> + </t> +</t> +<t t-name="FieldMany2ManyTagAvatar" t-extend="FieldMany2ManyTag"> + <t t-jquery="span:first" t-operation="prepend"> + <img t-attf-src="/web/image/#{avatarModel}/#{el.id}/#{avatarField}" class="rounded-circle"/> + </t> +</t> +<t t-name="FieldMany2ManyTag.colorpicker"> + <div class="o_colorpicker dropdown-menu tagcolor_dropdown_menu" role="menu"> + <ul> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_1" data-color="1" title="Red" aria-label="Red"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_2" data-color="2" title="Orange" aria-label="Orange"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_3" data-color="3" title="Yellow" aria-label="Yellow"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_4" data-color="4" title="Light blue" aria-label="Light blue"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_5" data-color="5" title="Dark purple" aria-label="Dark purple"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_6" data-color="6" title="Salmon pink" aria-label="Salmon pink"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_7" data-color="7" title="Medium blue" aria-label="Medium blue"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_8" data-color="8" title="Dark blue" aria-label="Dark blue"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_9" data-color="9" title="Fushia" aria-label="Fushia"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_10" data-color="10" title="Green" aria-label="Green"/></li> + <li><a role="menuitem" href="#" t-att-data-id="tag_id" class="o_tag_color_11" data-color="11" title="Purple" aria-label="Purple"/></li> + <li> <!-- checkbox for tag color 0 --> + <div role="menuitem" class="o_hide_in_kanban" + t-att-data-id="tag_id" + t-att-data-color="0"> + <div class="custom-control custom-checkbox"> + <input type="checkbox" id="o_hide_in_kanban_checkbox" class="custom-control-input"/> + <label for="o_hide_in_kanban_checkbox" class="custom-control-label">Hide in Kanban</label> + </div> + </div> + </li> + </ul> + </div> +</t> +<t t-name="ProgressBar"> + <div class="o_progressbar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"> + <div t-if="widget.title" class="o_progressbar_title"><t t-esc="widget.title"/></div><div class="o_progress"> + <div class="o_progressbar_complete"/> + </div><div class="o_progressbar_value"/> + </div> +</t> +<t t-name="FieldPercentPie"> + <div class="o_field_percent_pie"> + <div class="o_pie"> + <div class="o_mask"/> + <div class="o_mask"/> + <div class="o_pie_value"/> + </div> + <span t-if="widget.string"><t t-esc="widget.string"/></span> + </div> +</t> +<t t-name="FieldStatus.content"> + <t t-if="selection_folded.length"> + <button type="button" class="btn o_arrow_button btn-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">More</button> + <div class="dropdown-menu" role="menu"> + <t t-foreach="selection_folded" t-as="i"> + <t t-call="FieldStatus.content.button"> + <t t-set="is_dropdown" t-value="true"/> + </t> + </t> + </div> + </t> + <t t-foreach="selection_unfolded.reverse()" t-as="i"> + <t t-call="FieldStatus.content.button"/> + </t> +</t> +<t t-name="FieldStatus.content.button"> + <t t-set="disabled" t-value="!clickable"/> + <button type="button" t-att-data-value="i.id" disabled="disabled" title="Current state" aria-checked="true" + t-att-role="is_dropdown ? 'menuitemradio': 'radio'" + t-attf-class="btn o_arrow_button btn-primary disabled #{is_dropdown ? 'dropdown-item bg-primary text-white': ''}" t-if="i.selected" aria-current="step"> + <t t-esc="i.display_name" role="img" t-attf-aria-label="#{i.display_name} is current state"/> + </button> + <button type="button" t-att-data-value="i.id" disabled="disabled" title="Not active state" aria-checked="false" + t-att-role="is_dropdown ? 'menuitemradio': 'radio'" + t-attf-class="btn o_arrow_button btn-secondary disabled #{is_dropdown ? 'dropdown-item': ''}" t-if="!i.selected and disabled"> + <t t-esc="i.display_name" role="img" t-attf-aria-label="#{i.display_name} is not current state"/> + </button> + <button type="button" t-att-data-value="i.id" title="Not active state, click to change it" aria-checked="false" + t-att-role="is_dropdown ? 'menuitemradio': 'radio'" + t-attf-class="btn o_arrow_button btn-secondary #{is_dropdown ? 'dropdown-item': ''}" t-if="!i.selected and !disabled"> + <t t-esc="i.display_name" role="img" t-attf-aria-label="Click to change current state to #{i.display_name}"/> + </button> +</t> +<t t-name="FieldBinaryImage"> + <div class="o_field_image" aria-atomic="true"> + <t t-if="widget.mode !== 'readonly'"> + <div class="o_form_image_controls"> + <button class="fa fa-pencil fa-lg float-left o_select_file_button" title="Edit" aria-label="Edit"/> + <button class="fa fa-trash-o fa-lg float-right o_clear_file_button" title="Clear" aria-label="Clear"/> + + <span class="o_form_binary_progress">Uploading...</span> + <t t-call="HiddenInputFile"> + <t t-set="fileupload_id" t-value="widget.fileupload_id"/> + </t> + </div> + </t> + </div> +</t> +<t t-name="FieldBinaryImage-img"> + <img class="img img-fluid" + alt="Binary file" + t-att-src='url' + t-att-border="widget.readonly ? 0 : 1" + t-att-name="widget.name"/> +</t> +<t t-name="CopyClipboardText"> + <button class="btn btn-sm btn-primary o_clipboard_button o_btn_text_copy"> + <span class="fa fa-clipboard"></span><span> Copy Text</span> + </button> +</t> +<t t-name="CopyClipboardChar"> + <button class="btn btn-sm btn-primary o_clipboard_button o_btn_char_copy"> + <span class="fa fa-clipboard"></span><span> Copy Text</span> + </button> +</t> +<t t-name="FieldBinaryFile"> + <a t-if="widget.mode === 'readonly'" href="javascript:void(0)" class="o_form_uri"/> + + <div t-if="widget.mode !== 'readonly'" class="o_field_binary_file" aria-atomic="true"> + <input type="text" class="o_input" + readonly="readonly" + t-att-name="widget.name" + t-att-tabindex="widget.attrs.tabindex" + t-att-autofocus="widget.attrs.autofocus"/> + + <button type="button" class="btn btn-primary o_select_file_button" title="Select">Upload your file</button> + <button type="button" class="btn btn-secondary fa fa-pencil o_select_file_button" title="Select" aria-label="Select"/> + <button type="button" class="btn btn-secondary fa fa-trash-o o_clear_file_button" title="Clear" aria-label="Clear"/> + + <span class="o_form_binary_progress">Uploading...</span> + <t t-call="HiddenInputFile"> + <t t-set="fileupload_id" t-value="widget.fileupload_id"/> + <t t-set="fileupload_style" t-translation="off">overflow-x: hidden</t> + </t> + </div> +</t> + +<t t-name="HiddenInputFile"> + <div t-attf-class="o_hidden_input_file #{fileupload_class or ''}" t-att-style="fileupload_style" aria-atomic="true"> + <form class="o_form_binary_form" t-att-target="fileupload_id" + method="post" enctype="multipart/form-data" t-att-action="fileupload_action || '/web/binary/upload'"> + <input type="hidden" name="csrf_token" t-att-value="csrf_token"/> + <input type="hidden" name="callback" t-att-value="fileupload_id"/> + <input type="file" class="o_input_file" name="ufile" + t-att="{'multiple': multi_upload ? 'multiple' : null, 'accept': widget.accepted_file_extensions || '*'}"/> + <t t-raw="0"/> + </form> + <iframe t-att-id="fileupload_id" t-att-name="fileupload_id" style="display: none"/> + </div> +</t> + +<t t-name="FieldBinarySignature-img"> + <img class="o_signature img img-fluid" + alt="Binary file" + t-att-src='url' + t-att-border="1" + t-att-name="widget.name"/> +</t> + +<div t-name="FieldBinarySignature"> + <div class="o_sign_signature_draw panel panel-default mt16 mb0"> + <div class="card-header"> + <a role="button" class="o_sign_select_style float-right btn btn-link">Select Signature Style</a> + <a role="button" class="o_sign_clean float-right btn btn-link">Clear Signature</a> + <a data-mode="draw" class="o_sign_mode o_sign_mode_draw btn btn-primary" role="button">Draw</a> + <a data-mode="auto" class="o_sign_mode o_sign_mode_auto btn" role="button">Auto</a> + <a data-mode="load" class="o_sign_mode o_sign_mode_load btn" role="button">Load</a> + <input type="file" name="files[]" class="o_sign_load btn btn-link" role="button"/> + </div> + <div class="o_sign_signature card-body"/> + </div> + <div class="mt16 small">By clicking Adopt and Sign, I agree that the chosen signature/initials will be a valid electronic representation of my hand-written signature/initials for all purposes when it is used on documents, including legally binding contracts.</div> + + <div class="o_sign_font_dialog card"> + <div class="card-header">Styles</div> + <div class="o_sign_font_selection card-body"/> + </div> +</div> + +<t t-name="SignatureSvgText" name="SVG Signature Text"> + <svg t-att-width="width" t-att-height="height"> + <defs> + <style type="text/css"> + @font-face { + font-family: "font_sign"; + src: url(data:font/ttf;base64,<t t-esc="font"/>) format("woff"); + font-weight: normal; + font-style: normal; + } + </style> + </defs> + <text x="50%" t-att-y="height*4/5" t-att-font-size="height*4/5" t-att-textLength="width * 4 / 5 * Math.min(1, text.length / 7)" lengthAdjust="spacingAndGlyphs" style="font-family:'font_sign'" fill="black" text-anchor="middle"><t t-esc="text"/></text> + </svg> +</t> + +<t t-name="FieldPdfViewer"> + <div class="o_field_pdfviewer" aria-atomic="true"> + <div t-if="widget.mode !== 'readonly'" class="o_form_pdf_controls mt8" role="toolbar" aria-label="PDF controls"> + <span class="o_form_binary_progress">Uploading...</span> + <button type="button" class="btn btn-primary o_select_file_button" title="Select">Upload your file</button> + <button class="btn btn-secondary fa fa-pencil o_select_file_button" title="Select" aria-label="Select" type="button"></button> + <button class="btn btn-secondary fa fa-trash-o o_clear_file_button" title="Clear" aria-label="Clear" type="button"></button> + </div> + <iframe class="o_pdfview_iframe o_field_pdfviewer"/> + <t t-call="HiddenInputFile"> + <t t-set="fileupload_id" t-value="widget.fileupload_id"/> + <t t-set="fileupload_style" t-translation="off">overflow-x: hidden</t> + </t> + </div> +</t> + +<div t-name="FieldBinaryFileUploader" t-attf-class="oe_fileupload #{widget.attrs.class ? widget.attrs.class :''}" aria-atomic="true"> + <div class="oe_placeholder_files"/> + <div t-if="widget.mode !== 'readonly'" class="oe_add"> + <button class="btn btn-secondary o_attach" title="Attach"><span class="fa fa-paperclip" aria-label="Attach"/> <t t-esc="widget.string"/></button> + <t t-call="HiddenInputFile"> + <t t-set="fileupload_id" t-value="widget.fileupload_id"/> + <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> + <t t-set="multi_upload" t-value="true"/> + <input type="hidden" name="model" t-att-value="widget.model"/> + <input type="hidden" name="id" value="0"/> + </t> + </div> +</div> + +<t t-name="FieldBinaryFileUploader.attachment_preview"> + <t t-set="url" t-value="widget.metadata[file.id] ? widget.metadata[file.id].url : false"/> + <t t-if="file.data" t-set="file" t-value="file.data"/> + <t t-set="editable" t-value="widget.mode === 'edit'"/> + <t t-if="file.mimetype" t-set="mimetype" t-value="file.mimetype"/> + <div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name"> + <div class="o_attachment_wrap"> + <t t-set="ext" t-value="file.name.replace(/^.*\./, '')"/> + <div class="o_image_box float-left" t-att-data-id="file.id"> + <a t-att-href="url" t-att-title="'Download ' + file.name" aria-label="Download"> + <span class="o_image o_hover" t-att-data-mimetype="mimetype" t-att-data-ext="ext" role="img"/> + </a> + </div> + + <div class="caption"> + <a class="ml4" t-att-href="url" t-att-title="'Download ' + file.name"><t t-esc='file.name'/></a> + </div> + <div class="caption small"> + <a class="ml4 small text-uppercase" t-att-href="url" t-att-title="'Download ' + file.name"><b><t t-esc='ext'/></b></a> + <div t-if="editable" class="progress o_attachment_progress_bar"> + <div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div> + </div> + </div> + + <div t-if="editable" class="o_attachment_uploaded"><i class="text-success fa fa-check" role="img" aria-label="Uploaded" title="Uploaded"/></div> + <div t-if="editable" class="o_attachment_delete" t-att-data-id="file.id"><span class="text-white" role="img" aria-label="Delete" title="Delete">×</span></div> + </div> + </div> +</t> + +<div t-name="FieldBinaryFileUploader.files" class="o_attachments" aria-atomic="true"> + <!-- uploaded files --> + <t t-foreach="widget.value.data" t-as="file"> + <t t-if="!file.data.upload" t-call="FieldBinaryFileUploader.attachment_preview"/> + </t> + <!-- uploading files --> + <t t-foreach="widget.uploadingFiles" t-as="file"> + <t t-set="upload" t-value="true"/> + <t t-call="FieldBinaryFileUploader.attachment_preview"/> + </t> +</div> + +<div t-name="ExportDialog" class="o_export"> + <div class="row o-export-panel no-gutters"> + <div class="col-6 d-flex o_left_panel"> + <div class="form-check o_import_compat"> + <input class="form-check-input" id="o-update-data" type="checkbox"/> + <label class="form-check-label" for="o-update-data"> + I want to update data (import-compatible export) + </label> + </div> + <div class="mt-3"> + <h4>Available fields</h4> + </div> + <div class="input-group mb-3"> + <input type="search" class="form-control o_export_search_input" id="o-export-search-filter" placeholder="Search" /> + </div> + <div class="border o_left_field_panel"/> + </div> + <div class="col-6 d-flex o_right_panel"> + <div class="o_export_format"> + <strong>Export Format:</strong> + </div> + <div class="mt-3"> + <h4>Fields to export</h4> + </div> + <div class="o_save_list"> + <t t-call="Export.SaveList"/> + </div> + <div class="o_exported_lists"/> + <div class="border o_right_field_panel"> + <ul class="o_fields_list list-unstyled"/> + </div> + </div> + </div> +</div> +<t t-name="Export.TreeItems"> + <t t-foreach="fields" t-as="field"> + <t t-set="has_child" t-value="field.children && (field.id).split('/').length != 3" /> + <div t-att-data-id="field.id" t-attf-class="o_export_tree_item #{has_child ? 'haschild o_expand' : ''}" tabindex="-1" role="treeitem"> <!-- tabindex make the div focusable --> + <span t-if="has_child" class="o_expand_parent fa fa-chevron-right" role="img" aria-label="Show sub-fields" title="Show sub-fields"/> + <div t-attf-class="o_tree_column" t-att-title="debug and field.id or None"> + <t t-esc="field.string"/> + <span title="Select field" class="fa fa-plus pull-right m-1 o_add_field"/> + </div> + </div> + </t> +</t> +<t t-name="Export.SaveList"> + <div class="input-group mb-3"> + <label class="pt-2 font-weight-bold">Save as : </label> + <input class="form-control ml-4 o_save_list_name" + placeholder="New template"/> + <button type="button" class="btn btn-secondary ml-1 o_save_list_btn"><i class="fa fa-floppy-o"/></button> + <button type="button" class="btn btn-secondary ml-1 o_cancel_list_btn"><i class="fa fa-times"/></button> + </div> +</t> +<t t-name="Export.SavedList"> + <div class="input-group mb-3"> + <label class="pt-2 mb-0 font-weight-bold">Template: </label> + <select class="form-control ml-4 o_exported_lists_select"> + <option></option> + <option class="font-italic" value="new_template">New template</option> + <t t-foreach="existing_exports" t-as="export"> + <option t-att-value="export.id"> + <t t-esc="export.name"/> + </option> + </t> + </select> + <button type="button" class="btn btn-secondary d-none ml-1 o_delete_exported_list"> + <i class="fa fa-trash"/> + </button> + </div> +</t> + +<t t-name="Throbber"> + <div> + <div class="oe_blockui_spin" style="height: 50px"> + <img src="/web/static/src/img/spin.png" style="animation: fa-spin 1s infinite steps(12);" alt="Loading..."/> + </div> + <br /> + <div class="oe_throbber_message" style="color:white"></div> + </div> +</t> +<t t-name="Spinner"> + <div class="o_spinner"><i class="fa fa-spinner fa-spin" role="img" aria-label="Loading, please wait..." title="Loading, please wait..."/></div> +</t> +<t t-name="M2ODialog"> + <div> + Do you want to create <strong t-esc="widget.value"/> as a new <t t-esc="widget.name"/>? + </div> +</t> +<t t-name="FieldMany2ManyCheckBoxes"> + <div aria-atomic="true"> + <div t-foreach="widget.m2mValues" t-as="m2m_value"> + <t t-set="id_for_label" t-value="'o_many2many_checkbox_' + _.uniqueId()"/> + <div class="custom-control custom-checkbox"> + <input type="checkbox" t-att-id="id_for_label" class="custom-control-input" t-att-data-record-id="JSON.stringify(m2m_value[0])"/> + <label t-att-for="id_for_label" class="custom-control-label o_form_label"><t t-esc="m2m_value[1]"/></label> + </div> + </div> + </div> +</t> +<t t-name="StatInfo"> + <span class="o_stat_value"><t t-esc="value"/></span> + <span class="o_stat_text"><t t-esc="text"/></span> +</t> +<t t-name="toggle_button"> + <button type="button" class="o_icon_button" t-att-title="widget.string" t-att-aria-label="widget.string" aria-pressed="false"> + <i class="fa fa-circle" t-att-title="widget.string"/> + </button> +</t> + +<t t-name="AceEditor"> + <div class="oe_form_field o_ace_view_editor oe_ace_open"> + <div class="ace-view-editor"/> + </div> +</t> + +<t t-name="notification-box"> + <div t-attf-class="o_notification_box mb0 alert alert-dismissible alert-{{type}}" role="alertdialog"> + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span class="fa fa-times"></span> + </button> + </div> +</t> + +<t t-name="translation-alert"> + <div role="alertdialog"> + Please update translations of : + <t t-foreach="fields" t-as="field"> + <strong><a class="oe_field_translate" t-att-name="field" href="#"><t t-esc="field_value.string"/><t t-if="field_index < _.size(fields)-1">, </t></a></strong> + </t> + </div> +</t> + +<t t-name="UserMenu"> + <li class="o_user_menu"> + <a role="button" class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="false" href="#"> + <img class="rounded-circle oe_topbar_avatar" t-att-src="_s + '/web/static/src/img/user_menu_avatar.png'" alt="User"/> + <span class="oe_topbar_name"/> + </a> + <div class="dropdown-menu dropdown-menu-right" role="menu"> + <t t-call="UserMenu.Actions"/> + </div> + </li> +</t> + +<t t-name="UserMenu.Actions"> + <a role="menuitem" href="#" data-menu="documentation" class="dropdown-item">Documentation</a> + <a role="menuitem" href="#" data-menu="support" class="dropdown-item">Support</a> + <div role="separator" class="dropdown-divider"/> + <a role="menuitem" href="#" data-menu="settings" class="dropdown-item">Preferences</a> + <a role="menuitem" href="#" data-menu="account" class="dropdown-item">My Odoo.com account</a> + <a role="menuitem" href="#" data-menu="logout" class="dropdown-item">Log out</a> +</t> + +<t t-name="SwitchCompanyMenu"> + <li class="o_switch_company_menu"> + <a role="button" class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="false" href="#" title="Dropdown menu"> + <span t-attf-class="#{widget.isMobile ? 'fa fa-building-o' : 'oe_topbar_name'}"> + <t t-if="!widget.isMobile"><t t-esc="widget.current_company_name"/></t> + </span> + </a> + <div class="dropdown-menu dropdown-menu-right" role="menu"> + <t t-foreach="widget.user_companies" t-as="company"> + <div class="dropdown-item d-flex py-0 px-0" data-menu="company" t-att-data-company-id="company[0]"> + <t t-set="is_allowed" t-value="widget.allowed_company_ids.includes(company[0])"/> + <t t-set="is_current" t-value="company[0] === widget.current_company"/> + <div role="menuitemcheckbox" t-att-aria-checked="is_allowed" t-att-aria-label="company[1]" tabindex="0" class="ml-auto pl-3 pr-3 border border-top-0 border-left-0 border-bottom-0 toggle_company o_py"> + <span style="height: 2rem;"> + <t t-if="is_allowed"> + <i class="fa fa-fw fa-check-square pt-2"></i> + </t> + <t t-if="!is_allowed"> + <i class="fa fa-fw fa-square-o pt-2"></i> + </t> + </span> + </div> + <div role="button" t-att-aria-pressed="is_current" aria-label="Switch to this company" tabindex="0" class="d-flex flex-grow-1 align-items-center py-0 log_into pl-3 o_py" t-att-style="is_current ? 'background-color: lightgrey;' : ''"> + <t t-if="is_allowed"> + <span class='mr-3 company_label'> + <t t-esc="company[1]"/> + </span> + </t> + <t t-if="!is_allowed"> + <span class='mr-3 company_label text-muted'> + <t t-esc="company[1]"/> + </span> + </t> + </div> + </div> + </t> + </div> + </li> +</t> + +<t t-name="EnterpriseUpgrade"> + <div class="row" role="status"> + <div class="col-6"> + Get this feature and much more with Odoo Enterprise! + <ul class="list-unstyled"> + <li><i class="fa fa-check"></i> Access to all Enterprise Apps</li> + <li><i class="fa fa-check"></i> New design</li> + <li><i class="fa fa-check"></i> Mobile support</li> + <li><i class="fa fa-check"></i> Upgrade to future versions</li> + <li><i class="fa fa-check"></i> Bugfixes guarantee</li> + <li><a href="http://www.odoo.com/editions?utm_source=db&utm_medium=enterprise" target="_blank"><i class="fa fa-plus"></i> And more</a></li> + </ul> + </div> + <div class="col-6"> + <img class="img-fluid" t-att-src='_s + "/web/static/src/img/enterprise_upgrade.jpg"' draggable="false" alt="Upgrade to enterprise"/> + </div> + </div> +</t> + +<t t-name="BaseSetting.Tabs"> + <t t-foreach="tabItems" t-as="tab"> + <div class="tab" t-attf-data-key="#{tab.key}" role="tab"> + <div class="icon d-none d-md-block" t-attf-style="background : url('#{imgurl}') no-repeat center;background-size:contain;"/> <span class="app_name"><t t-esc="tab.string"/></span> + </div> + </t> +</t> + +<t t-name="BaseSetting.SearchHeader"> + <div class="settingSearchHeader o_hidden" role="search"> + <img class="icon" t-att-src="imgurl" alt="Search"></img> + <span class="appName"><t t-esc="string"/></span> + </div> +</t> + +<t t-name="AttachDocument"> + <button t-attf-class="btn o_attachment_button #{widget.node.attrs.highlight?'btn-primary':'btn-secondary'}"> + <span class="o_attach_document"><t t-esc="widget.node.attrs.string"/></span> + <span class="d-none"> + <t t-call="HiddenInputFile"> + <t t-set="fileupload_id" t-value="widget.fileuploadID"/> + <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> + <t t-set="multi_upload" t-value="true"/> + <input type="hidden" name="model" t-att-value="widget.res_model"/> + <input type="hidden" name="id" t-att-value="widget.res_id"/> + </t> + </span> + </button> +</t> + +<t t-name="FieldColor"> + <div> + <button class="o_field_color" t-attf-tabindex="#{widget.mode === 'edit' ? 0 : -1}"></button> + </div> +</t> + +<t t-name="ColorPicker"> + <div class="o_field_color_picker"> + <ul/> + </div> +</t> +<t t-name="ColorPickerReadonly"> + <div class="o_field_color_picker_preview"> + <li> + <a href="#" role="menuitem" t-att-class="'oe_kanban_color_'+active_color" t-att-data-color="active_color" t-att-aria-label="name_color" t-att-title="name_color"/> + </li> + </div> +</t> + +<t t-name="SignButton"> + <button t-attf-class="btn o_sign_button #{widget.node.attrs.highlight?'btn-primary':'btn-secondary'}"> + <span class="o_sign_label"><t t-esc="widget.node.attrs.string"/></span> + </button> +</t> + +<t t-name="web.IframeWrapper"> + <div class="o_preview_iframe_wrapper"> + <i class="o_iframe_wrapper_spinner fa fa-spinner fa-spin fa-4x" style="color: #875a7b; z-index: 2"/> + <!--suppress CheckTagEmptyBody --> + <iframe src="about:blank" class="o_preview_iframe" style="display:none"></iframe> + </div> +</t> + +</templates> diff --git a/addons/web/static/src/xml/chart.xml b/addons/web/static/src/xml/chart.xml new file mode 100644 index 00000000..d45bef7a --- /dev/null +++ b/addons/web/static/src/xml/chart.xml @@ -0,0 +1,10 @@ +<template> + +<t t-name="web.PieChart"> + <graph type="pie" t-att-title="title"> + <field t-att-name="modifiers.groupby.split(':')[0]" t-att-interval="modifiers.groupby.split(':')[1]"/> + <field t-if="modifiers.measure" t-att-name="modifiers.measure" type="measure"/> + </graph> +</t> + +</template> diff --git a/addons/web/static/src/xml/colorpicker.xml b/addons/web/static/src/xml/colorpicker.xml new file mode 100644 index 00000000..23b35846 --- /dev/null +++ b/addons/web/static/src/xml/colorpicker.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<t t-name="Colorpicker"> + <div class="o_colorpicker_widget"> + <div class="d-flex justify-content-between align-items-stretch mb-2"> + <div class="o_color_pick_area position-relative w-75" t-att-style="widget.options.noTransparency ? 'width: 89%;' : None"> + <div class="o_picker_pointer rounded-circle p-1 position-absolute" tabindex="-1"/> + </div> + <div class="o_color_slider position-relative"> + <div class="o_slider_pointer" tabindex="-1"/> + </div> + <div class="o_opacity_slider position-relative" t-if="!widget.options.noTransparency"> + <div class="o_opacity_pointer" tabindex="-1"/> + </div> + </div> + <div t-if="widget.options.colorPreview" class="o_color_preview mb-1 w-100 p-2"/> + <div class="o_color_picker_inputs d-flex justify-content-between mb-2"> + <t t-set="input_classes" t-value="'p-0 border-0 text-center text-monospace bg-transparent text-white'" /> + + <div class="o_hex_div bg-black-50 px-1 d-flex align-items-baseline"> + <input type="text" t-attf-class="o_hex_input {{input_classes}}" data-color-method="hex" size="1"/> + <span class="flex-grow-0 ml-1 text-white-50">hex</span> + </div> + <div class="o_rgba_div bg-black-50 px-1 d-flex align-items-baseline"> + <input type="text" t-attf-class="o_red_input {{input_classes}}" data-color-method="rgb" size="1"/> + <input type="text" t-attf-class="o_green_input {{input_classes}}" data-color-method="rgb" size="1"/> + <input type="text" t-attf-class="o_blue_input mr-0 {{input_classes}}" data-color-method="rgb" size="1"/> + <t t-if="!widget.options.noTransparency"> + <input type="text" t-attf-class="o_opacity_input {{input_classes}}" data-color-method="opacity" size="1"/> + <span class="flex-grow-0 ml-1 text-white-50"> + RGBA + </span> + </t> + <span t-else="" class="flex-grow-0 ml-1 text-white-50"> + RGB + </span> + </div> + </div> + </div> +</t> +</templates> diff --git a/addons/web/static/src/xml/crash_manager.xml b/addons/web/static/src/xml/crash_manager.xml new file mode 100644 index 00000000..50b4c126 --- /dev/null +++ b/addons/web/static/src/xml/crash_manager.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<div t-name="CrashManager.warning" class="o_dialog_warning" role="alert"> + <p t-esc="widget.message" style="white-space: pre-wrap;"/> +</div> + +<div t-name="CrashManager.error" class="o_dialog_error"> + <div class="alert alert-warning clearfix" role="alert"> + <div class="float-right ml8 btn-group-vertical"> + <button class="btn btn-primary o_clipboard_button"> + <i class="fa fa-clipboard mr8"/>Copy the full error to clipboard + </button> + </div> + <p><b>An error occurred</b></p> + <p>Please use the copy button to report the error to your support service.</p> + </div> + + <t t-set="errUID" t-value="_.uniqueId()"/> + <button class="btn btn-link" t-att-data-target="'#o_error_detail' + errUID" data-toggle="collapse">See details</button> + <div t-att-id="'o_error_detail' + errUID" class="collapse alert alert-danger o_error_detail" role="alert"> + <pre t-esc="widget.message"/> + <pre t-esc="widget.traceback"/> + </div> +</div> + +</templates> diff --git a/addons/web/static/src/xml/debug.xml b/addons/web/static/src/xml/debug.xml new file mode 100644 index 00000000..3c5f593a --- /dev/null +++ b/addons/web/static/src/xml/debug.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<t t-name="WebClient.DebugManager"> + <li class="o_debug_manager" role="menuitem"> + <t t-set="_devtool_button_title">Open Developer Tools</t> + <a role="button" href="#" class="o_debug_mode" + t-att-title="_devtool_button_title + widget.debug_mode_help" + t-att-aria-label="_devtool_button_title + widget.debug_mode_help" + t-att-data-debug-mode="widget.debug_mode" + data-toggle="dropdown" aria-expanded="false" tabindex="-1" data-display="static"> + <span class="fa fa-bug"/> + </a> + <div class="dropdown-menu dropdown-menu-right o_debug_dropdown" role="menu"/> + </li> +</t> +<t t-name="WebClient.DebugManager.Global"> + <a role="menuitem" href="#" data-action="split_assets" class="dropdown-item o_debug_split_assets">Activate Assets Debugging</a> + <a role="menuitem" href="#" data-action="tests_assets" class="dropdown-item">Activate Tests Assets Debugging</a> + <a role="menuitem" href="#" data-action="regenerateAssets" class="dropdown-item">Regenerate Assets Bundles</a> + <a t-if="manager._is_admin" role="menuitem" href="/web/become" class="dropdown-item">Become Superuser</a> + <a role="menuitem" href="#" data-action="leave_debug_mode" class="dropdown-item">Leave the Developer Tools</a> +</t> +<t t-name="WebClient.DebugManager.Backend"> + <a role="menuitem" href="#" data-action="perform_js_tests" class="dropdown-item">Run JS Tests</a> + <a role="menuitem" href="#" data-action="perform_js_mobile_tests" class="dropdown-item">Run JS Mobile Tests</a> + <a role="menuitem" href="#" data-action="perform_click_everywhere_test" class="dropdown-item">Run Click Everywhere Test</a> + <a role="menuitem" href="#" data-action="select_view" class="dropdown-item">Open View</a> + <t t-if="manager._events"> + <div class="dropdown-divider" role="separator"/> + <a role="menuitem" href="#" data-action="show_timelines" class="dropdown-item">Toggle Timelines</a> + <a role="menuitem" href="#" data-action="requests_clear" class="dropdown-item">Clear Events</a> + </t> + <div class="dropdown-divider o_debug_leave_section" role="separator"/> +</t> +<t t-name="WebClient.DebugManager.Action"> + <t t-if="action"> + <div class="dropdown-divider" role="separator"/> + <a role="menuitem" href="#" data-action="edit" t-att-data-model="action.type" t-att-data-id="action.id" class="dropdown-item">Edit Action</a> + <t t-if="action.res_model"> + <a role="menuitem" href="#" data-action="get_view_fields" class="dropdown-item">View Fields</a> + <a role="menuitem" href="#" data-action="manage_filters" class="dropdown-item">Manage Filters</a> + <a role="menuitem" href="#" data-action="translate" class="dropdown-item">Technical Translation</a> + <div t-if="manager.canSeeModelAccess || manager.canSeeRecordRules" class="dropdown-divider" role="separator"/> + <a t-if="manager.canSeeModelAccess" role="menuitem" href="#" data-action="actionModelAccess" class="dropdown-item">View Access Rights</a> + <a t-if="manager.canSeeRecordRules" role="menuitem" href="#" data-action="actionRecordRules" class="dropdown-item">View Record Rules</a> + </t> + </t> +</t> +<t t-name="WebClient.DebugManager.View"> + <t t-if="view"> + <div role="separator" class="dropdown-divider"/> + <t t-if="view.type === 'form'"> + <a role="menuitem" href="#" data-action="set_defaults" class="dropdown-item">Set Defaults</a> + <t t-if="controller.getSelectedIds().length === 1"> + <a role="menuitem" href="#" data-action="get_metadata" class="dropdown-item">View Metadata</a> + <a role="menuitem" href="#" data-action="get_attachments" class="dropdown-item">Manage Attachments</a> + </t> + </t> + <a role="menuitem" href="#" data-action="fvg" class="dropdown-item">Fields View Get</a> + <t t-if="can_edit"> + <a role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="view.fieldsView.view_id" class="dropdown-item"> + Edit View: <t t-esc="view.displayName"/> + </a> + <a t-if="withControlPanel" role="menuitem" href="#" data-action="edit" data-model="ir.ui.view" t-att-data-id="action.controlPanelFieldsView.view_id" class="dropdown-item">Edit ControlPanelView</a> + </t> + </t> +</t> +<t t-name="WebClient.DebugViewLog"> + <table class="table table-sm table-striped"> + <tr> + <th>ID:</th> + <td><t t-esc="perm.id"/></td> + </tr> + <tr> + <th>XML ID:</th> + <td><t t-esc="perm.xmlid or '/'"/></td> + </tr> + <tr> + <th>No Update:</th> + <td> + <t t-esc="perm.noupdate"/> + <t t-if="perm.xmlid"> + <a data-action="toggle_noupdate">(change)</a> + </t> + </td> + </tr> + <tr> + <th>Creation User:</th> + <td><t t-esc="perm.creator"/></td> + </tr> + <tr> + <th>Creation Date:</th> + <td><t t-esc="perm.create_date"/></td> + </tr> + <tr> + <th>Latest Modification by:</th> + <td><t t-esc="perm.lastModifiedBy"/></td> + </tr> + <tr> + <th>Latest Modification Date:</th> + <td><t t-esc="perm.write_date"/></td> + </tr> + </table> +</t> +<div t-name="WebClient.DebugManager.RequestsOverlay" class="o_debug_manager_overlay"> + <header> + <!-- enough height to display all tracks + 1px spacing between tracks --> + <t t-set="canvas_height" t-value="widget.TRACKS * (widget.TRACK_WIDTH + 1)"/> + <canvas t-att-height="canvas_height" id="o_debug_requests_summary"/> + <!-- transparent overlay to display selected range --> + <canvas t-att-height="canvas_height" id="o_debug_requests_selector"/> + </header> + <div class="o_debug_requests"/> + <div class="o_debug_tooltip"/> +</div> + +</templates> diff --git a/addons/web/static/src/xml/dialog.xml b/addons/web/static/src/xml/dialog.xml new file mode 100644 index 00000000..848f5a1e --- /dev/null +++ b/addons/web/static/src/xml/dialog.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<!-- These templates are accessible in backend and frontend --> + +<t t-name="Dialog"> + <div role="dialog" + t-attf-class="modal o_legacy_dialog #{ technical ? ' o_technical_modal' : '' } #{ fullscreen ? ' o_modal_full': '' }" + tabindex="-1" + data-backdrop="static" + t-att-id="_.uniqueId('modal_')" + aria-hidden="true" + > + <div class="modal-dialog"> + <div class="modal-content"> + <header t-if="renderHeader" class="modal-header"> + <h4 class="modal-title"><t t-raw="title"/><span class="o_subtitle text-muted small" t-esc="subtitle"/></h4> + <button type="button" class="close" data-dismiss="modal" aria-label="Close" tabindex="-1">×</button> + </header> + <main class="modal-body"/> + <footer t-if="renderFooter" class="modal-footer"/> + </div> + </div> + </div> +</t> + +</templates> diff --git a/addons/web/static/src/xml/fields.xml b/addons/web/static/src/xml/fields.xml new file mode 100644 index 00000000..ce271ba2 --- /dev/null +++ b/addons/web/static/src/xml/fields.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="web.FieldBoolean" owl="1"> + <CustomCheckbox disabled="mode === 'readonly'" value="value" + class="o_field_boolean" t-on-change="_onChange"/> + </t> + + <t t-name="web.FieldBadge" owl="1"> + <span class="badge badge-pill o_field_badge" t-esc="_formatValue(value)"/> + </t> + +</templates> diff --git a/addons/web/static/src/xml/file_upload_progress_bar.xml b/addons/web/static/src/xml/file_upload_progress_bar.xml new file mode 100644 index 00000000..bdba37a6 --- /dev/null +++ b/addons/web/static/src/xml/file_upload_progress_bar.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates> + +<div t-name="web.FileUploadProgressBar" class="o_file_upload_progress_bar"> + <div class="o_file_upload_progress_bar_value"/> + <span class="o_upload_cross fa fa-times-circle" title="Cancel Upload" aria-label="Cancel Upload"/> +</div> + +</templates> diff --git a/addons/web/static/src/xml/file_upload_progress_card.xml b/addons/web/static/src/xml/file_upload_progress_card.xml new file mode 100644 index 00000000..d60b38cf --- /dev/null +++ b/addons/web/static/src/xml/file_upload_progress_card.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates> + +<t t-name="web.ProgressCard"> + <t t-if="widget.viewType === 'kanban'"> + <div class="o_kanban_progress_card o_kanban_record o_kanban_attachment"> + <div class="o_kanban_image"> + <div class="o_kanban_image_wrapper"> + <div class="o_image o_image_thumbnail" t-att-data-mimetype="widget.type"/> + </div> + </div> + <div class="o_kanban_details"> + <div class="o_kanban_details_wrapper"> + <div t-att-title="widget.title" t-att-aria-label="widget.title" class="o_kanban_record_title"> + <span t-esc="widget.title"/> + </div> + <div class="o_kanban_record_body"/> + <div class="o_kanban_record_bottom"> + <div class="oe_kanban_bottom_left"> + <div class="o_file_upload_progress_text_left">Processing...</div> + </div> + <div class="oe_kanban_bottom_right"> + <span class="o_file_upload_progress_text_right"/> + </div> + </div> + </div> + </div> + </div> + </t> + <t t-if="widget.viewType === 'list'"> + <div class="o_data_row o_list_progress_card"> + <span class="o_file_upload_upload_title" t-esc="widget.title"/> + <span class="o_file_upload_progress_text_left">Processing...</span> + <span class="o_file_upload_progress_text_right"/> + </div> + </t> +</t> + +</templates> diff --git a/addons/web/static/src/xml/kanban.xml b/addons/web/static/src/xml/kanban.xml new file mode 100644 index 00000000..2fd7f8ca --- /dev/null +++ b/addons/web/static/src/xml/kanban.xml @@ -0,0 +1,227 @@ +<template> + +<t t-name="KanbanView.buttons"> + <div> + <button t-if="!noCreate" type="button" t-attf-class="btn #{btnClass} o-kanban-button-new" accesskey="c"> + <t t-esc="create_text || _t('Create')"/> + </button> + </div> +</t> + +<t t-name="KanbanView.Group"> + <div t-attf-class="o_kanban_group#{widget.data_records.length == 0 ? ' o_kanban_no_records' : ''}" t-att-data-id="widget.id or widget.db_id" + role="feed" t-attf-aria-labelledby="kanban_header_#{widget.id or widget.db_id}"> + <div class="o_kanban_header"> + <div class="o_kanban_header_title"> + <span t-attf-id="#kanban_header_#{widget.id or widget.db_id}" class="o_column_title"><t t-esc="widget.title"/></span> + <span class="o_column_unfold"><i class="fa fa-arrows-h" role="img" aria-label="Unfold" title="Unfold"/></span> + <span class="o_kanban_config dropdown"> + <a class="dropdown-toggle o-no-caret" data-toggle="dropdown" href="#"><i class="fa fa-gear" role="img" aria-label="Settings" title="Settings"/></a> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" class="dropdown-item o_kanban_toggle_fold" href="#">Fold</a> + <t t-if="widget.grouped_by_m2o"> + <a t-if="widget.editable and widget.id" role="menuitem" class="dropdown-item o_column_edit" href="#">Edit Stage</a> + <a t-if="widget.deletable and widget.id" role="menuitem" class="dropdown-item o_column_delete" href="#">Delete</a> + </t> + <t t-if="widget.has_active_field and widget.archivable"> + <a role="menuitem" href="#" class="dropdown-item o_column_archive_records">Archive All</a> + <a role="menuitem" href="#" class="dropdown-item o_column_unarchive_records">Unarchive All</a> + </t> + </div> + </span> + <span t-if="widget.quick_create" class="o_kanban_quick_add"><i class="fa fa-plus" role="img" aria-label="Quick add" title="Quick add"/></span> + </div> + </div> + <div t-if="widget.remaining > 0" class="o_kanban_load_more"> + <t t-call="KanbanView.LoadMore"/> + </div> + </div> +</t> + +<t t-name="KanbanView.LoadMore"> + <a href="#">Load more... (<t t-esc="widget.remaining"/> remaining)</a> +</t> + +<t t-name="KanbanView.ColumnQuickCreate"> + <div class="o_column_quick_create"> + <div class="o_quick_create_folded"> + <span class="o_kanban_add_column"><i class="fa fa-plus" role="img" aria-label="Add column" title="Add column"/></span> + <span class="o_kanban_title">Add a Column</span> + </div> + <div class="o_quick_create_unfolded"> + <div class="o_kanban_header"> + <div class="input-group"> + <input type="text" class="form-control o_input" placeholder="Column title"/> + <span class="input-group-append"> + <button class="btn btn-primary o_kanban_add" type="button">Add</button> + </span> + </div> + <span t-if="!widget.isMobile" class="o_discard_msg text-muted float-right">Esc to discard</span> + <t t-if="widget.examples && !widget.isMobile"> + <button type="button" class="btn btn-link o_kanban_examples">See examples</button> + </t> + </div> + <div class="o_kanban_muted_record"/> + <div class="o_kanban_muted_record"/> + <div class="o_kanban_muted_record"/> + </div> + </div> +</t> + +<t t-name="KanbanView.RecordQuickCreate.buttons"> + <div> + <button class="btn btn-primary o_kanban_add">Add</button> + <button class="btn btn-primary o_kanban_edit">Edit</button> + <button class="btn btn-secondary o_kanban_cancel ml8">Discard</button> + </div> +</t> + +<t t-name="KanbanColorPicker"> + <t t-foreach="colors" t-as="color"> + <li> + <a role="menuitem" + href="#" + t-att-data-color="color_index" + t-attf-class="oe_kanban_color_#{color_index}" + t-att-title="color" + t-att-aria-label="color"/> + </li> + </t> +</t> + +<t t-name="GraphCustomTooltip"> + <table> + <tbody> + <tr> + <td class="legend-color-guide"> + <div t-attf-style="background-color: #{color};"></div> + </td> + <td class="key"><t t-esc="key" /></td> + <td class="value"><t t-esc="value" /></td> + </tr> + </tbody> + </table> +</t> + +<t t-name="KanbanView.ColumnProgressBar"> + <div class="o_kanban_counter"> + <div class="o_kanban_counter_progress progress"> + <t t-foreach="widget.colors" t-as="color"> + <t t-set="count" t-value="widget.subgroupCounts and widget.subgroupCounts[color] or 0"/> + <div t-attf-class="progress-bar transition-off bg-#{color_value}-full#{count ? ' o_bar_has_records' : ''}#{widget.activeFilter ? ' progress-bar-animated progress-bar-striped' : ''}" + t-att-data-filter="color" + t-attf-data-original-title="#{count} #{color}" + aria-valuemin="0" aria-valuemax="100" t-att-aria-valuenow="count*100" role="progressbar" + t-attf-style="width: #{count ? (count * 100 / widget.groupCount) : 0}%;"/> + </t> + </div> + <div class="o_kanban_counter_side"><b><t t-esc="widget.totalCounterValue || 0"/></b></div> + </div> +</t> + +<t t-name="KanbanView.SetCoverModal"> + <div t-if="attachmentIds.length" class="ml32 mr0 o_kanban_cover_container"> + <t t-foreach="attachmentIds" t-as="attachment"> + <div t-attf-class="o_kanban_cover_image#{coverId === attachment.id ? ' o_selected' : ''}"> + <img t-attf-src="/web/image/#{attachment.id}?unique=1" t-att-data-id="attachment.id" t-att-data-name="attachment.name" alt="Attachment"/> + </div> + </t> + </div> + <div t-else="">There is no available image to be set as cover.</div> + <span class="d-none"> + <t t-call="HiddenInputFile"> + <t t-set="fileupload_id" t-value="widget.imageUploadID" /> + <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t> + <input type="hidden" name="model" t-att-value="widget.modelName" /> + <input type="hidden" name="id" t-att-value="widget.id" /> + </t> + </span> +</t> + +<!-- Note: this dialog isn't responsive, but it is not accessible on mobile --> +<div t-name="KanbanView.ExamplesDialog" class="o_kanban_examples_dialog"> + <div class="o_kanban_examples_dialog_nav"> + <ul class="nav nav-pills flex-column"> + <t t-foreach="examples" t-as="example"> + <li class="nav-item"> + <a t-attf-aria-controls="example_#{example_index}" data-toggle="tab" role="tab" t-att-data-example-index="example_index" t-attf-href="#example_#{example_index}" t-attf-class="nav-link#{example_index == 0 and ' active' or ''}"> <t t-esc="example.name"/> </a> + </li> + </t> + </ul> + </div> + <div class="o_kanban_examples_dialog_content"> + <div class="tab-content"> + <t t-foreach="examples" t-as="example"> + <div role="tabpanel" t-attf-id="example_#{example_index}" t-attf-class="tab-pane #{example_index == 0 and 'active in' or ''}"> + <div t-if="example.description" class="o_kanban_examples_description"> + <t t-raw="example.description"/> <!-- description is supposed to be properly escaped --> + </div> + <div class="o_kanban_examples"> + <t t-foreach="example.columns" t-as="column"> + <div class="o_kanban_examples_group"> + <h6><b><t t-esc="column"/></b></h6> + <t t-foreach="_.random(1,4)"> + <t t-call="KanbanView.ExamplesDialog.RecordGhost"/> + </t> + </div> + </t> + </div> + </div> + </t> + </div> + </div> +</div> +<t t-name="KanbanView.ExamplesDialog.RecordGhost"> + <div class="o_kanban_examples_ghost"> + <div class="o_ghost_content"/> + <div class="o_ghost_content o_ghost_tag"/> + <t t-if="example.bullets"> + <t t-if="_.random(0,5) > 3"> + <t t-raw="example.bullets[_.random(0, example.bullets.length-1)]"/> + </t> + </t> + <img class="float-right o_ghost_avatar" src="/base/static/img/avatar.png" alt="Avatar"/> + </div> +</t> + +<!-- Kanban Example Background --> +<t t-name="KanbanView.ExamplesBackground"> + <div class="o_kanban_example_background_container"> + <div class="o_kanban_example_background"> + <div class="o_kanban_examples"> + <t t-foreach="ghostColumns" t-as="column"> + <div class="o_kanban_examples_group"> + <h6><b><t t-esc="column"/></b></h6> + <t t-foreach="_.random(2,6)"> + <t t-call="KanbanView.ExamplesBackground.RecordGhost"/> + </t> + </div> + </t> + </div> + </div> + </div> +</t> +<t t-name="KanbanView.ExamplesBackground.RecordGhost"> + <div class="o_kanban_examples_ghost"> + <div class="o_ghost_content"/> + <div class="o_ghost_content o_ghost_tag"/> + <img class="float-right o_ghost_avatar" src="/base/static/img/avatar.png" alt="Avatar"/> + </div> +</t> + +<!-- Mobile templates --> +<t t-name="KanbanView.MobileTabs"> + <div class="o_kanban_mobile_tabs_container"> + <div class="o_kanban_mobile_tabs"> + <t t-foreach="data" t-as="group"> + <div class="o_kanban_mobile_tab" t-att-data-id="group.res_id or group.id"> + <span class="o_column_title"><t t-esc="group.value"/></span> + </div> + </t> + <div class="o_kanban_mobile_add_column" t-if="quickCreateEnabled"> + <i class="fa fa-plus " role="img" aria-label="Add column" title="Add column"/> + </div> + </div> + </div> +</t> +</template> diff --git a/addons/web/static/src/xml/menu.xml b/addons/web/static/src/xml/menu.xml new file mode 100644 index 00000000..0526a96f --- /dev/null +++ b/addons/web/static/src/xml/menu.xml @@ -0,0 +1,201 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<header t-name="Menu"> + <nav class="o_main_navbar"> + <ul class="o_menu_apps"/> + <a class="o_menu_brand" role="button"/> + <ul class="o_menu_sections" role="menu"/> + <ul class="o_menu_systray" role="menu"/> + </nav> +</header> + +<!-- + @param {web.AppsMenu} widget +--> +<t t-name="AppsMenu"> + <li class="dropdown"> + <a class="full" data-toggle="dropdown" data-display="static" href="#" accesskey="h"> + <i class="fa fa-th-large"/> + </a> + <div class="dropdown-menu" role="menu"> + <t t-foreach="widget.getApps()" t-as="app"> + <a role="menuitem" t-attf-href="#menu_id=#{app.menuID}" + class="dropdown-item o_app" + t-att-data-menu-id="app.menuID" + t-att-data-menu-xmlid="app.xmlID" + t-att-data-action-id="app.actionID"> + <t t-esc="app.name"/> + </a> + </t> + </div> + </li> +</t> + +<t t-name="Menu.link"> + <t t-set="depth" t-value="(depth || 0) + 1"/> + + <t t-if="!menu.children.length"> + <t t-set="_link"> + <a role="menuitem" t-attf-href="#menu_id=#{menu.id}&action=#{menu.action ? menu.action.split(',')[1] : ''}" + t-att-data-menu="menu.id" + t-att-data-action-model="menu.action ? menu.action.split(',')[0] : ''" + t-att-data-action-id="menu.action ? menu.action.split(',')[1] : ''" + t-att-data-menu-xmlid="menu.xmlid" + t-attf-class="#{inNavbar ? '' : 'dropdown-item '}o_menu_entry_lvl_#{depth}" + data-toggle="collapse" data-target="#o_navbar_collapse.in"> + <span><t t-esc="menu.name"/></span> + </a> + </t> + <li t-if="inNavbar"> + <t t-raw="_link"/> + </li> + <t t-else=""> + <t t-raw="_link"/> + </t> + </t> + <t t-else=""> + <div t-attf-class="dropdown-header o_menu_header_lvl_#{depth}"> + <span><t t-esc="menu.name"/></span> + </div> + <t t-foreach="menu.children" t-as="menu"> + <t t-call="Menu.link"/> + </t> + </t> +</t> + +<!-- separate first level dropdown from the others to avoid nested dropdown --> +<t t-name="Menu.sections"> + <t t-foreach="menu_data.children" t-as="first_level_menu"> + <section t-att-class="first_level_menu.id"> + <t t-foreach="first_level_menu.children" t-as="second_level_menu"> + <t t-if="!second_level_menu.children.length"> + <t t-call="Menu.link"> + <t t-set="inNavbar" t-value="true"/> + <t t-set="menu" t-value="second_level_menu"/> + </t> + </t> + <t t-else=""> + <li> + <a href="#" class="dropdown-toggle o-no-caret o_menu_header_lvl_1" t-att-data-menu-xmlid="second_level_menu.xmlid" data-toggle="dropdown" data-display="static" role="button" aria-expanded="false"> + <t t-esc="second_level_menu.name"/> + </a> + <div class="dropdown-menu" role="menu"> + <t t-foreach="second_level_menu.children" t-as="third_level_menu"> + <t t-call="Menu.link"> + <t t-set="depth" t-value="1"/> + <t t-set="menu" t-value="third_level_menu"/> + </t> + </t> + </div> + </li> + </t> + </t> + </section> + </t> +</t> + +<t t-extend="UserMenu.Actions"> + <t t-jquery=".dropdown-divider" t-operation="before"> + <a role="menuitem" href="#" data-menu="shortcuts" class="dropdown-item d-none d-md-inline-block">Shortcuts</a> + </t> +</t> + +<div t-name="UserMenu.shortcuts"> + <div class="container-fluid"> + <div class="row"> + <div class="offset-md-2 col-md-8"> + <table class="o_shortcut_table text-center"> + <thead> + <tr> + <th style="width:50%;">Description</th> + <th style="width:25%;" class="text-center">Windows/Linux</th> + <th style="width:25%;" class="text-center">Mac</th> + </tr> + </thead> + <tbody> + <tr> + <td align="left">Save a record</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">s</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">s</span> + </td> + </tr> + <tr> + <td align="left">Edit a record</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">a</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">a</span> + </td> + </tr> + <tr> + <td align="left">Discard a record modification</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">j</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">j</span> + </td> + </tr> + <tr> + <td align="left">Create a new record</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">c</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">c</span> + </td> + </tr> + <tr> + <td align="left">Open to list view</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">l</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">l</span> + </td> + </tr> + <tr> + <td align="left">Open to kanban view</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">k</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">k</span> + </td> + </tr> + <tr> + <td align="left">Open the previous record</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">p</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">p</span> + </td> + </tr> + <tr> + <td align="left">Open the next record</td> + <td> + <span class="o_key">Alt</span> + <span class="o_key">n</span> + </td> + <td> + <span class="o_key">Control</span> + <span class="o_key">Alt</span> + <span class="o_key">n</span> + </td> + </tr> + + </tbody> + </table> + </div> + </div> + </div> +</div> + +<t t-extend="FormSelection"> + <t t-jquery=".dropdown-menu.state">$(this).addClass("dropdown-menu-right");</t> +</t> + +</templates> diff --git a/addons/web/static/src/xml/name_and_signature.xml b/addons/web/static/src/xml/name_and_signature.xml new file mode 100644 index 00000000..aecffdfa --- /dev/null +++ b/addons/web/static/src/xml/name_and_signature.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <!-- + This template is used to generate the SVG containing the signature when + using mode 'auto'. + + The following variables have to be defined: + - width: (number) the width of the resulting image in px + - height: (number) the height of the resulting image in px + - font: base64 encoded font to use + - text: (string) the name to draw + - type: (string) + -> if set to 'signature', it will adapt the characters width to + fit the whole text in the image. + -> otherwise, it will adapt the space between characters to fill + the image with the text. + --> + <t t-name="web.sign_svg_text" name="SVG Signature Text"> + <svg t-att-width="width" t-att-height="height"> + <defs> + <style type="text/css"> + @font-face { + font-family: "font"; + src: url(data:font/ttf;base64,<t t-esc="font"/>) format("woff"); + font-weight: normal; + font-style: normal; + } + </style> + </defs> + <!-- adapt textLength to prevent distortion and left overflow with small words --> + <text t-esc="text" x="50%" t-att-y="height * 4 / 5" t-att-font-size="height * 4 / 5" + t-att-textLength="width * 4 / 5 * (type === 'signature' ? Math.min(1, text.length / 7) : 1)" + t-att-lengthAdjust="'spacing' + (type === 'signature' ? 'AndGlyphs' : '')" + t-attf-style="font-family:'font'; stroke: none; fill: {{color}};" text-anchor="middle"/> + </svg> + </t> + + <!-- Template for the widget webSignNameAndDraw. --> + <t t-name="web.sign_name_and_signature"> + <div class="o_web_sign_name_and_signature"> + <div class="o_web_sign_name_group form-group"> + <label class="col-form-label" t-att-for="'o_web_sign_name_input_' + widget.htmlId">Full Name</label> + <input type="text" name="signer" t-att-id="'o_web_sign_name_input_' + widget.htmlId" class="o_web_sign_name_input form-control" t-att-value="widget.defaultName" placeholder="Your name" required=""/> + </div> + + <!-- + Overflow hidden is necessary because the card has a rounded + border, but we remove the padding from the body, so the canvas + will overflow on the corners without this rule. + --> + <div class="o_web_sign_signature_group bg-white card mt-3" style="overflow: hidden;"> + <div class="card-header"> + <div class="row no-gutters"> + <div class="col-auto"> + <a role="button" href="#" t-attf-class="o_web_sign_draw_button mr-2 btn btn-light {{ widget.signMode === 'draw' ? 'active': '' }}"> + Draw + </a> + </div> + <div class="col-auto"> + <a role="button" href="#" t-attf-class="o_web_sign_auto_button mr-2 btn btn-light {{ widget.signMode === 'auto' ? 'active': '' }}"> + Auto + </a> + </div> + <div class="col-auto"> + <a role="button" href="#" t-attf-class="o_web_sign_load_button mr-2 btn btn-light {{ widget.signMode === 'load' ? 'active': '' }}"> + Load + </a> + </div> + <div t-attf-class="o_web_sign_draw_clear col-auto ml-auto {{ widget.signMode !== 'draw' ? 'd-none' : '' }}"> + <a role="button" href="#" class="btn btn-link"> + Clear + </a> + </div> + <div t-attf-class="o_web_sign_auto_select_style col-auto ml-auto {{ widget.signMode !== 'auto' ? 'd-none' : '' }}"> + <a role="button" href="#" class="btn btn-link"> + Style + </a> + </div> + <div t-attf-class="o_web_sign_load_file col-auto {{ widget.signMode !== 'load' ? 'd-none' : '' }}"> + <input type="file" role="button" name="files[]" class="btn btn-link py-0"/> + </div> + </div> + </div> + + <div class="o_signature_stroke position-absolute"/> + + <div class="o_web_sign_signature p-0 bg-transparent position-relative"/> + + <div t-attf-class="o_web_sign_load_invalid card-footer d-none"> + <div class="alert alert-danger mb-0" role="alert"> + This file is invalid. Please select an image. + </div> + </div> + </div> + + <div class="o_web_sign_auto_font_selection card d-none h-100 flex-column"> + <div class="card-header">Styles</div> + <div class="o_web_sign_auto_font_list card-body text-center p-3 flex-grow-1"/> + </div> + </div> + </t> + <div t-name="web.signature_dialog"> + <div class="o_web_sign_name_and_signature"/> + + <div class="mt16 small">By clicking Adopt and Sign, I agree that the chosen signature/initials will be a valid electronic representation of my hand-written signature/initials for all purposes when it is used on documents, including legally binding contracts.</div> + </div> +</templates> diff --git a/addons/web/static/src/xml/notification.xml b/addons/web/static/src/xml/notification.xml new file mode 100644 index 00000000..0555c21c --- /dev/null +++ b/addons/web/static/src/xml/notification.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<t t-name="Notification"> + <div t-attf-class="toast o_notification #{widget.className}" + role="alert" aria-live="assertive" aria-atomic="true"> + <t t-set="closeButton"> + <button type="button" + class="close o_notification_close" + data-dismiss="toast" aria-label="Close"> + <span class="d-inline" aria-hidden="true">×</span> + </button> + </t> + <div t-if="widget.title" class="toast-header"> + <span t-attf-class="fa fa-2x mr-3 #{widget.icon} o_notification_icon" + role="img" t-attf-aria-label="Notification #{widget.name}" + t-attf-title="Notification #{widget.name}"/> + <div class="d-flex align-items-center mr-auto font-weight-bold o_notification_title" + t-raw="widget.title"/> + <t t-raw="closeButton"/> + </div> + <div t-if="widget.message or widget.subtitle or widget.buttons.length" class="toast-body"> + <t t-if="!widget.title" t-raw="closeButton"/> + <strong t-if="widget.subtitle" t-raw="widget.subtitle" + class="o_notification_subtitle"/> + <div t-if="widget.message" t-raw="widget.message" + class="mr-auto o_notification_content"/> + <div t-if="widget.buttons.length" class="mt-2 o_notification_buttons"> + <button t-foreach="widget.buttons" t-as="button" type="button" + t-attf-class="btn btn-sm #{button.primary ? 'btn-primary' : 'btn-secondary'}"> + <t t-if="button.icon"> + <i t-if="button.icon.indexOf('fa-') === 0" t-attf-class="fa fa-fw o_button_icon #{button.icon}" role="img" t-att-aria-label="button.name" t-att-title="button.name"/> + <img t-else="" t-att-src="button.icon" t-att-alt="button.name"/> + </t> + <span t-esc="button.text"/> + </button> + </div> + </div> + </div> +</t> + +</templates> diff --git a/addons/web/static/src/xml/pivot.xml b/addons/web/static/src/xml/pivot.xml new file mode 100644 index 00000000..ce6e13b3 --- /dev/null +++ b/addons/web/static/src/xml/pivot.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<templates> + + <div t-name="web.PivotRenderer" class="o_pivot" owl="1"> + <t t-if="!(props.hasData and props.measures.length) or (props.isSample and !props.isEmbedded)"> + <t t-if="props.noContentHelp" t-call="web.ActionHelper" > + <t t-set="noContentHelp" t-value="props.noContentHelp"/> + </t> + <t t-else="" t-call="web.NoContentHelper"/> + </t> + + <table t-if="props.hasData and props.measures.length" class="table-hover table-sm table-bordered" t-att-class="{ o_enable_linking: !props.disableLinking }"> + <thead> + <tr t-foreach="props.table.headers" t-as="row" t-key="'header_' + row_index"> + <t t-foreach="row" t-as="cell" t-key="'header_row_' + cell_index"> + <t t-if="cell.measure" t-call="web.PivotMeasure"/> + <t t-elif="cell.isLeaf !== undefined" t-call="web.PivotHeader"> + <t t-set="isXAxis" t-value="true"/> + </t> + <th t-else="1" t-att-colspan="cell.width" t-att-rowspan="cell.height"/> + </t> + </tr> + </thead> + <tbody> + <tr t-foreach="props.table.rows" t-as="row" t-key="'row_' + row_index"> + <t t-call="web.PivotHeader"> + <t t-set="isXAxis" t-value="false"/> + <t t-set="cell" t-value="row"/> + </t> + <t t-foreach="row.subGroupMeasurements" t-as="cell" t-key="'row_cell_' + cell_index"> + <td class="o_pivot_cell_value text-right" t-att-class="{ + o_empty: cell.value === undefined, + 'font-weight-bold': cell.isBold, + }" t-on-click="trigger('open_view', cell)" + t-on-mouseover="_onMouseEnter" t-on-mouseout="_onMouseLeave"> + <t t-if="cell.value !== undefined"> + <div t-if="cell.originIndexes.length > 1" class="o_variation" t-att-class="{ + o_positive: cell.value > 0, + o_negative: cell.value < 0, + o_null: cell.value === 0, + }" t-esc="_getFormattedVariation(cell)"/> + <div t-elif="props.fields and props.fields[cell.measure].type === 'boolean'" class="o_value"> + <div class="custom-control custom-checkbox"> + <input type="checkbox" t-attf-id="checkbox_{{cell_index}}_{{row_index}}" disabled="disabled" t-att-checked="cell.value" class="custom-control-input"/> + <label t-attf-for="checkbox_{{cell_index}}_{{row_index}}" class="custom-control-label"/> + </div> + </div> + <div t-else="1" class="o_value" t-esc="_getFormattedValue(cell)"/> + </t> + </td> + </t> + </tr> + </tbody> + </table> + </div> + + <t t-name="web.PivotHeader" owl="1"> + <th t-att-colspan="isXAxis ? cell.width : undefined" t-att-rowspan="isXAxis ? cell.height : undefined" t-att-class="{ + o_pivot_header_cell_closed: cell.isLeaf, + o_pivot_header_cell_opened: !cell.isLeaf, + }" t-attf-style="{{ isXAxis ? undefined : 'padding-left: ' + _getPadding(cell) + 'px;' }}" t-att-title="cell.label" t-on-click.self.prevent="_onHeaderClick(cell, isXAxis ? 'col' : 'row')"> + <span t-on-click.self.prevent="_onHeaderClick(cell, isXAxis ? 'col' : 'row')" t-esc="cell.title"/> + <t t-if="_isClicked(cell.groupId, isXAxis)" t-call="web.PivotGroupBySelection"/> + </th> + </t> + + <t t-name="web.PivotMeasure" owl="1"> + <th class="text-muted" t-att-colspan="cell.width" t-att-rowspan="cell.height" t-att-class="{ + o_pivot_origin_row: cell.originIndexes, + o_pivot_measure_row: !cell.originIndexes, + o_pivot_sort_order_asc: cell.order === 'asc', + o_pivot_sort_order_desc: cell.order === 'desc', + }" t-on-click.prevent="trigger('sort_rows',cell)" t-on-mouseover="_onMouseEnter" t-on-mouseout="_onMouseLeave"> + <t t-esc="cell.title"/> + </th> + </t> + + <div t-name="web.PivotGroupBySelection" class="dropdown" owl="1"> + <div class="dropdown-menu o_pivot_field_menu show" data-display="static" role="menu"> + <t t-foreach="props.selectionGroupBys" t-as="field" t-key="field.field.name"> + <t t-if="(field.field.type === 'date') || (field.field.type === 'datetime')"> + <div role="menuitem" aria-haspopup="true" class="o_inline_dropdown"> + <a href="#" + t-on-click.prevent="_onClickMenuGroupBy(field, 'month')" + class="dropdown-item o_pivot_field_selection" + t-att-class="{ disabled: field.active }" + t-att-data-field="field.name" + > + <t t-esc="field.field.string"/> + </a> + <div class="dropdown-menu" role="menu"> + <a role="menuitem" t-att-data-field="field.name" href="#" class="dropdown-item" t-on-click.prevent="_onClickMenuGroupBy(field, 'day')">Day</a> + <a role="menuitem" t-att-data-field="field.name" href="#" class="dropdown-item" t-on-click.prevent="_onClickMenuGroupBy(field, 'week')">Week</a> + <a role="menuitem" t-att-data-field="field.name" href="#" class="dropdown-item" t-on-click.prevent="_onClickMenuGroupBy(field, 'month')">Month</a> + <a role="menuitem" t-att-data-field="field.name" href="#" class="dropdown-item" t-on-click.prevent="_onClickMenuGroupBy(field, 'quarter')">Quarter</a> + <a role="menuitem" t-att-data-field="field.name" href="#" class="dropdown-item" t-on-click.prevent="_onClickMenuGroupBy(field, 'year')">Year</a> + </div> + </div> + </t> + <a t-else="" href="#" role="menuitem" class="dropdown-item" t-att-data-field="field.name" t-att-class="{ disabled: field.active }" t-on-click.prevent="_onClickMenuGroupBy(field, false)"> + <t t-esc="field.field.string"/> + </a> + </t> + </div> + </div> + +</templates> diff --git a/addons/web/static/src/xml/rainbow_man.xml b/addons/web/static/src/xml/rainbow_man.xml new file mode 100644 index 00000000..744912a9 --- /dev/null +++ b/addons/web/static/src/xml/rainbow_man.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates xml:space="preserve"> + <t t-name="rainbow_man.notification"> + <div class="o_reward"> + <svg class="o_reward_rainbow" viewBox="0 0 340 180"> + <path d="M270,170a100,100,0,0,0-200,0" style="stroke:#FF9E80;"/> + <path d="M290,170a120,120,0,0,0-240,0" style="stroke:#FFE57F;"/> + <path d="M310,170a140,140,0,0,0-280,0" style="stroke:#80D8FF;"/> + <path d="M330,170a160,160,0,0,0-320,0" style="stroke:#c794ba;"/> + </svg> + <div class="o_reward_stars" t-foreach="[1, 2, 3, 4]" t-as="star"> + <t t-call="rainbow_man.star"> + <t t-set="class" t-value="star"/> + </t> + </div> + <div class="o_reward_face_group"> + <svg style="display:none"> + <symbol id="thumb"> + <path d="M10,52 C6,51 3,48 3,44 C2,42 3,39 5,38 C3,36 2,34 2,32 C2,29 3,27 5,26 C3,24 2,21 2,19 C2,15 7,12 10,12 L23,12 C23,11 23,11 23,11 L23,10 C23,8 24,6 25,4 C27,2 29,2 31,2 C33,2 35,2 36,4 C38,5 39,7 39,10 L39,38 C39,41 37,45 35,47 C32,50 28,51 25,52 L10,52 L10,52 Z" fill="#FBFBFC"/> + <polygon fill="#ECF1FF" points="25 11 25 51 5 52 5 12"/> + <path d="M31,0 C28,0 26,1 24,3 C22,5 21,7 21,10 L10,10 C8,10 6,11 4,12 C2,14 1,16 1,19 C1,21 1,24 2,26 C1,27 1,29 1,32 C1,34 1,36 2,38 C1,40 0,42 1,45 C1,50 5,53 10,54 L25,54 C29,54 33,52 36,49 C39,46 41,42 41,38 L41,10 C41,4 36,3.38176876e-16 31,0 M31,4 C34,4 37,6 37,10 L37,38 C37,41 35,44 33,46 C31,48 28,49 25,50 L10,50 C7,49 5,47 5,44 C4,41 6,38 9,37 L9,37 C6,37 5,35 5,32 C5,28 6,26 9,26 L9,26 C6,26 5,22 5,19 C5,16 8,14 11,14 L23,14 C24,14 25,12 25,11 L25,10 C25,7 28,4 31,4" id="Shape" fill="#A1ACBA"/> + </symbol> + </svg> + <span class="o_reward_face" t-attf-style="background-image:url(#{widget.options.img_url});"/> + + <svg class="o_reward_thumbup" viewBox="0 0 42 60"> + <use href="#thumb"/> + </svg> + + <div class="o_reward_msg_container"> + <svg class="o_reward_thumb_right" viewBox="0 0 100 55"> + <use href="#thumb" transform="scale(-1, 1.2) rotate(-90) translate(-42,-60)"/> + </svg> + <div class="o_reward_msg"> + <div class="o_reward_msg_card"> + <div class="o_reward_msg_content"/> + <div class="o_reward_shadow_container"> + <div class="o_reward_shadow"/> + </div> + </div> + </div> + </div> + </div> + + </div> + </t> + <t t-name="rainbow_man.star"> + <svg t-attf-class="star{{ star }}" width="35px" height="34px" viewBox="0 0 35 34"> + <path fill="#fff" d="M33,15.9 C26.3557814,13.6951256 21.1575294,8.45974313 19,1.8 C19,1.24771525 18.5522847,0.8 18,0.8 C17.4477153,0.8 17,1.24771525 17,1.8 C14.6431206,8.69377078 9.02624222,13.9736364 2,15.9 C1.36487254,15.9 0.85,16.4148725 0.85,17.05 C0.85,17.6851275 1.36487254,18.2 2,18.2 C8.6215326,20.3844521 13.8155479,25.5784674 16,32.2 C16,32.7522847 16.4477153,33.2 17,33.2 C17.5522847,33.2 18,32.7522847 18,32.2 C20.3568794,25.3062292 25.9737578,20.0263636 33,18.1 C33.6351275,18.1 34.15,17.5851275 34.15,16.95 C34.15,16.3148725 33.6351275,15.8 33,15.8"></path> + </svg> + </t> +</templates> diff --git a/addons/web/static/src/xml/report.xml b/addons/web/static/src/xml/report.xml new file mode 100644 index 00000000..7f08d009 --- /dev/null +++ b/addons/web/static/src/xml/report.xml @@ -0,0 +1,14 @@ +<template> + + <!-- Main layout (iframe) --> + <div t-name="report.client_action"> + <iframe class="o_report_iframe"/> + </div> + + <!-- Buttons of the Control Panel --> + <t t-name="report.client_action.ControlButtons"> + <div class="o_report_buttons"> + <button type="button" class="btn btn-primary o_report_print" title="Print">Print</button> + </div> + </t> +</template> diff --git a/addons/web/static/src/xml/ribbon.xml b/addons/web/static/src/xml/ribbon.xml new file mode 100644 index 00000000..87df25d2 --- /dev/null +++ b/addons/web/static/src/xml/ribbon.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<template> + + <t t-name="web.ribbon"> + <div class="ribbon ribbon-top-right"> + <span t-att-class="widget.className" t-att-title="widget.tooltip"> + <t t-esc="widget.text"/> + </span> + </div> + </t> + +</template> diff --git a/addons/web/static/src/xml/search_panel.xml b/addons/web/static/src/xml/search_panel.xml new file mode 100644 index 00000000..4b6dc4d7 --- /dev/null +++ b/addons/web/static/src/xml/search_panel.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<t t-name="web.SearchPanel" owl="1"> + <div class="o_search_panel" t-att-class="props.className"> + <section t-foreach="model.get('sections', s => !s.empty)" t-as="section" t-key="section.id" + t-attf-class="o_search_panel_section o_search_panel_{{ section.type }}" + > + <header class="o_search_panel_section_header text-uppercase"> + <i t-attf-class="fa {{ section.icon }} o_search_panel_section_icon mr-2" + t-att-style="section.color and ('color: ' + section.color)" + /> + <b t-esc="section.description"/> + </header> + <div t-if="section.errorMsg" class="alert alert-warning"> + <span><t t-esc="section.errorMsg"/></span> + </div> + <ul t-else="" class="list-group d-block o_search_panel_field"> + <t t-if="section.type === 'category'" t-call="web.SearchPanel.Category"> + <t t-set="values" t-value="section.rootIds"/> + </t> + <t t-elif="section.groups"> + <li t-foreach="section.sortedGroupIds" t-as="groupId" t-key="groupId" + class="o_search_panel_filter_group list-group-item border-0" + > + <!-- TODO: this is a workaround for issue https://github.com/odoo/owl/issues/695 (remove when solved) --> + <t t-set="_section" t-value="section"/> + <t t-set="group" t-value="section.groups.get(groupId)"/> + <header class="o_search_panel_group_header"> + <div class="custom-control custom-checkbox"> + <!-- TODO: "indeterminate" could not be set in the template and had to be set in + JS manually. See https://github.com/odoo/owl/issues/713 (adapt when solved) + --> + <input type="checkbox" + class="custom-control-input" + t-attf-id="{{ section.id }}_input_{{ groupId }})" + t-on-click="_toggleFilterGroup(section.id, group)" + /> + <label t-attf-for="{{ section.id }}_input_{{ groupId }})" + class="o_search_panel_label custom-control-label" + t-att-class="{ o_with_counters: group.enableCounters }" + t-att-title="group.tooltip or false" + > + <span class="o_search_panel_label_title"> + <span t-if="group.hex_color" class="mr-1" t-attf-style="color: {{ group.hex_color }};">●</span> + <t t-esc="group.name"/> + </span> + </label> + </div> + </header> + <ul class="list-group d-block"> + <t t-call="web.SearchPanel.FiltersGroup"> + <t t-set="values" t-value="group.values"/> + <!-- TODO: this is a workaround for issue https://github.com/odoo/owl/issues/695 (remove when solved) --> + <t t-set="section" t-value="_section"/> + </t> + </ul> + </li> + <ul t-if="section.groups.get(false)" class="list-group d-block"> + <t t-call="web.SearchPanel.FiltersGroup"> + <t t-set="group" t-value="section.groups.get(false)"/> + <t t-set="values" t-value="group.values"/> + <!-- TODO: this is a workaround for issue https://github.com/odoo/owl/issues/695 (remove when solved) --> + <t t-set="section" t-value="section"/> + </t> + </ul> + </t> + <t t-else="" t-call="web.SearchPanel.FiltersGroup"> + <t t-set="values" t-value="section.values"/> + </t> + </ul> + </section> + </div> +</t> + +<t t-name="web.SearchPanel.Category" owl="1"> + <t t-foreach="values" t-as="valueId" t-key="valueId"> + <t t-set="value" t-value="section.values.get(valueId)"/> + <li class="o_search_panel_category_value list-group-item border-0"> + <header class="list-group-item-action" + t-att-class="{ active: state.active[section.id] === valueId }" + t-on-click="_toggleCategory(section, value)" + > + <label class="o_search_panel_label mb0" t-att-class="{ o_with_counters: section.enableCounters }"> + <div class="o_toggle_fold"> + <i t-if="value.childrenIds.length" + t-attf-class="fa fa-caret-{{ state.expanded[section.id][valueId] ? 'down' : 'right' }}" + /> + </div> + <b t-if="value.bold" class="o_search_panel_label_title" t-esc="value.display_name"/> + <span t-else="" class="o_search_panel_label_title" t-esc="value.display_name"/> + </label> + <span t-if="section.enableCounters and value.__count gt 0" + class="o_search_panel_counter text-muted ml-2 small" + t-esc="value.__count" + /> + </header> + <ul t-if="value.childrenIds.length and state.expanded[section.id][valueId]" class="list-group d-block"> + <t t-call="web.SearchPanel.Category"> + <t t-set="values" t-value="value.childrenIds"/> + </t> + </ul> + </li> + </t> +</t> + +<t t-name="web.SearchPanel.FiltersGroup" owl="1"> + <li t-foreach="[...values.keys()]" t-as="valueId" t-key="valueId" + class="o_search_panel_filter_value list-group-item border-0" + > + <t t-set="value" t-value="values.get(valueId)"/> + <div class="custom-control custom-checkbox w-100"> + <input type="checkbox" + t-attf-id="{{ section.id }}_input_{{ valueId }}" + t-att-checked="state.active[section.id][valueId]" + class="custom-control-input" + t-on-click="_toggleFilterValue(section.id, valueId)" + /> + <label class="o_search_panel_label custom-control-label" + t-attf-for="{{ section.id }}_input_{{ valueId }}" + t-att-title="(group and group.tooltip) or false"> + <span class="o_search_panel_label_title" t-esc="value.display_name"/> + <span t-if="section.enableCounters and value.__count gt 0" + class="o_search_panel_counter text-muted ml-2 small" + t-esc="value.__count" + /> + </label> + </div> + </li> +</t> + +</templates> diff --git a/addons/web/static/src/xml/translation_dialog.xml b/addons/web/static/src/xml/translation_dialog.xml new file mode 100644 index 00000000..7ee3e2f4 --- /dev/null +++ b/addons/web/static/src/xml/translation_dialog.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + <div t-name="TranslationDialog" class="o_translation_dialog"> + <div class="row" t-foreach="widget.data" t-as="term"> + <div t-attf-class="col-12 #{widget.showSrc ? 'col-lg-2' : 'col-lg-3'} #{widget.currentInterfaceLanguage == term.lang ? 'o_language_current' : ''}"> + <t t-esc="term.langName"></t> + </div> + <div t-if="widget.showSrc" class="col-12 col-lg-3 source"> + <t t-esc="term.source"></t> + </div> + <div t-attf-class="col-12 #{widget.showSrc ? 'col-lg-7' : 'col-lg-9'} translation"> + <input t-if="!widget.isText" type="text" + class="o_field_char o_input" + t-att-value="term.value" + t-att-data-id="term.id"/> + + <textarea t-if="widget.isText" + t-esc="term.value" + t-att-data-id="term.id" + t-att-rows="widget.showSrc ? 2 : 5" + class="o_field_text o_field_translate o_field_widget o_input"> + </textarea> + </div> + </div> + </div> +</templates> diff --git a/addons/web/static/src/xml/web_calendar.xml b/addons/web/static/src/xml/web_calendar.xml new file mode 100644 index 00000000..45b03ee2 --- /dev/null +++ b/addons/web/static/src/xml/web_calendar.xml @@ -0,0 +1,158 @@ +<template> + <div t-name="CalendarView" class="o_calendar_container"> + <div class="o_calendar_view"> + <div class="o_calendar_buttons" role="toolbar" aria-label="Calendar toolbar"/> + <div class="o_calendar_widget" /> + </div> + <div class="o_calendar_sidebar_container d-none d-md-block"> + <div class="o_calendar_sidebar"> + <div class="o_calendar_mini"/> + </div> + </div> + </div> + + <t t-name="calendar-box"> + <div t-att-style="typeof color === 'string' ? ('background-color:' + color) + ';' : ''" t-attf-class="#{record.is_highlighted ? 'o_event_hightlight' : ''} #{typeof color === 'number' ? _.str.sprintf('o_calendar_color_%s', color) : 'o_calendar_color_1'}"> + <span t-if="showTime" class="fc-time"/> + <div class="o_event_title" t-esc="record.display_name"/> + </div> + </t> + + <t t-name="CalendarView.event.popover.placeholder"> + <div t-attf-class="o_cw_popover popover card shadow #{typeof color === 'number' ? _.str.sprintf('o_calendar_color_%s', color) : ''}" role="tooltip"> + <div class="arrow"/> + <div class="card-header d-flex justify-content-between py-2 pr-2"> + <h4 class="popover-header border-0 p-0 pt-1"/> + <span class="o_cw_popover_close ml-4"><i class="fa fa-close small"/></span> + </div> + <div class="o_cw_body"> + </div> + </div> + </t> + + <t t-name="CalendarView.event.popover"> + <div class="o_cw_body"> + <ul class="list-group list-group-flush"> + <li t-if="!widget.hideDate and widget.eventDate.date" class="list-group-item"> + <i class="fa fa-fw fa-calendar-o"/> + <b class="text-capitalize" t-esc="widget.eventDate.date"/> <small t-if="widget.eventDate.duration"><b t-esc="_.str.sprintf('(%s)', widget.eventDate.duration)"/></small> + </li> + <li t-if="!widget.hideTime and widget.eventTime.time" class="list-group-item"> + <i class="fa fa-fw fa-clock-o"/> + <b t-esc="widget.eventTime.time"/> <small t-if="widget.eventTime.duration"><b t-esc="_.str.sprintf('(%s)', widget.eventTime.duration)"/></small> + </li> + </ul> + <ul t-if="widget.isEventDetailsVisible()" class="list-group list-group-flush o_cw_popover_fields_secondary"/> + <div class="card-footer border-top"> + <a t-if="widget.isEventEditable()" href="#" class="btn btn-primary o_cw_popover_edit">Edit</a> + <a t-if="widget.isEventDeletable()" href="#" class="btn btn-secondary o_cw_popover_delete ml-2">Delete</a> + </div> + </div> + </t> + + <t t-name="CalendarView.sidebar.filter"> + <t t-set="needCollapse" t-value="widget.filters.length > 2 and widget.title"></t> + <t t-set="collapseTitle" t-value="widget.title and widget.title.split(' ').join('')"></t> + <div class="o_calendar_filter"> + <h5 t-if="needCollapse" type="button" data-toggle="collapse" t-attf-data-target="#o_cw_filter_collapse_#{collapseTitle}" class="d-flex justify-content-between align-items-center"> + <t t-esc="widget.title"/><i class="o_cw_filter_collapse_icon fa fa-chevron-down"/> + </h5> + + <h5 t-elif="widget.title" t-esc="widget.title"/> + + <div t-attf-class="o_calendar_filter_items #{needCollapse ? 'collapse show' : 0}" aria-expanded="true" t-attf-id="o_cw_filter_collapse_#{collapseTitle}"> + <t t-foreach="widget.filters" t-as="filter" t-if="filter.display == null || filter.display"> + <t t-set="idForLabel" t-value="_.uniqueId('o_calendar_filter_item_')"/> + <t t-set="color" t-value="widget.getColor(filter.color_index)"/> + <t t-set="isColorNumber" t-value="typeof color === 'number'"/> + + <div t-attf-class="o_calendar_filter_item w-100 position-relative mb-2 #{isColorNumber ? _.str.sprintf('o_cw_filter_color_%s', color) : ''}" + t-att-data-value="filter.value" t-att-data-id="filter.id"> + + <input type="checkbox" t-att-id="idForLabel" name="selection" class="position-absolute" t-att-checked="filter.active ? true : undefined"/> + + <label t-att-for="idForLabel" class="d-flex align-items-center m-0"> + <span t-attf-class="o_cw_filter_input_bg align-items-center d-flex flex-shrink-0 justify-content-center position-relative mr-1 #{widget.avatar_field ? 'o_beside_avatar' : ''}" + t-att-style="color and !isColorNumber ? _.str.sprintf('border-color:%s;background-color:%s', color, color) : ''"> + <i class="fa fa-check position-relative"/> + </span> + <i t-if="filter.value == 'all'" class="o_cw_filter_avatar fa fa-users fa-fw flex-shrink-0 mr-1" role="img" aria-label="Avatar" title="Avatar"/> + <img t-elif="widget.avatar_field and filter.value" t-attf-src="/web/image/#{widget.avatar_model}/#{filter.value}/#{widget.avatar_field}" class="o_cw_filter_avatar flex-shrink-0 mr-1" alt="Avatar"/> + <span class="o_cw_filter_title text-truncate flex-grow" t-esc="filter.label" t-attf-title="#{ ['all', false].includes(filter.value) or !widget.avatar_field ? filter.label : '' }"/> + </label> + + <button t-if="filter.id" class="o_remove btn bg-white text-700 py-0 px-2" title="Remove this favorite from the list" role="img" aria-label="Remove this favorite from the list"> + <i class="fa fa-times"/> + </button> + </div> + </t> + </div> + </div> + </t> + + <t t-name="CalendarView.buttons"> + <div class="o_calendar_buttons"> + <span class="o_calendar_navigation_buttons"> + <t t-call="CalendarView.navigation_buttons" /> + </span> + <t t-if="!scaleDrop"> + <span class="o_calendar_scale_buttons"> + <t t-call="CalendarView.scale_buttons" /> + </span> + </t> + </div> + </t> + + <t t-name="CalendarView.navigation_buttons"> + <button class="o_calendar_button_prev btn btn-primary" aria-label="Previous" title="Previous"><span class="fa fa-arrow-left"/></button> + <button class="o_calendar_button_today btn btn-primary">Today</button> + <button class="o_calendar_button_next btn btn-primary" aria-label="Next" title="Next"><span class="fa fa-arrow-right"/></button> + </t> + + <t t-name="CalendarView.scale_buttons"> + <div class="btn-group"> + <button type="button" t-if="scales.includes('day')" class="o_calendar_button_day btn btn-secondary">Day</button> + <button type="button" t-if="scales.includes('week')" class="o_calendar_button_week btn btn-secondary">Week</button> + <button type="button" t-if="scales.includes('month')" class="o_calendar_button_month btn btn-secondary">Month</button> + <button type="button" t-if="scales.includes('year')" class="o_calendar_button_year btn btn-secondary">Year</button> + </div> + </t> + + <main t-name="CalendarView.quick_create" class="o_calendar_quick_create"> + <div class="form-group"> + <label for='name' class='col-form-label o_form_label'>Summary:</label> + <input type='text' name='name' class="o_input o_required_modifier" t-att-value="widget.dataTemplate.name or None"/> + </div> + </main> + + <t t-name="CalendarView.yearEvent.popover"> + <div class="o_cw_body"> + <t t-foreach="groupKeys" t-as="groupKey"> + <div class="font-weight-bold mt-2" t-esc="groupKey"/> + <t t-foreach="groupedEvents[groupKey]" t-as="event"> + <t t-set="record" t-value="event.extendedProps.record"/> + <a href="#" class="o_cw_popover_link btn-link d-block" + t-att-data-id="record.id" + t-att-data-title="record.display_name" + t-esc="record.display_name"/> + </t> + </t> + <div class="mt-2"> + <a t-if="canCreate" href="#" class="btn-link o_cw_popover_create"> + <i class="fa fa-plus"/> Create + </a> + </div> + </div> + </t> + + <t t-name="CalendarView.yearEvent.popover.placeholder"> + <div class="popover o_cw_popover" style="position: relative"> + <div class="arrow"></div> + <div class="popover-header"></div> + <div style="position: absolute; top: 0; right: 0.5rem;"> + <span class="o_cw_popover_close"><i class="fa fa-close small"></i></span> + </div> + <div class="popover-body"></div> + </div> + </t> +</template> |
