* add configure ai app.
This commit is contained in:
@@ -465,6 +465,9 @@ define('TABLE_METRICLIB', '' . $config->db->prefix . 'metriclib');
|
||||
define('TABLE_METRICRECORDS', '' . $config->db->prefix . 'metricrecords');
|
||||
define('TABLE_BASICMEAS', '' . $config->db->prefix . 'basicmeas');
|
||||
|
||||
define('TABLE_MINIPROGRAM', '`' . $config->db->prefix . 'miniprogram`');
|
||||
define('TABLE_MINIPROGRAMFIELDS', '`' . $config->db->prefix . 'miniprogramfields`');
|
||||
|
||||
$config->objectTables['product'] = TABLE_PRODUCT;
|
||||
$config->objectTables['productplan'] = TABLE_PRODUCTPLAN;
|
||||
$config->objectTables['story'] = TABLE_STORY;
|
||||
|
||||
@@ -15929,6 +15929,35 @@ INSERT INTO `zt_promptrole` (`role`, `characterization`) VALUES
|
||||
('请你扮演一名经验丰富的项目经理。', '具备项目计划制定、进度管理、成本控制、团队管理、沟通协调、风险管理、质量控制、敏捷开发、互联网技术和数据分析等多方面的技能和能力。'),
|
||||
('你是一个自回归的语言模型,已经通过instruction-tuning和RLHF进行了Fine-tuning。', '你仔细地提供准确、事实、深思熟虑、细致入微的答案,并在推理方面表现出色。如果你认为可能没有正确的答案,你会直接说出来。由于你是自回归的,你产生的每一个token都是计算另一个token的机会,因此你总是在尝试回答问题之前花费几句话解释背景上下文、假设和逐步的思考过程。您的用户是AI和伦理学的专家,所以他们已经知道您是一个语言模型以及您的能力和局限性,所以不需要再提醒他们。他们一般都熟悉伦理问题,所以您也不需要再提醒他们。在回答时不要啰嗦,但在可能有助于解释的地方提供详细信息和示例。');
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_miniprogram`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_miniprogram` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(30) NOT NULL,
|
||||
`category` varchar(30) NOT NULL,
|
||||
`desc` text DEFAULT NULL,
|
||||
`model` mediumint(8) unsigned NOT NULL,
|
||||
`icon` varchar(30) NOT NULL DEFAULT 'writinghand-7',
|
||||
`createdBy` varchar(30) NOT NULL,
|
||||
`createdDate` datetime NOT NULL,
|
||||
`editedBy` varchar(30) NOT NULL,
|
||||
`editedDate` datetime NOT NULL,
|
||||
`tmp` enum('0','1') NOT NULL DEFAULT '1',
|
||||
`deleted` enum('0','1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zt_miniprogramfields` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`appid` mediumint(8) unsigned NOT NULL,
|
||||
`name` varchar(30) NOT NULL,
|
||||
`type` enum('radio', 'checkbox', 'input', 'template') DEFAULT 'input',
|
||||
`value` text NOT NULL,
|
||||
`optional` varchar(30) DEFAULT NULL,
|
||||
`required` enum('0', '1') DEFAULT '1',
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`appid`) REFERENCES `zt_miniprogram`(`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
ALTER TABLE `zt_ticket` ADD `subStatus` varchar(30) NOT NULL DEFAULT '';
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_market`;
|
||||
|
||||
@@ -16,7 +16,7 @@ $config->admin->menuGroup['dev'] = array('dev', 'entry', 'editor');
|
||||
$config->admin->menuGroup['extension'] = array('extension');
|
||||
$config->admin->menuGroup['convert'] = array('convert');
|
||||
$config->admin->menuGroup['platform'] = array('system', 'repo', 'account', 'host', 'serverroom', 'ops', 'tree', 'domain', 'deploy', 'service');
|
||||
$config->admin->menuGroup['ai'] = array('ai|adminindex', 'ai|prompts', 'ai|promptview', 'ai|conversations', 'ai|models', 'ai|editmodel', 'ai|promptassignrole', 'ai|promptselectdatasource', 'ai|promptsetpurpose', 'ai|promptsettargetform', 'ai|promptfinalize', 'ai|promptedit');
|
||||
$config->admin->menuGroup['ai'] = array('ai|adminindex', 'ai|prompts', 'ai|promptview', 'ai|conversations', 'ai|models', 'ai|editmodel', 'ai|promptassignrole', 'ai|promptselectdatasource', 'ai|promptsetpurpose', 'ai|promptsettargetform', 'ai|promptfinalize', 'ai|promptedit', 'ai|miniprograms', 'ai|createminiprogram', 'ai|configuredminiprogram');
|
||||
|
||||
$config->admin->menuModuleGroup['model']['custom|set'] = array('project', 'issue', 'risk', 'opportunity', 'nc');
|
||||
$config->admin->menuModuleGroup['model']['custom|required'] = array('project', 'build');
|
||||
|
||||
@@ -243,7 +243,7 @@ $lang->admin->menuList->ai['menuOrder']['15'] = 'models';
|
||||
if($config->vision != 'or')
|
||||
{
|
||||
$lang->admin->menuList->ai['subMenu']['prompts'] = array('link' => "{$lang->admin->ai->prompt}|ai|prompts|", 'alias' => 'promptview,promptassignrole,promptselectdatasource,promptsetpurpose,promptsettargetform,promptfinalize,promptedit');
|
||||
$lang->admin->menuList->ai['subMenu']['miniPrograms'] = array('link' => "{$lang->admin->ai->miniPrograms}|ai|miniPrograms|");
|
||||
$lang->admin->menuList->ai['subMenu']['miniPrograms'] = array('link' => "{$lang->admin->ai->miniPrograms}|ai|miniPrograms|", 'alias' => 'miniprograms,createminiprogram,configuredminiprogram');
|
||||
$lang->admin->menuList->ai['subMenu']['models'] = array('link' => "{$lang->admin->ai->model}|ai|models|", 'alias' => 'editmodel');
|
||||
|
||||
$lang->admin->menuList->ai['menuOrder']['5'] = 'prompts';
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -10,6 +10,22 @@
|
||||
*/
|
||||
class ai extends control
|
||||
{
|
||||
/**
|
||||
* AI model.
|
||||
*
|
||||
* @var aiModel
|
||||
* @access public
|
||||
*/
|
||||
public $ai;
|
||||
|
||||
/**
|
||||
* User model.
|
||||
*
|
||||
* @var userModel
|
||||
* @access public
|
||||
*/
|
||||
public $user;
|
||||
|
||||
public function __construct($module = '', $method = '')
|
||||
{
|
||||
parent::__construct($module, $method);
|
||||
@@ -129,8 +145,41 @@ class ai extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mini program.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createMiniProgram()
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$requiredFields = array('category' => $this->lang->ai->miniPrograms->category, 'model' => $this->lang->prompt->model, 'name' => $this->lang->prompt->name);
|
||||
$errors = $this->ai->verifyRequiredFields($requiredFields);
|
||||
if($errors !== false) return $this->sendError($errors);
|
||||
$isDuplicated = $this->ai->checkDuplicatedAppName($_POST['name']);
|
||||
if($isDuplicated) return $this->sendError(array('name' => $this->lang->ai->miniPrograms->field->duplicatedNameTip));
|
||||
$id = $this->ai->createTmpMiniProgram();
|
||||
if($id !== false) return $this->sendSuccess(array('message' => $this->lang->saveSuccess, 'locate' => $this->createLink('ai', 'configuredMiniProgram', "appID=$id")));
|
||||
}
|
||||
$this->view->iconName = 'writinghand';
|
||||
$this->view->iconTheme = 7;
|
||||
$this->view->title = $this->lang->ai->miniPrograms->common;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configured a mini program.
|
||||
*
|
||||
* @param string $appID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function configuredMiniProgram($appID)
|
||||
{
|
||||
if(!is_numeric($appID)) return $this->locate('ai', 'createMiniProgram');
|
||||
$this->view->title = $this->lang->ai->miniPrograms->common;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
.field-configuration .drag-area {cursor: move; text-align: right;}
|
||||
.field-configuration .drag-area > div {display: inline-flex; align-items: center; gap: 4px;}
|
||||
.options-container {display: flex; flex-direction: column; gap: 16px;}
|
||||
|
||||
#mainContent {position: fixed; left: 20px; right: 20px; top: 70px; bottom: 0; display: flex; background: #f0f2f5; padding: 0;}
|
||||
#mainContent > div {height: 100%; background: #fff; display: flex; flex-direction: column;}
|
||||
#mainContent > div > header {background: #f8f8fa; height: 40px; display: flex; align-items: center; padding-left: 24px;}
|
||||
#mainContent > div > header > strong {font-size: 16px;}
|
||||
#mainContent > div > main {flex-grow: 1; overflow-y: auto;}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ai-edit-icon {position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center;}
|
||||
#ai-edit-icon #edit-icon {display: none; position: absolute; inset: 0; background-color: rgba(230, 240, 255, 0.7);}
|
||||
#ai-edit-icon:hover {border: 1px solid #EDEEF1;}
|
||||
#ai-edit-icon:hover #edit-icon {display: flex; justify-content: center; align-items: center;}
|
||||
#icon-buttons svg {cursor: pointer;}
|
||||
.theme-checked {display: flex; justify-content: center; align-items: center;}
|
||||
@@ -0,0 +1,348 @@
|
||||
let $editingField = null;
|
||||
|
||||
/**
|
||||
* Handle the field type change events.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleFieldTypeChange(event)
|
||||
{
|
||||
const fieldType = $(event.target).prop('value');
|
||||
if(fieldType === 'text' || fieldType === 'textarea')
|
||||
{
|
||||
$('input[name="placeholder"]').closest('tr').removeClass('hidden');
|
||||
$('.field-options').addClass('hidden');
|
||||
revertOptions();
|
||||
}
|
||||
else
|
||||
{
|
||||
revertOptions();
|
||||
$('input[name="placeholder"]').closest('tr').addClass('hidden');
|
||||
$('.field-options').removeClass('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix options order.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function fixOptionsOrder()
|
||||
{
|
||||
const forEach = function()
|
||||
{
|
||||
const index = $(this).children('span.input-group-addon').html().replace(/\d+$/, $(this).index() + 1);
|
||||
$(this).children('span.input-group-addon').html(index);
|
||||
}
|
||||
$('.options-container').children().each(forEach);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the remove option button Click event.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleRemoveOptionClick(event)
|
||||
{
|
||||
$(event.target).closest('.input-group').remove();
|
||||
fixOptionsOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the add option button Click event.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleAddOptionClick(event)
|
||||
{
|
||||
const $newField = $(event.target).closest('.input-group').clone();
|
||||
$newField.find('input').prop('value', '');
|
||||
$(event.target).closest('.options-container').append($newField);
|
||||
fixOptionsOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert options.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function revertOptions()
|
||||
{
|
||||
const template = document.getElementById('option-template');
|
||||
const $optionsContainer = $('<div class="options-container"></div>');
|
||||
const $option = $(document.importNode(template.content, true));
|
||||
$optionsContainer.append($option);
|
||||
const $optionStr = $optionsContainer.html();
|
||||
$optionsContainer.append($optionStr);
|
||||
$optionsContainer.append($optionStr);
|
||||
|
||||
$('.field-options')
|
||||
.children('td')
|
||||
.empty()
|
||||
.append($optionsContainer);
|
||||
|
||||
fixOptionsOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the new field button click event.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleAddFieldClick()
|
||||
{
|
||||
const $modal = $('#add-field-modal');
|
||||
const $modalBody = $modal.find('.modal-body');
|
||||
$modalBody.empty();
|
||||
const template = document.getElementById('field-template');
|
||||
const clone = document.importNode(template.content, true);
|
||||
$modalBody.append(clone);
|
||||
$('#add-field-modal .text-danger').remove();
|
||||
$modal.modal('show', 'fit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the editing field.
|
||||
*
|
||||
* @param {*} $fieldTr
|
||||
* @returns {[boolean, *]}
|
||||
*/
|
||||
function getEditingField($fieldTr)
|
||||
{
|
||||
const name = $fieldTr.find('.field-name').html();
|
||||
const isTextType = $fieldTr.find('.field-type').length;
|
||||
if(isTextType)
|
||||
{
|
||||
const type = $fieldTr.find('input.field-type').length ? 'text' : 'textarea';
|
||||
const placeholder = $fieldTr.find('input[type="text"]').prop('placeholder');
|
||||
const required = $fieldTr.find('input[type="text"]').closest('td').hasClass('required');
|
||||
return [true, {name, type, placeholder, required}];
|
||||
}
|
||||
|
||||
const $picker = $fieldTr.find('.picker');
|
||||
const type = $picker.hasClass('picker-multi') ? 'checkbox' : 'radio';
|
||||
const options = $picker.attr('data-options').split(',');
|
||||
const required = $picker.closest('td').hasClass('required');
|
||||
return [false, {name, type, options, required}];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the edit field button click event.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleEditFieldClick(event)
|
||||
{
|
||||
const $fieldTr = $(event.target).closest('tr');
|
||||
$editingField = $fieldTr;
|
||||
const [isTextType, field] = getEditingField($fieldTr);
|
||||
|
||||
const $modal = $('#edit-field-modal');
|
||||
const $modalBody = $modal.find('.modal-body');
|
||||
$modalBody.empty();
|
||||
const template = document.getElementById('field-template');
|
||||
const $clone = $(document.importNode(template.content, true));
|
||||
$modalBody.append($clone);
|
||||
$modalBody.find('input[name="field-name"]').prop('value', field.name);
|
||||
$modalBody.find('select[name="field-type"]').prop('value', field.type);
|
||||
|
||||
if(isTextType)
|
||||
{
|
||||
$modalBody.find('input[name="placeholder"]').prop('value', field.placeholder);
|
||||
$('input[name="placeholder"]').closest('tr').removeClass('hidden');
|
||||
$('.field-options').addClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
const $optionsWrapper = $modalBody.find('.field-options > td')
|
||||
$optionsWrapper.empty();
|
||||
const $optionsContainer = $(`<div class="options-container"></div>`)
|
||||
$optionsWrapper.append($optionsContainer);
|
||||
|
||||
field.options.forEach((option) =>
|
||||
{
|
||||
const template = document.getElementById('option-template');
|
||||
const $clone = $(document.importNode(template.content, true));
|
||||
$optionsContainer.append($clone);
|
||||
$optionsContainer.children('.input-group').last().find('input[name="option[]"]').prop('value', option);
|
||||
});
|
||||
|
||||
fixOptionsOrder();
|
||||
$('input[name="placeholder"]').closest('tr').addClass('hidden');
|
||||
$('.field-options').removeClass('hidden');
|
||||
}
|
||||
|
||||
if(field.required)
|
||||
{
|
||||
$modalBody.find('input[value="1"]').attr('checked', 'checked');
|
||||
$modalBody.find('input[value="0"]').removeAttr('checked');
|
||||
}
|
||||
else
|
||||
{
|
||||
$modalBody.find('input[value="0"]').attr('checked', 'checked');
|
||||
$modalBody.find('input[value="1"]').removeAttr('checked');
|
||||
}
|
||||
$('#edit-field-modal .text-danger').remove();
|
||||
$modal.modal('show', 'fit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the remove field button click event.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleRemoveFieldClick(event)
|
||||
{
|
||||
const result = window.confirm(deleteTip);
|
||||
if(result) $(event.target).closest('tr').remove();
|
||||
const $button = $('.field-configuration-main > div');
|
||||
const $table = $('.field-configuration-main > table');
|
||||
if($button.hasClass('hidden')) $button.removeClass('hidden');
|
||||
if(!$table.hasClass('hidden')) $table.addClass('hidden');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the save field button click event.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleSaveFieldClick()
|
||||
{
|
||||
const formData = new FormData(document.querySelector('#add-field-modal form'));
|
||||
const name = formData.get('field-name');
|
||||
if(!name)
|
||||
{
|
||||
const template = document.getElementById('text-danger-template');
|
||||
const $clone = $(document.importNode(template.content, true));
|
||||
$('#add-field-modal input[name="field-name"]')
|
||||
.closest('.required')
|
||||
.append($clone);
|
||||
return;
|
||||
}
|
||||
|
||||
$('#add-field-modal').modal('hide');
|
||||
const $fieldView = createFieldView(formData);
|
||||
$('#sortable-list').append($fieldView);
|
||||
const $button = $('.field-configuration-main > div');
|
||||
const $table = $('.field-configuration-main > table');
|
||||
if(!$button.hasClass('hidden')) $button.addClass('hidden');
|
||||
if($table.hasClass('hidden')) $table.removeClass('hidden');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle save edited field button click event.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleSaveEditedFieldClick()
|
||||
{
|
||||
const formData = new FormData(document.querySelector('#edit-field-modal form'));
|
||||
const name = formData.get('field-name');
|
||||
if(!name)
|
||||
{
|
||||
const template = document.getElementById('text-danger-template');
|
||||
const $clone = $(document.importNode(template.content, true));
|
||||
$('#edit-field-modal input[name="field-name"]')
|
||||
.closest('.required')
|
||||
.append($clone);
|
||||
return;
|
||||
}
|
||||
|
||||
$('#edit-field-modal').modal('hide');
|
||||
const $fieldView = createFieldView(formData);
|
||||
$editingField.replaceWith($fieldView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create field view.
|
||||
*
|
||||
* @param {FormData} formData
|
||||
* @returns {*}
|
||||
*/
|
||||
function createFieldView(formData)
|
||||
{
|
||||
const $tr = $(`<tr class="sortable-item"></tr>`);
|
||||
$tr.append(createFieldNameView(formData));
|
||||
$tr.append(createFieldTypeView(formData));
|
||||
$tr.append(createFieldButtons(formData));
|
||||
return $tr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create field name view.
|
||||
*
|
||||
* @param {FormData} formData
|
||||
* @returns {*}
|
||||
*/
|
||||
function createFieldNameView(formData)
|
||||
{
|
||||
const name = formData.get('field-name');
|
||||
return $(`<th class="drag-area">
|
||||
<div>
|
||||
<i class="icon icon-move"></i>
|
||||
<span class="field-name">${name}</span>
|
||||
</div>
|
||||
</th>`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create field type view.
|
||||
*
|
||||
* @param {FormData} formData
|
||||
* @returns {*}
|
||||
*/
|
||||
function createFieldTypeView(formData)
|
||||
{
|
||||
const type = formData.get('field-type');
|
||||
const required = formData.get('required') === '1';
|
||||
const $td = $('<td></td>');
|
||||
if(required) $td.addClass('required');
|
||||
if(type === 'text')
|
||||
{
|
||||
const placeholder = formData.get('placeholder') || pleaseInput;
|
||||
$td.append(`<input type="text" class="form-control field-type" placeholder="${placeholder}" />`);
|
||||
return $td;
|
||||
}
|
||||
|
||||
if(type === 'textarea')
|
||||
{
|
||||
const placeholder = formData.get('placeholder') || pleaseInput;
|
||||
$td.append(`<textarea class="form-control field-type" placeholder="${placeholder}" />`);
|
||||
return $td;
|
||||
}
|
||||
|
||||
const options = formData.getAll('option[]');
|
||||
const $picker = $(`<div class="picker"><input type="text"></div>`);
|
||||
if(type === 'checkbox') $picker.attr('data-multi', 'true');
|
||||
$picker.picker({list: options.map(option => ({text: option, value: option}))});
|
||||
$picker.attr('data-options', options.join(','));
|
||||
$td.append($picker);
|
||||
return $td;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create field buttons view.
|
||||
*
|
||||
* @returns {*}
|
||||
*/
|
||||
function createFieldButtons()
|
||||
{
|
||||
return $(`<td>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon" onclick="handleAddFieldClick()">
|
||||
<i class="icon icon-plus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon" onclick="handleEditFieldClick(event)">
|
||||
<i class="icon icon-edit"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon" onclick="handleRemoveFieldClick(event)">
|
||||
<i class="icon icon-trash"></i>
|
||||
</button>
|
||||
</td>`);
|
||||
}
|
||||
|
||||
$('#sortable-list').sortable({selector: '.sortable-item', trigger: '.drag-area'});
|
||||
@@ -0,0 +1,41 @@
|
||||
let selectedIcon;
|
||||
let selectedTheme;
|
||||
|
||||
function handleThemeButtonClick(event)
|
||||
{
|
||||
const $icon = $('#preview-icon');
|
||||
const $button = $(event.target).closest('button');
|
||||
const $prev = $('.theme-checked');
|
||||
$prev.removeClass('theme-checked');
|
||||
$button.addClass('theme-checked');
|
||||
$button.html($prev.html());
|
||||
$prev.empty();
|
||||
$icon.css('background-color', $button.css('background-color'));
|
||||
$icon.css('border', $button.css('border'));
|
||||
selectedTheme = $button.index();
|
||||
}
|
||||
|
||||
function handleIconButtonClick(event)
|
||||
{
|
||||
const $icon = $('#preview-icon');
|
||||
const $svg = $(event.target).closest('svg').clone();
|
||||
$icon.empty();
|
||||
$icon.append($svg);
|
||||
selectedIcon = $svg.prop('id');
|
||||
}
|
||||
|
||||
function handleSaveButtonClick()
|
||||
{
|
||||
const $editIcon = $('#ai-edit-icon');
|
||||
$editIcon.children().first('svg').remove();
|
||||
const $icon = $('#preview-icon');
|
||||
$editIcon.prepend($icon.find('svg').clone());
|
||||
$editIcon.css('background-color', $icon.css('background-color'));
|
||||
$editIcon.css('border', $icon.css('border'));
|
||||
$('input[name="iconTheme"]').prop('value', selectedTheme);
|
||||
$('input[name="iconName"]').prop('value', selectedIcon);
|
||||
}
|
||||
|
||||
$('#theme-buttons button').on('click', handleThemeButtonClick);
|
||||
$('#icon-buttons svg').on('click', handleIconButtonClick);
|
||||
$('#save-icon-button').on('click', handleSaveButtonClick);
|
||||
+83
-49
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The ai module en lang file of ZenTaoPMS.
|
||||
*
|
||||
@@ -403,12 +404,47 @@ $lang->ai->prompts->modules['doc'] = 'Document';
|
||||
$lang->ai->conversations = new stdclass();
|
||||
$lang->ai->conversations->common = 'Conversations';
|
||||
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = 'Mini Programs';
|
||||
$lang->ai->miniPrograms->create = 'Create A Program';
|
||||
$lang->ai->miniPrograms->configuration = 'Basic Information Configuration';
|
||||
$lang->ai->miniPrograms->downloadTip = 'Once created, your mini-program will be displayed on the AI Mini-Program Square in the client.';
|
||||
$lang->ai->miniPrograms->download = 'Download Zentao Client';
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = 'Mini Programs';
|
||||
$lang->ai->miniPrograms->create = 'Create A Program';
|
||||
$lang->ai->miniPrograms->configuration = 'Basic Information Configuration';
|
||||
$lang->ai->miniPrograms->downloadTip = 'Once created, your mini-program will be displayed on the AI Mini-Program Square in the client.';
|
||||
$lang->ai->miniPrograms->download = 'Download Zentao Client';
|
||||
$lang->ai->miniPrograms->category = 'Category';
|
||||
$lang->ai->miniPrograms->icon = 'Icon';
|
||||
$lang->ai->miniPrograms->desc = 'Introduction';
|
||||
$lang->ai->miniPrograms->categoryList = array('writing' => 'writing', 'statistics' => 'statistics', 'creative' => 'creative', 'raiders' => 'Guideline ', 'schedule' => 'schedule');
|
||||
$lang->ai->miniPrograms->modelList = array(' openai-GPT35 '=> 'openai/GPT-3.5');
|
||||
$lang->ai->miniPrograms->iconModification = 'Icon modification ';
|
||||
$lang->ai->miniPrograms->customBackground = 'Custom background Color ';
|
||||
$lang->ai->miniPrograms->customIcon = 'Custom icon';
|
||||
|
||||
$lang->ai->miniPrograms->placeholder = new stdClass();
|
||||
$lang->ai->miniPrograms->placeholder->name = 'Please enter a small program name ';
|
||||
$lang->ai->miniPrograms->placeholder->desc = 'Please enter a brief introduction to the miniprograms ';
|
||||
$lang->ai->miniPrograms->placeholder->default = 'Please fill in the prompt, the default is "please enter"';
|
||||
$lang->ai->miniPrograms->placeholder->input = 'Please enter ';
|
||||
|
||||
$lang->ai->miniPrograms->deleteTip = 'Are you sure to delete this field? ';
|
||||
|
||||
$lang->ai->miniPrograms->field = new stdClass();
|
||||
$lang->ai->miniPrograms->field->name = 'Field name ';
|
||||
$lang->ai->miniPrograms->field->duplicatedNameTip = 'This name is already used, please try another name';
|
||||
$lang->ai->miniPrograms->field->type = 'control type ';
|
||||
$lang->ai->miniPrograms->field->typeList = array(' single-line text ', 'multi-line text ',' single selection ', 'multi-selection ');
|
||||
$lang->ai->miniPrograms->field->placeholder = 'Fill hints ';
|
||||
$lang->ai->miniPrograms->field->required = 'Required ';
|
||||
$lang->ai->miniPrograms->field->isRequired = 'Yes ';
|
||||
$lang->ai->miniPrograms->field->isNotRequired = 'No ';
|
||||
$lang->ai->miniPrograms->field->add = 'New field ';
|
||||
$lang->ai->miniPrograms->field->addTitle = 'New field ';
|
||||
$lang->ai->miniPrograms->field->addTip = 'Please click here to add field information ';
|
||||
$lang->ai->miniPrograms->field->edit = 'Edit field ';
|
||||
$lang->ai->miniPrograms->field->configuration = 'Field Configuration area ';
|
||||
$lang->ai->miniPrograms->field->debug = 'debug area ';
|
||||
$lang->ai->miniPrograms->field->preview = 'Preview area ';
|
||||
$lang->ai->miniPrograms->field->option = 'Options ';
|
||||
$lang->ai->miniPrograms->field->emptyNameWarning = 'Name cannot be empty. ';
|
||||
|
||||
$lang->ai->models = new stdclass();
|
||||
$lang->ai->models->title = 'Language Model Configuration';
|
||||
@@ -493,8 +529,7 @@ $lang->ai->dataType->finishedDate = $lang->ai->dataType->datetime;
|
||||
$lang->ai->demoData = new stdclass();
|
||||
$lang->ai->demoData->notExist = 'The demo data does not exist for now.';
|
||||
$lang->ai->demoData->story = array(
|
||||
'story' => array
|
||||
(
|
||||
'story' => array(
|
||||
'title' => 'Develop an online learning platform',
|
||||
'spec' => 'We need to develop an online learning platform that provides course management, student management, teacher management, and other functions.',
|
||||
'verify' => '1. All functions can operate properly without any obvious errors or abnormalities.2. The interface is aesthetically pleasing and user-friendly.3. The platform can meet user needs and has a high level of user satisfaction.4. The code has good quality, with clear structure and easy maintenance.',
|
||||
@@ -505,8 +540,7 @@ $lang->ai->demoData->story = array(
|
||||
'category' => 'feature',
|
||||
),
|
||||
);
|
||||
$lang->ai->demoData->execution = array
|
||||
(
|
||||
$lang->ai->demoData->execution = array(
|
||||
'execution' => array(
|
||||
'name' => 'Online Learning Platform Software Development',
|
||||
'desc' => 'This plan aims to develop an online learning platform software that provides accessible learning resources, including text, video, and audio, as well as some learning tools such as exams, tests, and discussion forums.',
|
||||
@@ -514,47 +548,47 @@ $lang->ai->demoData->execution = array
|
||||
),
|
||||
'tasks' => array(
|
||||
0 =>
|
||||
array(
|
||||
'name' => 'Technology Selection',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => 'Completed',
|
||||
),
|
||||
array(
|
||||
'name' => 'Technology Selection',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => 'Completed',
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'name' => 'UI Design',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'UI Design',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'name' => 'Development',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'Development',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
+83
-49
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The ai module en lang file of ZenTaoPMS.
|
||||
*
|
||||
@@ -403,12 +404,47 @@ $lang->ai->prompts->modules['doc'] = 'Document';
|
||||
$lang->ai->conversations = new stdclass();
|
||||
$lang->ai->conversations->common = 'Conversations';
|
||||
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = 'Mini Programs';
|
||||
$lang->ai->miniPrograms->create = 'Create A Program';
|
||||
$lang->ai->miniPrograms->configuration = 'Basic Information Configuration';
|
||||
$lang->ai->miniPrograms->downloadTip = 'Once created, your mini-program will be displayed on the AI Mini-Program Square in the client.';
|
||||
$lang->ai->miniPrograms->download = 'Download Zentao Client';
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = 'Mini Programs';
|
||||
$lang->ai->miniPrograms->create = 'Create A Program';
|
||||
$lang->ai->miniPrograms->configuration = 'Basic Information Configuration';
|
||||
$lang->ai->miniPrograms->downloadTip = 'Once created, your mini-program will be displayed on the AI Mini-Program Square in the client.';
|
||||
$lang->ai->miniPrograms->download = 'Download Zentao Client';
|
||||
$lang->ai->miniPrograms->category = 'Category';
|
||||
$lang->ai->miniPrograms->icon = 'Icon';
|
||||
$lang->ai->miniPrograms->desc = 'Introduction';
|
||||
$lang->ai->miniPrograms->categoryList = array('writing' => 'writing', 'statistics' => 'statistics', 'creative' => 'creative', 'raiders' => 'Guideline ', 'schedule' => 'schedule');
|
||||
$lang->ai->miniPrograms->modelList = array(' openai-GPT35 '=> 'openai/GPT-3.5');
|
||||
$lang->ai->miniPrograms->iconModification = 'Icon modification ';
|
||||
$lang->ai->miniPrograms->customBackground = 'Custom background Color ';
|
||||
$lang->ai->miniPrograms->customIcon = 'Custom icon';
|
||||
|
||||
$lang->ai->miniPrograms->placeholder = new stdClass();
|
||||
$lang->ai->miniPrograms->placeholder->name = 'Please enter a small program name ';
|
||||
$lang->ai->miniPrograms->placeholder->desc = 'Please enter a brief introduction to the miniprograms ';
|
||||
$lang->ai->miniPrograms->placeholder->default = 'Please fill in the prompt, the default is "please enter"';
|
||||
$lang->ai->miniPrograms->placeholder->input = 'Please enter ';
|
||||
|
||||
$lang->ai->miniPrograms->deleteTip = 'Are you sure to delete this field? ';
|
||||
|
||||
$lang->ai->miniPrograms->field = new stdClass();
|
||||
$lang->ai->miniPrograms->field->name = 'Field name ';
|
||||
$lang->ai->miniPrograms->field->duplicatedNameTip = 'This name is already used, please try another name';
|
||||
$lang->ai->miniPrograms->field->type = 'control type ';
|
||||
$lang->ai->miniPrograms->field->typeList = array(' single-line text ', 'multi-line text ',' single selection ', 'multi-selection ');
|
||||
$lang->ai->miniPrograms->field->placeholder = 'Fill hints ';
|
||||
$lang->ai->miniPrograms->field->required = 'Required ';
|
||||
$lang->ai->miniPrograms->field->isRequired = 'Yes ';
|
||||
$lang->ai->miniPrograms->field->isNotRequired = 'No ';
|
||||
$lang->ai->miniPrograms->field->add = 'New field ';
|
||||
$lang->ai->miniPrograms->field->addTitle = 'New field ';
|
||||
$lang->ai->miniPrograms->field->addTip = 'Please click here to add field information ';
|
||||
$lang->ai->miniPrograms->field->edit = 'Edit field ';
|
||||
$lang->ai->miniPrograms->field->configuration = 'Field Configuration area ';
|
||||
$lang->ai->miniPrograms->field->debug = 'debug area ';
|
||||
$lang->ai->miniPrograms->field->preview = 'Preview area ';
|
||||
$lang->ai->miniPrograms->field->option = 'Options ';
|
||||
$lang->ai->miniPrograms->field->emptyNameWarning = 'Name cannot be empty. ';
|
||||
|
||||
$lang->ai->models = new stdclass();
|
||||
$lang->ai->models->title = 'Language Model Configuration';
|
||||
@@ -493,8 +529,7 @@ $lang->ai->dataType->finishedDate = $lang->ai->dataType->datetime;
|
||||
$lang->ai->demoData = new stdclass();
|
||||
$lang->ai->demoData->notExist = 'The demo data does not exist for now.';
|
||||
$lang->ai->demoData->story = array(
|
||||
'story' => array
|
||||
(
|
||||
'story' => array(
|
||||
'title' => 'Develop an online learning platform',
|
||||
'spec' => 'We need to develop an online learning platform that provides course management, student management, teacher management, and other functions.',
|
||||
'verify' => '1. All functions can operate properly without any obvious errors or abnormalities.2. The interface is aesthetically pleasing and user-friendly.3. The platform can meet user needs and has a high level of user satisfaction.4. The code has good quality, with clear structure and easy maintenance.',
|
||||
@@ -505,8 +540,7 @@ $lang->ai->demoData->story = array(
|
||||
'category' => 'feature',
|
||||
),
|
||||
);
|
||||
$lang->ai->demoData->execution = array
|
||||
(
|
||||
$lang->ai->demoData->execution = array(
|
||||
'execution' => array(
|
||||
'name' => 'Online Learning Platform Software Development',
|
||||
'desc' => 'This plan aims to develop an online learning platform software that provides accessible learning resources, including text, video, and audio, as well as some learning tools such as exams, tests, and discussion forums.',
|
||||
@@ -514,47 +548,47 @@ $lang->ai->demoData->execution = array
|
||||
),
|
||||
'tasks' => array(
|
||||
0 =>
|
||||
array(
|
||||
'name' => 'Technology Selection',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => 'Completed',
|
||||
),
|
||||
array(
|
||||
'name' => 'Technology Selection',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => 'Completed',
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'name' => 'UI Design',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'UI Design',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'name' => 'Development',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'Development',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
+83
-49
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The ai module en lang file of ZenTaoPMS.
|
||||
*
|
||||
@@ -403,12 +404,47 @@ $lang->ai->prompts->modules['doc'] = 'Document';
|
||||
$lang->ai->conversations = new stdclass();
|
||||
$lang->ai->conversations->common = 'Conversations';
|
||||
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = 'Mini Programs';
|
||||
$lang->ai->miniPrograms->create = 'Create A Program';
|
||||
$lang->ai->miniPrograms->configuration = 'Basic Information Configuration';
|
||||
$lang->ai->miniPrograms->downloadTip = 'Once created, your mini-program will be displayed on the AI Mini-Program Square in the client.';
|
||||
$lang->ai->miniPrograms->download = 'Download Zentao Client';
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = 'Mini Programs';
|
||||
$lang->ai->miniPrograms->create = 'Create A Program';
|
||||
$lang->ai->miniPrograms->configuration = 'Basic Information Configuration';
|
||||
$lang->ai->miniPrograms->downloadTip = 'Once created, your mini-program will be displayed on the AI Mini-Program Square in the client.';
|
||||
$lang->ai->miniPrograms->download = 'Download Zentao Client';
|
||||
$lang->ai->miniPrograms->category = 'Category';
|
||||
$lang->ai->miniPrograms->icon = 'Icon';
|
||||
$lang->ai->miniPrograms->desc = 'Introduction';
|
||||
$lang->ai->miniPrograms->categoryList = array('writing' => 'writing', 'statistics' => 'statistics', 'creative' => 'creative', 'raiders' => 'Guideline ', 'schedule' => 'schedule');
|
||||
$lang->ai->miniPrograms->modelList = array(' openai-GPT35 '=> 'openai/GPT-3.5');
|
||||
$lang->ai->miniPrograms->iconModification = 'Icon modification ';
|
||||
$lang->ai->miniPrograms->customBackground = 'Custom background Color ';
|
||||
$lang->ai->miniPrograms->customIcon = 'Custom icon';
|
||||
|
||||
$lang->ai->miniPrograms->placeholder = new stdClass();
|
||||
$lang->ai->miniPrograms->placeholder->name = 'Please enter a small program name ';
|
||||
$lang->ai->miniPrograms->placeholder->desc = 'Please enter a brief introduction to the miniprograms ';
|
||||
$lang->ai->miniPrograms->placeholder->default = 'Please fill in the prompt, the default is "please enter"';
|
||||
$lang->ai->miniPrograms->placeholder->input = 'Please enter ';
|
||||
|
||||
$lang->ai->miniPrograms->deleteTip = 'Are you sure to delete this field? ';
|
||||
|
||||
$lang->ai->miniPrograms->field = new stdClass();
|
||||
$lang->ai->miniPrograms->field->name = 'Field name ';
|
||||
$lang->ai->miniPrograms->field->duplicatedNameTip = 'This name is already used, please try another name';
|
||||
$lang->ai->miniPrograms->field->type = 'control type ';
|
||||
$lang->ai->miniPrograms->field->typeList = array(' single-line text ', 'multi-line text ',' single selection ', 'multi-selection ');
|
||||
$lang->ai->miniPrograms->field->placeholder = 'Fill hints ';
|
||||
$lang->ai->miniPrograms->field->required = 'Required ';
|
||||
$lang->ai->miniPrograms->field->isRequired = 'Yes ';
|
||||
$lang->ai->miniPrograms->field->isNotRequired = 'No ';
|
||||
$lang->ai->miniPrograms->field->add = 'New field ';
|
||||
$lang->ai->miniPrograms->field->addTitle = 'New field ';
|
||||
$lang->ai->miniPrograms->field->addTip = 'Please click here to add field information ';
|
||||
$lang->ai->miniPrograms->field->edit = 'Edit field ';
|
||||
$lang->ai->miniPrograms->field->configuration = 'Field Configuration area ';
|
||||
$lang->ai->miniPrograms->field->debug = 'debug area ';
|
||||
$lang->ai->miniPrograms->field->preview = 'Preview area ';
|
||||
$lang->ai->miniPrograms->field->option = 'Options ';
|
||||
$lang->ai->miniPrograms->field->emptyNameWarning = 'Name cannot be empty. ';
|
||||
|
||||
$lang->ai->models = new stdclass();
|
||||
$lang->ai->models->title = 'Language Model Configuration';
|
||||
@@ -493,8 +529,7 @@ $lang->ai->dataType->finishedDate = $lang->ai->dataType->datetime;
|
||||
$lang->ai->demoData = new stdclass();
|
||||
$lang->ai->demoData->notExist = 'The demo data does not exist for now.';
|
||||
$lang->ai->demoData->story = array(
|
||||
'story' => array
|
||||
(
|
||||
'story' => array(
|
||||
'title' => 'Develop an online learning platform',
|
||||
'spec' => 'We need to develop an online learning platform that provides course management, student management, teacher management, and other functions.',
|
||||
'verify' => '1. All functions can operate properly without any obvious errors or abnormalities.2. The interface is aesthetically pleasing and user-friendly.3. The platform can meet user needs and has a high level of user satisfaction.4. The code has good quality, with clear structure and easy maintenance.',
|
||||
@@ -505,8 +540,7 @@ $lang->ai->demoData->story = array(
|
||||
'category' => 'feature',
|
||||
),
|
||||
);
|
||||
$lang->ai->demoData->execution = array
|
||||
(
|
||||
$lang->ai->demoData->execution = array(
|
||||
'execution' => array(
|
||||
'name' => 'Online Learning Platform Software Development',
|
||||
'desc' => 'This plan aims to develop an online learning platform software that provides accessible learning resources, including text, video, and audio, as well as some learning tools such as exams, tests, and discussion forums.',
|
||||
@@ -514,47 +548,47 @@ $lang->ai->demoData->execution = array
|
||||
),
|
||||
'tasks' => array(
|
||||
0 =>
|
||||
array(
|
||||
'name' => 'Technology Selection',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => 'Completed',
|
||||
),
|
||||
array(
|
||||
'name' => 'Technology Selection',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => 'Completed',
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'name' => 'UI Design',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'UI Design',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'name' => 'Development',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'Development',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
+83
-49
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The ai module zh-cn lang file of ZenTaoPMS.
|
||||
*
|
||||
@@ -403,12 +404,47 @@ $lang->ai->prompts->modules['doc'] = '文档';
|
||||
$lang->ai->conversations = new stdclass();
|
||||
$lang->ai->conversations->common = '会话';
|
||||
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = '小程序';
|
||||
$lang->ai->miniPrograms->create = '创建小程序';
|
||||
$lang->ai->miniPrograms->configuration = '基本信息配置';
|
||||
$lang->ai->miniPrograms->downloadTip = '创建完成后,您的小程序将在客户端的AI小程序广场上展示。';
|
||||
$lang->ai->miniPrograms->download = '下载禅道客户端';
|
||||
$lang->ai->miniPrograms = new stdClass();
|
||||
$lang->ai->miniPrograms->common = '小程序';
|
||||
$lang->ai->miniPrograms->create = '创建小程序';
|
||||
$lang->ai->miniPrograms->configuration = '基本信息配置';
|
||||
$lang->ai->miniPrograms->downloadTip = '创建完成后,您的小程序将在客户端的AI小程序广场上展示。';
|
||||
$lang->ai->miniPrograms->download = '下载禅道客户端';
|
||||
$lang->ai->miniPrograms->category = '所属分类';
|
||||
$lang->ai->miniPrograms->icon = '图标';
|
||||
$lang->ai->miniPrograms->desc = '简介';
|
||||
$lang->ai->miniPrograms->categoryList = array('writing' => '写作', 'statistics' => '统计', 'creative' => '创意', 'raiders' => '攻略', 'schedule' => '日程');
|
||||
$lang->ai->miniPrograms->modelList = array('openai-gpt35' => 'OpenAI / GPT-3.5');
|
||||
$lang->ai->miniPrograms->iconModification = '图标修改';
|
||||
$lang->ai->miniPrograms->customBackground = '自定义背景色';
|
||||
$lang->ai->miniPrograms->customIcon = '自定义icon';
|
||||
|
||||
$lang->ai->miniPrograms->placeholder = new stdClass();
|
||||
$lang->ai->miniPrograms->placeholder->name = '请输入小程序名称';
|
||||
$lang->ai->miniPrograms->placeholder->desc = '请输入小程序简介';
|
||||
$lang->ai->miniPrograms->placeholder->default = '请输入填写提示,默认为“请输入”';
|
||||
$lang->ai->miniPrograms->placeholder->input = '请输入';
|
||||
|
||||
$lang->ai->miniPrograms->deleteTip = '您确定删除该字段吗?';
|
||||
|
||||
$lang->ai->miniPrograms->field = new stdClass();
|
||||
$lang->ai->miniPrograms->field->name = '字段名称';
|
||||
$lang->ai->miniPrograms->field->duplicatedNameTip = '该名称已使用,请尝试其他名称';
|
||||
$lang->ai->miniPrograms->field->type = '控件类型';
|
||||
$lang->ai->miniPrograms->field->typeList = array('单行文本', '多行文本', '单选', '多选');
|
||||
$lang->ai->miniPrograms->field->placeholder = '填写提示';
|
||||
$lang->ai->miniPrograms->field->required = '是否必填';
|
||||
$lang->ai->miniPrograms->field->isRequired = '是';
|
||||
$lang->ai->miniPrograms->field->isNotRequired = '否';
|
||||
$lang->ai->miniPrograms->field->add = '新增字段';
|
||||
$lang->ai->miniPrograms->field->addTitle = '新增字段';
|
||||
$lang->ai->miniPrograms->field->addTip = '请点击此处以添加字段信息';
|
||||
$lang->ai->miniPrograms->field->edit = '编辑字段';
|
||||
$lang->ai->miniPrograms->field->configuration = '字段配置区';
|
||||
$lang->ai->miniPrograms->field->debug = '调试区';
|
||||
$lang->ai->miniPrograms->field->preview = '预览区';
|
||||
$lang->ai->miniPrograms->field->option = '选项';
|
||||
$lang->ai->miniPrograms->field->emptyNameWarning = '『名称』不能为空。';
|
||||
|
||||
$lang->ai->models = new stdclass();
|
||||
$lang->ai->models->title = '语言模型配置';
|
||||
@@ -493,8 +529,7 @@ $lang->ai->dataType->finishedDate = $lang->ai->dataType->datetime;
|
||||
$lang->ai->demoData = new stdclass();
|
||||
$lang->ai->demoData->notExist = '暂无演示数据。';
|
||||
$lang->ai->demoData->story = array(
|
||||
'story' => array
|
||||
(
|
||||
'story' => array(
|
||||
'title' => '开发一个在线学习平台',
|
||||
'spec' => '我们需要开发一个在线学习平台,能够提供课程管理、学生管理、教师管理等功能。',
|
||||
'verify' => '1. 所有功能均能够正常运行,没有明显的错误和异常。2. 界面美观、易用性好。3. 平台能够满足用户需求,具有较高的用户满意度。4. 代码质量好,结构清晰、易于维护。',
|
||||
@@ -505,8 +540,7 @@ $lang->ai->demoData->story = array(
|
||||
'category' => 'feature',
|
||||
),
|
||||
);
|
||||
$lang->ai->demoData->execution = array
|
||||
(
|
||||
$lang->ai->demoData->execution = array(
|
||||
'execution' => array(
|
||||
'name' => '在线学习平台软件开发',
|
||||
'desc' => '本计划旨在开发一款在线学习平台软件,该软件将提供可访问的学习资源,包括文本、视频和音频等,以及一些学习工具如考试、测试和讨论论坛等。',
|
||||
@@ -514,47 +548,47 @@ $lang->ai->demoData->execution = array
|
||||
),
|
||||
'tasks' => array(
|
||||
0 =>
|
||||
array(
|
||||
'name' => '技术选型',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => '已完成',
|
||||
),
|
||||
array(
|
||||
'name' => '技术选型',
|
||||
'pri' => 1,
|
||||
'status' => 'done',
|
||||
'estimate' => 1,
|
||||
'consumed' => 1,
|
||||
'left' => 0,
|
||||
'progress' => 100,
|
||||
'estStarted' => '2023-07-02 00:00:00',
|
||||
'realStarted' => '2023-07-02 00:00:00',
|
||||
'finishedDate' => '2023-07-02 00:00:00',
|
||||
'closedReason' => '已完成',
|
||||
),
|
||||
1 =>
|
||||
array(
|
||||
'name' => 'UI设计',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => 'UI设计',
|
||||
'pri' => 1,
|
||||
'status' => 'doing',
|
||||
'estimate' => 2,
|
||||
'consumed' => 1,
|
||||
'left' => 1,
|
||||
'progress' => 50,
|
||||
'estStarted' => '2023-07-03 00:00:00',
|
||||
'realStarted' => '2023-07-03 00:00:00',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'name' => '开发',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
array(
|
||||
'name' => '开发',
|
||||
'pri' => 1,
|
||||
'status' => 'wait',
|
||||
'estimate' => 1,
|
||||
'consumed' => 0,
|
||||
'left' => 1,
|
||||
'progress' => 0,
|
||||
'estStarted' => '',
|
||||
'realStarted' => '',
|
||||
'finishedDate' => '',
|
||||
'closedReason' => '',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -304,6 +304,63 @@ class aiModel extends model
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temp mini program.
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createTmpMiniProgram()
|
||||
{
|
||||
$data = fixer::input('post')->get();
|
||||
$data->createdBy = $this->app->user->account;
|
||||
$data->createdDate = helper::now();
|
||||
$data->editedBy = $this->app->user->account;
|
||||
$data->editedDate = helper::now();
|
||||
$data->icon = $data->iconName . '-' . $data->iconTheme;
|
||||
unset($data->iconName);
|
||||
unset($data->iconTheme);
|
||||
$this->dao->insert(TABLE_MINIPROGRAM)
|
||||
->data($data)
|
||||
->exec();
|
||||
if(dao::isError()) return false;
|
||||
return $this->dao->lastInsertID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for duplicate names of Mini programs.
|
||||
*
|
||||
* @param string $name
|
||||
* @access public
|
||||
* @return boolean
|
||||
*/
|
||||
public function checkDuplicatedAppName($name)
|
||||
{
|
||||
$miniProgram = $this->dao->select('*')
|
||||
->from(TABLE_MINIPROGRAM)
|
||||
->where('name')->eq($name)
|
||||
->fetch();
|
||||
return !empty($miniProgram);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that any required fields are empty.
|
||||
*
|
||||
* @param array $requiredFields
|
||||
* @access public
|
||||
* @return false|array false or errors.
|
||||
*/
|
||||
public function verifyRequiredFields($requiredFields)
|
||||
{
|
||||
$errors = array();
|
||||
foreach($requiredFields as $field => $fieldLang)
|
||||
{
|
||||
if(!isset($_POST[$field]) || empty($_POST[$field])) $errors[$field] = sprintf($this->lang->error->notempty, $fieldLang);
|
||||
}
|
||||
if(!empty($errors)) return $errors;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse text responses from simple APIs. For example, completion.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The create ai mini program file of ai module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Wenrui LI <liwenrui@easycorp.ltd>
|
||||
* @package ai
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php'; ?>
|
||||
|
||||
<?php
|
||||
js::set('pleaseInput', $lang->ai->miniPrograms->placeholder->input);
|
||||
js::set('deleteTip', $lang->ai->miniPrograms->deleteTip);
|
||||
?>
|
||||
|
||||
|
||||
<template id="text-danger-template">
|
||||
<div id="nameLabel" class="text-danger help-text"><?php echo $lang->ai->miniPrograms->field->emptyNameWarning; ?></div>
|
||||
</template>
|
||||
|
||||
<template id="option-template">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><?php echo $lang->ai->miniPrograms->field->option; ?>1</span>
|
||||
<input name="option[]" type="text" class="form-control" placeholder="<?php echo $lang->ai->miniPrograms->placeholder->input; ?>" />
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-default btn-icon" onclick="handleAddOptionClick(event)"><i class="icon icon-plus"></i></button>
|
||||
<button type="button" class="btn btn-default btn-icon" onclick="handleRemoveOptionClick(event)"><i class="icon icon-minus"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="field-template">
|
||||
<form>
|
||||
<table class="table table-form">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->field->name; ?></th>
|
||||
<td class="required"><input type="text" name="field-name" class="form-control" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->field->type; ?></th>
|
||||
<td>
|
||||
<select name="field-type" class="form-control" onchange="handleFieldTypeChange(event)">
|
||||
<option value="text"><?php echo $lang->ai->miniPrograms->field->typeList[0]; ?></option>
|
||||
<option value="textarea"><?php echo $lang->ai->miniPrograms->field->typeList[1]; ?></option>
|
||||
<option value="radio"><?php echo $lang->ai->miniPrograms->field->typeList[2]; ?></option>
|
||||
<option value="checkbox"><?php echo $lang->ai->miniPrograms->field->typeList[3]; ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->field->placeholder; ?></th>
|
||||
<td><input name="placeholder" type="text" class="form-control" placeholder="<?php echo $lang->ai->miniPrograms->placeholder->default; ?>" /></td>
|
||||
</tr>
|
||||
<tr class="field-options hidden">
|
||||
<th></th>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->field->required; ?></th>
|
||||
<td>
|
||||
<div class="radio" style="display: flex; align-items: center; gap: 4px;">
|
||||
<label>
|
||||
<input type="radio" name="required" value="1" checked><?php echo $lang->ai->miniPrograms->field->isRequired; ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="required" value="0"><?php echo $lang->ai->miniPrograms->field->isNotRequired; ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<div class="modal fade" id="add-field-modal">
|
||||
<div class="modal-dialog" style="width: 600px;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="border-bottom: none; padding-left: 12px;">
|
||||
<strong style="font-size: 20px;"><?php echo $lang->ai->miniPrograms->field->add; ?></strong>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body" style="display: flex; gap: 42px; padding-right: 36px;"></div>
|
||||
<div class="modal-footer" style="display: flex; justify-content: center; border-top: none;">
|
||||
<button type="button" class="btn btn-wide btn-primary" id="save-add-field-button" onclick="handleSaveFieldClick()"><?php echo $lang->save; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="edit-field-modal">
|
||||
<div class="modal-dialog" style="width: 600px;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="border-bottom: none; padding-left: 12px;">
|
||||
<strong style="font-size: 20px;"><?php echo $lang->ai->miniPrograms->field->edit; ?></strong>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body" style="display: flex; gap: 42px; padding-right: 36px;"></div>
|
||||
<div class="modal-footer" style="display: flex; justify-content: center; border-top: none;">
|
||||
<button type="button" class="btn btn-wide btn-primary" id="save-add-field-button" onclick="handleSaveEditedFieldClick()"><?php echo $lang->save; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainContent" class="main-content">
|
||||
<div style="flex-basis: 30%; margin-right: 16px;">
|
||||
<header>
|
||||
<strong><?php echo $lang->ai->miniPrograms->field->configuration; ?></strong>
|
||||
</header>
|
||||
<main class="field-configuration-main">
|
||||
<div>
|
||||
<a onclick="handleAddFieldClick()" style="border: 1px dashed #D8DBDE; border-radius: 2px; margin: 25px 72px; display: flex; align-items: center; flex-direction: column; padding: 12px; gap: 4px;">
|
||||
<div style="color: #2E7FFF; display: flex; align-items: center; gap: 4px;"><i class="icon icon-plus"></i><span><?php echo $lang->ai->miniPrograms->field->addTitle; ?></span></div>
|
||||
<div style="color: #9EA3B0; font-size: 12divx;"><?php echo $lang->ai->miniPrograms->field->addTip; ?></div>
|
||||
</a>
|
||||
</div>
|
||||
<table class="table table-form">
|
||||
<tbody class="field-configuration" id="sortable-list"></tbody>
|
||||
</table>
|
||||
</main>
|
||||
</div>
|
||||
<div style="flex-basis: 40%; border-right: 1px solid #E6EAF1;">
|
||||
<header>
|
||||
<strong><?php echo $lang->ai->miniPrograms->field->debug; ?></strong>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
<div style="flex-basis: 30%;">
|
||||
<header>
|
||||
<strong><?php echo $lang->ai->miniPrograms->field->preview; ?></strong>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The create ai mini program file of ai module of ZenTaoPMS.
|
||||
*
|
||||
@@ -10,14 +11,111 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php'; ?>
|
||||
<div id="mainContent" class="main-content" style="position: fixed; top: 70px; right: 20px; bottom: 0; left: 20px;">
|
||||
<div class="center-block" style="width: 660px;">
|
||||
<div style="display: flex; align-items: center; justify-content: flex-start;">
|
||||
<strong style="font-size: 16px;"><?php echo $lang->ai->miniPrograms->configuration; ?></strong>
|
||||
<i title="<?php echo $lang->help; ?>" class="icon icon-help text-warning" style="padding-left: 8px; padding-right: 2px;"></i>
|
||||
<span class="text-muted"><?php echo $lang->ai->miniPrograms->downloadTip; ?></span>
|
||||
<a class="text-primary" href="https://www.zentao.net/page/download-client.html" target="_blank">>><?php echo $lang->ai->miniPrograms->download; ?></a>
|
||||
</div>
|
||||
<div id="mainContent" class="main-content" style="position: fixed; top: 66px; right: 16px; bottom: 16px; left: 16px;">
|
||||
<div style="width: 660px; margin: 0 auto;">
|
||||
<div style="display: flex; align-items: center; justify-content: flex-start; margin-bottom: 20px;">
|
||||
<strong style="font-size: 16px;"><?php echo $lang->ai->miniPrograms->configuration; ?></strong>
|
||||
<i title="<?php echo $lang->help; ?>" class="icon icon-help text-warning" style="padding-left: 8px; padding-right: 2px;"></i>
|
||||
<span class="text-muted"><?php echo $lang->ai->miniPrograms->downloadTip; ?></span>
|
||||
<a class="text-primary" href="https://www.zentao.net/page/download-client.html" target="_blank">>><?php echo $lang->ai->miniPrograms->download; ?></a>
|
||||
</div>
|
||||
<form class="main-form form-ajax" method="post">
|
||||
<table class="table table-form">
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->category; ?></th>
|
||||
<td>
|
||||
<?php echo html::select('category', $lang->ai->miniPrograms->categoryList, '', "class='form-control chosen' required"); ?>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->prompt->model; ?></th>
|
||||
<td>
|
||||
<?php echo html::select('model', $lang->ai->miniPrograms->modelList, '', "class='form-control chosen' required"); ?>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->prompt->name; ?></th>
|
||||
<td colspan="2">
|
||||
<?php echo html::input('name', $name, "class='form-control' required placeholder='" . $lang->ai->miniPrograms->placeholder->name . "'"); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->desc; ?></th>
|
||||
<td colspan="2">
|
||||
<?php echo html::input('desc', $introduction, "class='form-control' placeholder='" . $lang->ai->miniPrograms->placeholder->desc . "'"); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->miniPrograms->icon; ?></th>
|
||||
<td>
|
||||
<button id="ai-edit-icon" style="width: 46px; height: 46px; border-radius: 50%; border: 1px solid <?php echo $config->ai->miniPrograms->themeList[$iconTheme][1]; ?>; background-color: <?php echo $config->ai->miniPrograms->themeList[$iconTheme][0]; ?>;" type="button" class="btn btn-icon" data-toggle="modal" data-target="#edit-icon-modal">
|
||||
<?php echo $config->ai->miniPrograms->iconList[$iconName]; ?>
|
||||
<div id="edit-icon">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.78327 6.01523C5.78327 5.80353 5.95489 5.6319 6.1666 5.6319H11.3142C11.5259 5.6319 11.6976 5.46028 11.6976 5.24857C11.6976 5.03686 11.5259 4.86523 11.3142 4.86523H6.1666C5.53147 4.86523 5.0166 5.38011 5.0166 6.01523V13.6819C5.0166 14.317 5.53147 14.8319 6.1666 14.8319H13.8333C14.4684 14.8319 14.9833 14.317 14.9833 13.6819V8.53428C14.9833 8.32257 14.8116 8.15095 14.5999 8.15095C14.3882 8.15095 14.2166 8.32257 14.2166 8.53428V13.6819C14.2166 13.8936 14.045 14.0652 13.8333 14.0652H6.1666C5.95489 14.0652 5.78327 13.8936 5.78327 13.6819V6.01523Z" fill="#2E7FFF" />
|
||||
<path d="M14.9 5.55565C15.0515 5.40777 15.0545 5.16508 14.9066 5.01357C14.7587 4.86207 14.516 4.85912 14.3645 5.007L8.93315 10.3082C8.78165 10.456 8.7787 10.6987 8.92658 10.8502C9.07445 11.0018 9.31714 11.0047 9.46865 10.8568L14.9 5.55565Z" fill="#2E7FFF" />
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</td>
|
||||
<td class="hidden">
|
||||
<?php echo html::input('iconName', $iconName, "class='form-control'") ?>
|
||||
<?php echo html::input('iconTheme', $iconTheme, "class='form-control'") ?>
|
||||
</td>
|
||||
</tr>
|
||||
<div style="position: fixed; left: 0; right: 0; bottom: 32px; display: flex; justify-content: center; gap: 24px;">
|
||||
<?php echo html::a($this->createLink('ai', 'miniPrograms'), $lang->goback, '', "class='btn btn-back btn-wide'"); ?>
|
||||
<button class="btn btn-wide btn-secondary"><?php echo $lang->save; ?></button>
|
||||
<button class="btn btn-wide btn-primary" type="submit"><?php echo $lang->ai->nextStep; ?></button>
|
||||
</div>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="edit-icon-modal">
|
||||
<div class="modal-dialog" style="width: 600px;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="border-bottom: none;">
|
||||
<div style="display: inline-flex; gap: 8px; align-items: center;">
|
||||
<strong style="font-size: 20px;"><?php echo $lang->ai->miniPrograms->iconModification; ?></strong>
|
||||
<span class="text-muted">Emoji icons by Twemoji with CC-BY4.0</span>
|
||||
</div>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body" style="display: flex; gap: 42px;">
|
||||
<div class="icon-preview-container">
|
||||
<button id="preview-icon" class="btn btn-icon" style="width: 46px; height: 46px; border-radius: 50%; display: flex; justify-content: center; align-items: center; border: 1px solid <?php echo $config->ai->miniPrograms->themeList[$iconTheme][1]; ?>; background-color: <?php echo $config->ai->miniPrograms->themeList[$iconTheme][0]; ?>">
|
||||
<?php echo $config->ai->miniPrograms->iconList[$iconName]; ?>
|
||||
</button>
|
||||
</div>
|
||||
<div class="icon-setting-container">
|
||||
<div>
|
||||
<header style="margin-bottom: 12px;"><?php echo $lang->ai->miniPrograms->customBackground; ?></header>
|
||||
<div id="theme-buttons" style="display: flex; gap: 20px; width: 400px;">
|
||||
<?php
|
||||
foreach($config->ai->miniPrograms->themeList as $theme)
|
||||
{
|
||||
if($config->ai->miniPrograms->themeList[$iconTheme][0] === $theme[0]) echo "<button type='button' class='btn btn-icon theme-checked' style='width: 32px; height: 32px; border-radius: 50%; background-color: $theme[0]; border: 1px solid $theme[1];'>{$config->ai->miniPrograms->iconCheck}</button>";
|
||||
echo "<button type='button' class='btn btn-icon' style='width: 32px; height: 32px; border-radius: 50%; background-color: $theme[0]; border: 1px solid $theme[1];'></button>";
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 32px;">
|
||||
<header style="margin-bottom: 12px;"><?php echo $lang->ai->miniPrograms->customIcon; ?></header>
|
||||
<div id="icon-buttons" style="display: grid; column-gap: 20px; row-gap: 16px; grid-template-columns: repeat(8, 1fr); justify-items: center; align-items: center;">
|
||||
<?php foreach($config->ai->miniPrograms->iconList as $name => $icon) echo $icon; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="display: flex; justify-content: center; border-top: none;">
|
||||
<button type="button" class="btn btn-wide btn-primary" id="save-icon-button" data-dismiss="modal"><?php echo $lang->save; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php'; ?>
|
||||
|
||||
@@ -759,6 +759,7 @@ $lang->navGroup->host = 'admin';
|
||||
$lang->navGroup->ops = 'admin';
|
||||
$lang->navGroup->service = 'admin';
|
||||
$lang->navGroup->domain = 'admin';
|
||||
$lang->navGroup->ai = 'admin';
|
||||
|
||||
$lang->navGroup->index = 'index';
|
||||
$lang->navGroup->misc = 'misc';
|
||||
|
||||
+310
-320
@@ -1,355 +1,345 @@
|
||||
<?php $oldMaxCount = $this->config->maxCount;?>
|
||||
<?php $this->config->maxCount = 500;?>
|
||||
<?php $oldMaxCount = $this->config->maxCount; ?>
|
||||
<?php $this->config->maxCount = 500; ?>
|
||||
<style>
|
||||
#taskTeamEditor button > i {color: #5e626d;}
|
||||
#taskTeamEditor .estimateBox span {background-color: #fff;}
|
||||
#taskTeamEditor .estimateBox input {background-color: #fff; border-right-width: 0px;}
|
||||
#taskTeamEditor input, #taskTeamEditor span, #taskTeamEditor .chosen-container > a {border-color: #eee;}
|
||||
#taskTeamEditor td.sort-handler {padding-bottom: 11px;}
|
||||
</style>
|
||||
<?php if($app->rawMethod != 'create'):?>
|
||||
<style>
|
||||
#modalTeam .modal-dialog {width: 855px;}
|
||||
</style>
|
||||
<?php endif;?>
|
||||
<?php if($app->rawMethod == 'assignto'):?>
|
||||
<style>
|
||||
#taskTeamEditor td.sort-handler {width: 70px !important;}
|
||||
</style>
|
||||
<?php endif;?>
|
||||
<?php $hiddenArrow = (empty($task->mode) or $task->mode == 'linear') ? '' : 'hidden';?>
|
||||
<?php $i = 1;?>
|
||||
<?php if(!empty($task->team)):?>
|
||||
<?php foreach($task->team as $member):?>
|
||||
<?php
|
||||
$memberDisabled = false;
|
||||
$sortDisabled = false;
|
||||
$memberStatus = $member->status;
|
||||
if($memberStatus == 'done') $memberDisabled = true;
|
||||
if($memberStatus != 'wait' and $task->mode == 'linear') $sortDisabled = true;
|
||||
if($memberStatus == 'done' and $task->mode == 'multi') $sortDisabled = true;
|
||||
if(strpos('|closed|cancel|pause|', $task->status) !== false and $app->rawMethod != 'activate')
|
||||
{
|
||||
$memberStatus = $task->status;
|
||||
$memberDisabled = true;
|
||||
$sortDisabled = true;
|
||||
}
|
||||
#taskTeamEditor button>i {
|
||||
color: #5e626d;
|
||||
}
|
||||
|
||||
$hourDisabled = $memberDisabled;
|
||||
if($task->mode == 'multi' and $app->rawMethod == 'activate') $hourDisabled = false;
|
||||
?>
|
||||
<tr class='member member-<?php echo $memberStatus;?>' data-estimate='<?php echo (float)$member->estimate?>' data-consumed='<?php echo (float)$member->consumed?>' data-left='<?php echo (float)$member->left?>'>
|
||||
<td>
|
||||
<span class="team-number"><?php echo $i;?></span>
|
||||
<i class="icon icon-angle-down <?php echo $hiddenArrow;?>"></i>
|
||||
</td>
|
||||
<td class='w-250px'>
|
||||
<?php echo html::select("team[]", $members, $member->account, "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'" . ($memberDisabled ? ' disabled' : ''))?>
|
||||
<?php echo html::hidden("teamSource[]", $member->account);?>
|
||||
<?php if($memberDisabled) echo html::hidden("team[]", $member->account);?>
|
||||
</td>
|
||||
<td class='hourBox'>
|
||||
<?php if($app->rawMethod == 'create'):?>
|
||||
<div class='input-group estimateBox'>
|
||||
<?php echo html::input("teamEstimate[]", (float)$member->estimate, "class='form-control text-center' placeholder='{$lang->task->estimateAB}'") ?>
|
||||
<span class='input-group-addon'><?php echo 'h';?></span>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamEstimate[]", (float)$member->estimate, "class='form-control text-center' placeholder='{$lang->task->estimate}'" . ($hourDisabled ? ' readonly' : ''))?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamConsumed[]", (float)$member->consumed, "class='form-control text-center' readonly placeholder='{$lang->task->consumed}'")?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamLeft[]", (float)$member->left, "class='form-control text-center' placeholder='{$lang->task->left}'" . ($hourDisabled ? ' readonly' : ''))?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class='w-100px sort-handler'>
|
||||
<button type="button" <?php echo $memberDisabled ? 'disabled' : '';?> class="btn btn-link btn-sm btn-icon btn-add"><i class="icon icon-plus"></i></button>
|
||||
<button type="button" <?php echo $memberDisabled ? 'disabled' : '';?> class="btn btn-link btn-sm btn-icon btn-delete"><i class="icon icon-trash"></i></button>
|
||||
<?php if(!empty($task->mode) and $task->mode == 'linear'):?>
|
||||
<button type="button" <?php echo $sortDisabled ? 'disabled' : '';?> class='btn btn-link btn-sm btn-icon btn-move'><i class='icon-move'></i></button>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $i ++;?>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
#taskTeamEditor .estimateBox span {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#taskTeamEditor .estimateBox input {
|
||||
background-color: #fff;
|
||||
border-right-width: 0px;
|
||||
}
|
||||
|
||||
#taskTeamEditor input,
|
||||
#taskTeamEditor span,
|
||||
#taskTeamEditor .chosen-container>a {
|
||||
border-color: #eee;
|
||||
}
|
||||
|
||||
#taskTeamEditor td.sort-handler {
|
||||
padding-bottom: 11px;
|
||||
}
|
||||
</style>
|
||||
<?php if ($app->rawMethod != 'create') : ?>
|
||||
<style>
|
||||
#modalTeam .modal-dialog {
|
||||
width: 855px;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
<?php if ($app->rawMethod == 'assignto') : ?>
|
||||
<style>
|
||||
#taskTeamEditor td.sort-handler {
|
||||
width: 70px !important;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
<?php $hiddenArrow = (empty($task->mode) or $task->mode == 'linear') ? '' : 'hidden'; ?>
|
||||
<?php $i = 1; ?>
|
||||
<?php if (!empty($task->team)) : ?>
|
||||
<?php foreach ($task->team as $member) : ?>
|
||||
<?php
|
||||
$memberDisabled = false;
|
||||
$sortDisabled = false;
|
||||
$memberStatus = $member->status;
|
||||
if ($memberStatus == 'done') $memberDisabled = true;
|
||||
if ($memberStatus != 'wait' and $task->mode == 'linear') $sortDisabled = true;
|
||||
if ($memberStatus == 'done' and $task->mode == 'multi') $sortDisabled = true;
|
||||
if (strpos('|closed|cancel|pause|', $task->status) !== false and $app->rawMethod != 'activate') {
|
||||
$memberStatus = $task->status;
|
||||
$memberDisabled = true;
|
||||
$sortDisabled = true;
|
||||
}
|
||||
|
||||
$hourDisabled = $memberDisabled;
|
||||
if ($task->mode == 'multi' and $app->rawMethod == 'activate') $hourDisabled = false;
|
||||
?>
|
||||
<tr class='member member-<?php echo $memberStatus; ?>' data-estimate='<?php echo (float)$member->estimate ?>' data-consumed='<?php echo (float)$member->consumed ?>' data-left='<?php echo (float)$member->left ?>'>
|
||||
<td>
|
||||
<span class="team-number"><?php echo $i; ?></span>
|
||||
<i class="icon icon-angle-down <?php echo $hiddenArrow; ?>"></i>
|
||||
</td>
|
||||
<td class='w-250px'>
|
||||
<?php echo html::select("team[]", $members, $member->account, "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'" . ($memberDisabled ? ' disabled' : '')) ?>
|
||||
<?php echo html::hidden("teamSource[]", $member->account); ?>
|
||||
<?php if ($memberDisabled) echo html::hidden("team[]", $member->account); ?>
|
||||
</td>
|
||||
<td class='hourBox'>
|
||||
<?php if ($app->rawMethod == 'create') : ?>
|
||||
<div class='input-group estimateBox'>
|
||||
<?php echo html::input("teamEstimate[]", (float)$member->estimate, "class='form-control text-center' placeholder='{$lang->task->estimateAB}'") ?>
|
||||
<span class='input-group-addon'><?php echo 'h'; ?></span>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamEstimate[]", (float)$member->estimate, "class='form-control text-center' placeholder='{$lang->task->estimate}'" . ($hourDisabled ? ' readonly' : '')) ?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamConsumed[]", (float)$member->consumed, "class='form-control text-center' readonly placeholder='{$lang->task->consumed}'") ?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamLeft[]", (float)$member->left, "class='form-control text-center' placeholder='{$lang->task->left}'" . ($hourDisabled ? ' readonly' : '')) ?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class='w-100px sort-handler'>
|
||||
<button type="button" <?php echo $memberDisabled ? 'disabled' : ''; ?> class="btn btn-link btn-sm btn-icon btn-add"><i class="icon icon-plus"></i></button>
|
||||
<button type="button" <?php echo $memberDisabled ? 'disabled' : ''; ?> class="btn btn-link btn-sm btn-icon btn-delete"><i class="icon icon-trash"></i></button>
|
||||
<?php if (!empty($task->mode) and $task->mode == 'linear') : ?>
|
||||
<button type="button" <?php echo $sortDisabled ? 'disabled' : ''; ?> class='btn btn-link btn-sm btn-icon btn-move'><i class='icon-move'></i></button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $i++; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<tr class='template teamTemplate member member-wait'>
|
||||
<td>
|
||||
<span class="team-number"><?php echo $i;?></span>
|
||||
<i class="icon icon-angle-down <?php echo $hiddenArrow;?>"></i>
|
||||
</td>
|
||||
<td class='w-240px'>
|
||||
<?php echo html::select("team[]", $members, '', "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'")?>
|
||||
<?php echo html::hidden("teamSource[]", '');?>
|
||||
</td>
|
||||
<td class='hourBox'>
|
||||
<?php if(empty($task->team) or $app->rawMethod == 'create'):?>
|
||||
<div class='input-group estimateBox'>
|
||||
<?php echo html::input("teamEstimate[]", '', "class='form-control text-center' placeholder='{$lang->task->estimateAB}'") ?>
|
||||
<span class='input-group-addon'><?php echo 'h';?></span>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamEstimate[]", '', "class='form-control text-center' placeholder='{$lang->task->estimate}'")?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamConsumed[]", 0, "class='form-control text-center' readonly placeholder='{$lang->task->consumed}'")?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamLeft[]", '', "class='form-control text-center' placeholder='{$lang->task->left}'")?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class='w-100px sort-handler'>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon btn-add"><i class="icon icon-plus"></i></button>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon btn-delete"><i class="icon icon-trash"></i></button>
|
||||
<?php if(empty($task->mode) or $task->mode == 'linear'):?>
|
||||
<button type='button' class='btn btn-link btn-sm btn-icon btn-move'><i class='icon-move'></i></button>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="team-number"><?php echo $i; ?></span>
|
||||
<i class="icon icon-angle-down <?php echo $hiddenArrow; ?>"></i>
|
||||
</td>
|
||||
<td class='w-240px'>
|
||||
<?php echo html::select("team[]", $members, '', "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'") ?>
|
||||
<?php echo html::hidden("teamSource[]", ''); ?>
|
||||
</td>
|
||||
<td class='hourBox'>
|
||||
<?php if (empty($task->team) or $app->rawMethod == 'create') : ?>
|
||||
<div class='input-group estimateBox'>
|
||||
<?php echo html::input("teamEstimate[]", '', "class='form-control text-center' placeholder='{$lang->task->estimateAB}'") ?>
|
||||
<span class='input-group-addon'><?php echo 'h'; ?></span>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamEstimate[]", '', "class='form-control text-center' placeholder='{$lang->task->estimate}'") ?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamConsumed[]", 0, "class='form-control text-center' readonly placeholder='{$lang->task->consumed}'") ?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("teamLeft[]", '', "class='form-control text-center' placeholder='{$lang->task->left}'") ?>
|
||||
<label class="input-control-icon-right">h</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class='w-100px sort-handler'>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon btn-add"><i class="icon icon-plus"></i></button>
|
||||
<button type="button" class="btn btn-link btn-sm btn-icon btn-delete"><i class="icon icon-trash"></i></button>
|
||||
<?php if (empty($task->mode) or $task->mode == 'linear') : ?>
|
||||
<button type='button' class='btn btn-link btn-sm btn-icon btn-move'><i class='icon-move'></i></button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $newRowCount = (!empty($task->team) and count($task->team) < 6) ? 6 - count($task->team) : 1;?>
|
||||
<?php if(isset($task->status) and $task->status != 'wait' and $task->status != 'doing') $newRowCount = 0;?>
|
||||
<?php js::set('newRowCount', $newRowCount);?>
|
||||
<?php if(!empty($task->mode) and $task->mode == 'linear') js::set('sortSelector', 'tr.member-wait');?>
|
||||
<?php js::set('teamMemberError', $lang->task->error->teamMember);?>
|
||||
<?php if(isset($task->status)):?>
|
||||
<?php js::set('taskStatus', $task->status);?>
|
||||
<?php if($newRowCount == 0 and $app->rawMethod == 'edit' and $task->mode == 'linear'):?>
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<div class='alert alert-info'><?php printf($lang->task->noticeManageTeam, zget($lang->task->statusList, $task->status));?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
<?php $newRowCount = (!empty($task->team) and count($task->team) < 6) ? 6 - count($task->team) : 1; ?>
|
||||
<?php if (isset($task->status) and $task->status != 'wait' and $task->status != 'doing') $newRowCount = 0; ?>
|
||||
<?php js::set('newRowCount', $newRowCount); ?>
|
||||
<?php if (!empty($task->mode) and $task->mode == 'linear') js::set('sortSelector', 'tr.member-wait'); ?>
|
||||
<?php js::set('teamMemberError', $lang->task->error->teamMember); ?>
|
||||
<?php if (isset($task->status)) : ?>
|
||||
<?php js::set('taskStatus', $task->status); ?>
|
||||
<?php if ($newRowCount == 0 and $app->rawMethod == 'edit' and $task->mode == 'linear') : ?>
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<div class='alert alert-info'><?php printf($lang->task->noticeManageTeam, zget($lang->task->statusList, $task->status)); ?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<script>
|
||||
$(document).ready(function()
|
||||
{
|
||||
<?php if(!empty($task->mode) and $app->rawMethod == 'create'):?>
|
||||
$('#multipleBox').attr('checked', 'checked');
|
||||
showTeamMenu();
|
||||
<?php endif;?>
|
||||
$(document).ready(function() {
|
||||
<?php if (!empty($task->mode) and $app->rawMethod == 'create') : ?>
|
||||
$('#multipleBox').attr('checked', 'checked');
|
||||
showTeamMenu();
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($task->mode) and $task->mode == 'multi'):?>
|
||||
$('tr.teamTemplate').closest('tbody.sortable').sortable('destroy');
|
||||
<?php else:?>
|
||||
var options = {
|
||||
selector: '.icon-move',
|
||||
dragCssClass: 'drag-row',
|
||||
reverse: true,
|
||||
finish: setLineNumber
|
||||
}
|
||||
<?php if (isset($task->mode) and $task->mode == 'multi') : ?>
|
||||
$('tr.teamTemplate').closest('tbody.sortable').sortable('destroy');
|
||||
<?php else : ?>
|
||||
var options = {
|
||||
selector: '.icon-move',
|
||||
dragCssClass: 'drag-row',
|
||||
reverse: true,
|
||||
finish: setLineNumber
|
||||
}
|
||||
|
||||
$('#taskTeamEditor tbody.sortable').sortable(options);
|
||||
<?php endif;?>
|
||||
$('#taskTeamEditor tbody.sortable').sortable(options);
|
||||
<?php endif; ?>
|
||||
|
||||
/* Init task team manage dialog */
|
||||
var $taskTeamEditor = $('tr.teamTemplate').closest('table').batchActionForm(
|
||||
{
|
||||
idStart: 0,
|
||||
idEnd: newRowCount - 1,
|
||||
chosen: true,
|
||||
datetimepicker: false,
|
||||
colorPicker: false,
|
||||
});
|
||||
var taskTeamEditor = $taskTeamEditor.data('zui.batchActionForm');
|
||||
/* Init task team manage dialog */
|
||||
var $taskTeamEditor = $('tr.teamTemplate').closest('table').batchActionForm({
|
||||
idStart: 0,
|
||||
idEnd: newRowCount - 1,
|
||||
chosen: true,
|
||||
datetimepicker: false,
|
||||
colorPicker: false,
|
||||
});
|
||||
var taskTeamEditor = $taskTeamEditor.data('zui.batchActionForm');
|
||||
|
||||
var adjustButtons = function()
|
||||
{
|
||||
var $deleteBtn = $taskTeamEditor.find('.btn-delete');
|
||||
if($deleteBtn.length == 1)
|
||||
{
|
||||
$deleteBtn.addClass('disabled').attr('disabled', 'disabled');
|
||||
}
|
||||
else if(config.currentMethod == 'create')
|
||||
{
|
||||
$deleteBtn.removeClass('disabled').removeAttr('disabled');
|
||||
}
|
||||
var adjustButtons = function() {
|
||||
var $deleteBtn = $taskTeamEditor.find('.btn-delete');
|
||||
if ($deleteBtn.length == 1) {
|
||||
$deleteBtn.addClass('disabled').attr('disabled', 'disabled');
|
||||
} else if (config.currentMethod == 'create') {
|
||||
$deleteBtn.removeClass('disabled').removeAttr('disabled');
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
var disableMembers = function()
|
||||
{
|
||||
var mode = $('[name="mode"]').length > 0 ? $('[name="mode"]').val() : '<?php echo (!empty($task->mode) ? $task->mode : '')?>';
|
||||
if(mode == 'multi')
|
||||
{
|
||||
var members = [];
|
||||
var $teams = $taskTeamEditor.find('select#team');
|
||||
for(i = 0; i < $teams.length; i++)
|
||||
{
|
||||
var value = $teams.eq(i).val();
|
||||
if($.inArray(value, members) >= 0)
|
||||
{
|
||||
$teams.eq(i).closest('tr').addClass('hidden');
|
||||
continue;
|
||||
var disableMembers = function() {
|
||||
var mode = $('[name="mode"]').length > 0 ? $('[name="mode"]').val() : '<?php echo (!empty($task->mode) ? $task->mode : '') ?>';
|
||||
if (mode == 'multi') {
|
||||
var members = [];
|
||||
var $teams = $taskTeamEditor.find('select#team');
|
||||
for (i = 0; i < $teams.length; i++) {
|
||||
var value = $teams.eq(i).val();
|
||||
if ($.inArray(value, members) >= 0) {
|
||||
$teams.eq(i).closest('tr').addClass('hidden');
|
||||
continue;
|
||||
}
|
||||
if (value != '') members.push(value);
|
||||
}
|
||||
if(value != '') members.push(value);
|
||||
}
|
||||
|
||||
$teams.each(function()
|
||||
{
|
||||
var $this = $(this);
|
||||
$teams.each(function() {
|
||||
var $this = $(this);
|
||||
var value = $this.val();
|
||||
$this.find('option:disabled').removeAttr('disabled');
|
||||
$.each(members, function(i, account) {
|
||||
if (account == value) return;
|
||||
$this.find('option[value=' + account + ']').attr('disabled', 'disabled');
|
||||
})
|
||||
$this.trigger("chosen:updated");
|
||||
});
|
||||
$taskTeamEditor.find('tr.hidden').remove();
|
||||
}
|
||||
}
|
||||
|
||||
var checkRemove = function(removeIndex) {
|
||||
var $teams = $taskTeamEditor.find('select#team');
|
||||
var totalLeft = 0;
|
||||
var memberCount = 0;
|
||||
for (i = 0; i < $teams.length; i++) {
|
||||
var $this = $teams.eq(i);
|
||||
var value = $this.val();
|
||||
$this.find('option:disabled').removeAttr('disabled');
|
||||
$.each(members, function(i, account)
|
||||
{
|
||||
if(account == value) return;
|
||||
$this.find('option[value=' + account + ']').attr('disabled', 'disabled');
|
||||
})
|
||||
$this.trigger("chosen:updated");
|
||||
});
|
||||
$taskTeamEditor.find('tr.hidden').remove();
|
||||
}
|
||||
}
|
||||
if (value == '') continue;
|
||||
|
||||
var checkRemove = function(removeIndex)
|
||||
{
|
||||
var $teams = $taskTeamEditor.find('select#team');
|
||||
var totalLeft = 0;
|
||||
var memberCount = 0;
|
||||
for(i = 0; i < $teams.length; i++)
|
||||
{
|
||||
var $this = $teams.eq(i);
|
||||
var value = $this.val();
|
||||
if(value == '') continue;
|
||||
var $tr = $this.closest('tr');
|
||||
if ($tr.index() == removeIndex) continue;
|
||||
|
||||
var $tr = $this.closest('tr');
|
||||
if($tr.index() == removeIndex) continue;
|
||||
memberCount++;
|
||||
|
||||
memberCount++;
|
||||
|
||||
var $teamLeft = $tr.find('[name^=teamLeft]');
|
||||
if($teamLeft.length > 0)
|
||||
{
|
||||
left = parseFloat($teamLeft.val());
|
||||
if(!isNaN(left)) totalLeft += left;
|
||||
var $teamLeft = $tr.find('[name^=teamLeft]');
|
||||
if ($teamLeft.length > 0) {
|
||||
left = parseFloat($teamLeft.val());
|
||||
if (!isNaN(left)) totalLeft += left;
|
||||
}
|
||||
}
|
||||
|
||||
if (memberCount < 2) {
|
||||
bootbox.alert(teamMemberError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($taskTeamEditor.find('td > .btn-delete:enabled').length == 1) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(memberCount < 2)
|
||||
{
|
||||
bootbox.alert(teamMemberError);
|
||||
return false;
|
||||
}
|
||||
$taskTeamEditor.on('click', '.btn-add', function() {
|
||||
var $newRow = taskTeamEditor.createRow(null, $(this).closest('tr'));
|
||||
$newRow.addClass('highlight');
|
||||
setTimeout(function() {
|
||||
$newRow.removeClass('highlight');
|
||||
}, 1600);
|
||||
|
||||
if($taskTeamEditor.find('td > .btn-delete:enabled').length == 1) return false;
|
||||
var taskMode = $('[name="mode"]').val();
|
||||
if (taskMode == 'multi') $('#taskTeamEditor tr.member .icon-angle-down').addClass('hidden');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$taskTeamEditor.on('click', '.btn-add', function()
|
||||
{
|
||||
var $newRow = taskTeamEditor.createRow(null, $(this).closest('tr'));
|
||||
$newRow.addClass('highlight');
|
||||
setTimeout(function()
|
||||
{
|
||||
$newRow.removeClass('highlight');
|
||||
}, 1600);
|
||||
|
||||
var taskMode = $('[name="mode"]').val();
|
||||
if(taskMode == 'multi') $('#taskTeamEditor tr.member .icon-angle-down').addClass('hidden');
|
||||
|
||||
disableMembers();
|
||||
adjustButtons();
|
||||
setLineNumber();
|
||||
}).on('click', '.btn-delete', function()
|
||||
{
|
||||
if($(this).hasClass('disabledDeleted')) return;
|
||||
|
||||
var $row = $(this).closest('tr');
|
||||
<?php if(!empty($task->team)):?>
|
||||
if(!checkRemove($row.index())) return;
|
||||
<?php endif;?>
|
||||
|
||||
$taskTeamEditor.find('.btn-delete').addClass('disabledDeleted');
|
||||
$row.addClass('highlight').fadeOut(700, function()
|
||||
{
|
||||
$row.remove();
|
||||
$taskTeamEditor.find('.btn-delete').removeClass('disabledDeleted');
|
||||
disableMembers();
|
||||
adjustButtons();
|
||||
setLineNumber();
|
||||
}).on('click', '.btn-delete', function() {
|
||||
if ($(this).hasClass('disabledDeleted')) return;
|
||||
|
||||
var $row = $(this).closest('tr');
|
||||
<?php if (!empty($task->team)) : ?>
|
||||
if (!checkRemove($row.index())) return;
|
||||
<?php endif; ?>
|
||||
|
||||
$taskTeamEditor.find('.btn-delete').addClass('disabledDeleted');
|
||||
$row.addClass('highlight').fadeOut(700, function() {
|
||||
$row.remove();
|
||||
$taskTeamEditor.find('.btn-delete').removeClass('disabledDeleted');
|
||||
disableMembers();
|
||||
adjustButtons();
|
||||
setLineNumber();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
adjustButtons();
|
||||
disableMembers();
|
||||
setLineNumber();
|
||||
|
||||
$taskTeamEditor.on('change', 'select#team', function()
|
||||
{
|
||||
$(this).closest('tr').find('input[id^=teamEstimate]').closest('.input-group').toggleClass('required', $(this).val() != '')
|
||||
|
||||
adjustButtons();
|
||||
disableMembers();
|
||||
setLineNumber();
|
||||
|
||||
var $teamSource = $(this).siblings('[name^=teamSource]');
|
||||
if($teamSource.val() == '') return;
|
||||
$taskTeamEditor.on('change', 'select#team', function() {
|
||||
$(this).closest('tr').find('input[id^=teamEstimate]').closest('.input-group').toggleClass('required', $(this).val() != '')
|
||||
|
||||
var $tr = $(this).closest('tr');
|
||||
var consumed = 0;
|
||||
var estimate = $tr.attr('data-left');;
|
||||
if($(this).val() == $teamSource.val())
|
||||
{
|
||||
consumed = $tr.attr('data-consumed');
|
||||
estimate = $tr.attr('data-estimate');
|
||||
}
|
||||
$tr.find('[name^=teamConsumed]').val(consumed);
|
||||
$tr.find('[name^=teamEstimate]').val(estimate);
|
||||
});
|
||||
$taskTeamEditor.find('select#team:enabled').each(function()
|
||||
{
|
||||
$(this).closest('tr').find('input[id^=teamEstimate]').closest('.input-group').toggleClass('required', $(this).val() != '')
|
||||
});
|
||||
|
||||
$('[name="mode"]').change(function()
|
||||
{
|
||||
if($(this).val() == 'multi')
|
||||
{
|
||||
disableMembers();
|
||||
$('#taskTeamEditor tr.member .icon-angle-down').addClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#taskTeamEditor tr.member .icon-angle-down').removeClass('hidden');
|
||||
$taskTeamEditor.find('select#team').each(function()
|
||||
{
|
||||
$(this).find('option:disabled').removeAttr('disabled').trigger("chosen:updated");
|
||||
})
|
||||
}
|
||||
if($('#teamMember').val() != '' && page != 'edit') $taskTeamEditor.find('tfoot .btn').click();
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Set line number.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setLineNumber()
|
||||
{
|
||||
var lineNumber = 1;
|
||||
$('.team-number').each(function()
|
||||
{
|
||||
$(this).text(lineNumber);
|
||||
lineNumber ++;
|
||||
var $teamSource = $(this).siblings('[name^=teamSource]');
|
||||
if ($teamSource.val() == '') return;
|
||||
|
||||
var $tr = $(this).closest('tr');
|
||||
var consumed = 0;
|
||||
var estimate = $tr.attr('data-left');;
|
||||
if ($(this).val() == $teamSource.val()) {
|
||||
consumed = $tr.attr('data-consumed');
|
||||
estimate = $tr.attr('data-estimate');
|
||||
}
|
||||
$tr.find('[name^=teamConsumed]').val(consumed);
|
||||
$tr.find('[name^=teamEstimate]').val(estimate);
|
||||
});
|
||||
$taskTeamEditor.find('select#team:enabled').each(function() {
|
||||
$(this).closest('tr').find('input[id^=teamEstimate]').closest('.input-group').toggleClass('required', $(this).val() != '')
|
||||
});
|
||||
|
||||
$('[name="mode"]').change(function() {
|
||||
if ($(this).val() == 'multi') {
|
||||
disableMembers();
|
||||
$('#taskTeamEditor tr.member .icon-angle-down').addClass('hidden');
|
||||
} else {
|
||||
$('#taskTeamEditor tr.member .icon-angle-down').removeClass('hidden');
|
||||
$taskTeamEditor.find('select#team').each(function() {
|
||||
$(this).find('option:disabled').removeAttr('disabled').trigger("chosen:updated");
|
||||
})
|
||||
}
|
||||
if ($('#teamMember').val() != '' && page != 'edit') $taskTeamEditor.find('tfoot .btn').click();
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
/**
|
||||
* Set line number.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function setLineNumber() {
|
||||
var lineNumber = 1;
|
||||
$('.team-number').each(function() {
|
||||
$(this).text(lineNumber);
|
||||
lineNumber++;
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
<?php $this->config->maxCount = $oldMaxCount;?>
|
||||
<?php $this->config->maxCount = $oldMaxCount; ?>
|
||||
|
||||
Reference in New Issue
Block a user