Делалось Deva V. для собственных нужд в Конфигураторе Yougile https://yougile.com/
Видео о работе с Конфигуратором - https://www.youtube.com/watch?v=UOKxyTRv0Bo
Быстрое открытие окна Конфигуратора - Ctrl+Shift+~ (тильда)
Пользовательская информация на досках и в задачах не затрагивается.
> Применяя идеи, содержащиеся на этой странице, вы сами несете полную личную ответственность за полученный результат.
Модификация скрипта из стандартного примера
Приклеиваем нужный стикер при попадании задачи в определенную колонку
/**
* При перемещении задачи в колонку, присваивать стикер "сегодня",
* при перемещении задачи из колонки, убирать стикер.
* Замените на своё: ID колонки, Срочность и сегодня
*/
var column = Items.get('--- ID колонки ---'); // нужная колонка, потянуть ее в это место в редакторе из "Навигатора по объектам"
var priority = Stickers.get('Срочность'); // набор стикеров
Items.onMove = function Sticker3gvozd (object, from, to) { // при перемещении задачи...
if (to.id === column.id) { // ...если в нужную колонку
if (object.type === 'Task') { // если объект - задача
Stickers.pin(object, priority, 'сегодня'); // присвоить стикер
}
}
else {
if (from.id === column.id) { // ...иначе (т.е. из заданной колонки)
if (object.type === 'Task') { // если объект - задача
Stickers.unpin(object, priority); // снять стикер из выбранного набора стикеров
}
}
return true; // и затем переместить задачу (не возвращать ее на место)
}
};
Модификация скрипта из стандартного примера
Приклеиваем нужный стикер при добавлении задачи в определенную колонку
/**
* При добавлении задачи в нужную колонку, присваивать стикер "сегодня"
* Замените на своё: ID колонки, Срочность и сегодня
*/
var column = Items.get('--- ID колонки ---'); // нужная колонка, потянуть ее в это место в редакторе из "Навигатора по объектам"
var priority = Stickers.get('Срочность'); // набор стикеров
// подсказка по object.up().id: object - в данном случае это "задача", up (выше) задачи - это "колонка" и берём id колонки
Items.onAdd = function (object) { // при добавлении новой задачи...
if (object.type === 'Task' && column.id === object.up().id) { // если объект - новая задача в нужной колонке
Stickers.pin(object, priority, 'сегодня'); // ...присвоить стикер
}
return true; // добавить задачу (не отменять процедуру создания задачи)
};
Модификация скрипта из стандартного примера
Задаем нужный стикер во время постановки задачи
/**
* Если при создании задачи сначала написать особый символ, то она сразу получит определенный стикер
*/
var stickerset = Stickers.get('--- стикер ----'); // выбираем набор стикеров
Items.onAdd = function (object) { // если добавляем новую...
if (object.type === 'Task') { // ...задачу
var stickerstate = 'none'; // начальное состояние стикера
var firstletter = object.name[0];
if (firstletter === '!') { // и если имя задачи начинается с этого символа и пробела...
stickerstate = 'важно'; // ...будем клеить этот стикер
object.name = object.name.slice(1).trim(); // ...вырезаем первый символ и пробел(ы) (если есть) в тексте задачи
}
Stickers.pin(object, stickerset, stickerstate); // приклеиваем стикер
}
};
Модификация скрипта из стандартного примера
заготовка на будущее
/**
* Добавляет панель (контейнер) с кнопкой и текстом в задачу.
*/
var t = Items.get('--- ID задачи ---');
var pan = UI.panel();
t.ui.add(pan);
pan.style = {
background: '#000',
color: '#1f1'
};
pan.add(UI.button('Нажмите!')); // текст кнопки
pan.onClick = function () {
alert('I was clicked!');
};
var txt = UI.text('... какой-то текст ...');
pan.add(txt); // добавляет текст внутрь панели
// pan.clear(); // убирает панель и очищает ее стили
// t.ui.clear(); // второй способ очистить то, что мы добавили в задачу
Модификация скрипта из стандартного примера
заготовка на будущее
/**
* Добавляет текст внутрь задачи.
*/
var t = Items.get('--- ID задачи ---');
var txt = UI.text('... какой-то текст ...');
t.ui.add(txt);
Создает XLXS файл, содержащий: названия задач, описание задач, подзадачи, сообщения чата
/**
* Автоматическое создание резервной копии (через выбранный промежуток времени)
* всех задач, их описаний, подзадач и всех сообщений из всех проектов компании.
* Скрипт должен быть всегда включен!
*/
function BackupRegulary() {
const table = [];
table.push(['Дата', 'Задача', 'Где находится', 'Описание']);
Current.company.list().forEach(project =>
project.list().forEach(board =>
board.list().forEach(column =>
column.list().forEach(task => {
// получаем сообщения чата этой задачи
var TaskChatMessages = Chat.listMessages(task);
const ChatMessages = Array.from(TaskChatMessages, ({text}) => text);
// получаем описание этой задачи
var TaskDescription = Chat.getDescription(task);
table.push([App.formatDateTime(task.timestamp), task.name, task.path, TaskDescription], ChatMessages); // нужны [] иначе будет побуквенный вывод
// получаем подзадачи этой задачи
var TaskSubtasks = Chat.getSubtasks(task);
for(let elem of TaskSubtasks) {
//console.log(elem.title); // выводит title списка подзадач
table.push([elem.title]);
// console.log(elem.items); // для откладки - выводит массив items подзадач и из них берем title подзадачи
for (let item of elem.items) {
//console.log(item.title) // выводит title каждой подзадачи
table.push([item.title]);
}
}
}) // конец цикла каждой задачи
)
)
);
App.saveXlsx('Yougile backup ' + App.time() + '.xlsx', table);
} // конец BackupRegulary
setInterval(BackupRegulary, 604800000); // периодический запуск: 1 неделя = 604800000 миллисекунд, 1 сутки = 86400000 миллисекунд
Создает XLXS файл, содержащий: названия задач, описание задач, подзадачи, сообщения чата
/**
* Ручное создание резервной копии всех задач, их описаний, подзадач и всех сообщений из всех проектов компании.
* При запуске срипта под панелью стикеров появится кнопка "Скачать резервную копию".
* При нажатии на кнопку через несколько секунд будет предложено скачать файл XLSX - просто нажмите Ок
* (не надо дописывать расширение файла)
* Скрипт может быть выключен и запускаться вручную из Конфигуратора
*/
const table = [];
table.push(['Дата', 'Задача', 'Где находится', 'Описание']);
Current.company.list().forEach(project =>
project.list().forEach(board =>
board.list().forEach(column =>
column.list().forEach(task => {
// получаем сообщения чата этой задачи
var TaskChatMessages = Chat.listMessages(task);
const ChatMessages = Array.from(TaskChatMessages, ({text}) => text);
// получаем описание этой задачи
var TaskDescription = Chat.getDescription(task);
table.push([App.formatDateTime(task.timestamp), task.name, task.path, TaskDescription], ChatMessages); // нужны [] иначе будет побуквенный вывод
// получаем подзадачи этой задачи
var TaskSubtasks = Chat.getSubtasks(task);
for(let elem of TaskSubtasks) {
//console.log(elem.title); // выводит title списка подзадач
table.push([elem.title]);
// console.log(elem.items); // для откладки - выводит массив items подзадач и из них берем title подзадачи
for (let item of elem.items) {
//console.log(item.title) // выводит title каждой подзадачи
table.push([item.title]);
}
}
}) // конец цикла каждой задачи
)
)
);
const btn = UI.button('Скачать резервную копию');
btn.onClick = function() {
App.saveXlsx('Yougile backup ' + App.time() + '.xlsx', table);
};
const drawBackupButton = function() {
if (Current.board) {
//Current.board.ui.clear(); // не очищать, потому что есть кнопки под стикерами
Current.board.ui.add(btn);
}
};
drawBackupButton();
Current.onBoardChange = drawBackupButton();
Добавьте эмоджи в названия колонок, в задачи и стикеры… Это придает свежести и помогает уникальности. В Windows это можно сделать через Сенсорную клавиатуру (добавить панель на Панель задач).
Модификация скрипта из стандартного примера
Создаем цветную кнопку на панели стикеров - например, для мотивации. Она сама по себе может быть постоянным ярким напоминанием. А при нажатии появится сообщение/напоминание, которое через несколько секунд исчезнет.
/**
* Добавляет кнопку в панель стикеров на доски.
* При нажатии кнопки вверху появляется сообщение.
* Для создания нескольких кнопок повторяем весь код и меняем в нём trigger1 на trigger2 и т.д.
*/
var trigger1 = UI.text('текст кнопки');
UI.components.stickerPanel.add(trigger1);
trigger1.style = {
fontSize: '14px',
lineHeight: '15px',
padding: '0px 10px 2px',
display: 'inline-block',
borderRadius: '10px',
cursor: 'pointer',
border: '1px solid #fff',
marginTop: '0px',
marginBottom: '4px',
marginLeft: '5px',
marginRight: '10px',
color: '#ad42ff',
background: 'rgba(255, 215, 0, 1)'
};
// всплывающее сообщение при нажатии на кнопку
trigger1.onClick = function () {
Notifier.success('....... текст доп.сообщения .......');
};
Модификация скрипта из стандартного примера
Покрасьте свои и стандартные стикеры в любой цвет.
/**
* Меняем цвет определеннного стикера.
* Замените на своё: Срочность, Важность, срочно и не важно
*/
// определяем наборы стикеров
var st1 = Stickers.get('Срочность');
var st2 = Stickers.get('Важность');
// новые цвета стикеров из этих наборов
st1.setData('срочно', {color: '#FF4040'});
st2.setData('не важно', {color: '#FF7A33'});
// при необходимости повторить код выше с другими значениями
Если нужно изменить только что-то одно - или фон, или текст - закомментируйте ненужный параметр, добавив впереди символы //
/**
* Замена цвета текста и фона у конкретной задачи
*/
var task = Items.get('--- ID задачи ---');
task.ui.style = {
color: '#f00',
background: 'NavajoWhite' // html-название цвета или цвет в формате #aaa
};
Если нужно изменить только что-то одно - или фон, или текст - закомментируем ненужный параметр, добавив впереди символы //
/**
* Замена цвета текста и фона у конкретной задачи при добавлении определенного стикера
*/
Stickers.onPin = function (task, sticker, value) {
// ниже прописываем системное значение стикера, которое можно узнать через Notifier.warn(value); если добавить строкой выше
if (value === 'ab1234567890') { // если добавляем особый стикер...
task.ui.add(UI.rawHtml(html)); // ...включить анимацию
task.ui.style = {
color: '#000', // темнее цвет
background: 'NavajoWhite' // новый фон
};
return true; // и приклеить стикер
}
};
Stickers.onUnpin = function (task, sticker) { // если снимаем этот стикер...
task.ui.clear(); // ...выключить анимацию
task.ui.style = {
color: '#2b3541', // ...восстановить цвет текста
background: '#fff' // ...цвет фона
};
return true; // и удалить стикер
};
Для привлечения внимания :)
добавляем html-код с анимированным эффектом
/**
* С помощью анимации на CSS3 добавим от 1 до 7 медленно вращающихся слов поверх текста задачи.
*/
var task = Items.get('--- ID задачи ---'); // задача, которую нужно визуально выделить
// для IE ниже используем кавычки '' вместо ``
var html = `
<!-- начало внедряемого html-кода -->
<style>
@-webkit-keyframes ckw {
0% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
}
@-moz-keyframes ckw {
0% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes cckw {
0% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
100% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
}
@-moz-keyframes cckw {
0% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
100% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
}
.gear {
float: none;
position: absolute;
text-align: center;
font-weight: bold;
-moz-animation-timing-function: linear;
-moz-animation-iteration-count: infinite;
-moz-animation-direction: normal;
-moz-animation-delay: 0;
-moz-animation-play-state: running;
-moz-animation-fill-mode: forwards;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal;
-webkit-animation-delay: 0;
-webkit-animation-play-state: running;
-webkit-animation-fill-mode: forwards;
}
#gear1 {
height: 15px;
left: 225px;
top: 90px;
width: 30px;
color: red;
-moz-animation-name: ckw;
-moz-animation-duration: 5s;
-webkit-animation-name: ckw;
-webkit-animation-duration: 5s;
}
#gear2 {
height: 30px;
left: 175px;
top: 75px;
width: 50px;
color: purple;
-moz-animation-name: cckw;
-moz-animation-duration: 8s;
-webkit-animation-name: cckw;
-webkit-animation-duration: 8s;
}
#gear3 {
height: 103px;
left: 10px;
top: 10px;
width: 103px;
-moz-animation-name: ckw;
-moz-animation-duration: 13.5s;
-webkit-animation-name: ckw;
-webkit-animation-duration: 13.5s;
}
#gear4 {
height: 144px;
left: 46px;
top: 20px;
width: 20px;
-moz-animation-name: cckw;
-moz-animation-duration: 20.2s;
-webkit-animation-name: cckw;
-webkit-animation-duration: 20.2s;
}
#gear5 {
height: 85px;
left: 30px;
top: 30px;
width: 85px;
-moz-animation-name: ckw;
-moz-animation-duration: 10s;
-webkit-animation-name: ckw;
-webkit-animation-duration: 10s;
}
#gear6 {
height: 125px;
left: 40px;
top: 40px;
width: 125px;
-moz-animation-name: cckw;
-moz-animation-duration: 16.84s;
-webkit-animation-name: cckw;
-webkit-animation-duration: 16.84s;
}
#gear7 {
height: 103px;
left: 50px;
top: 50px;
width: 103px;
-moz-animation-name: ckw;
-moz-animation-duration: 13.5s;
-webkit-animation-name: ckw;
-webkit-animation-duration: 13.5s;
}
</style>
<div class="container">
<!-- вращающиеся слова -->
<div class="gear" id="gear1">это</div>
<div class="gear" id="gear2">Делай</div>
<!-- если ниже раскомментировать строки, то добавится еще пять вращающихся элементов -->
<!--
<div class="gear" id="gear3">№3</div>
<div class="gear" id="gear4">№4</div>
<div class="gear" id="gear5">№5</div>
<div class="gear" id="gear6">№6</div>
<div class="gear" id="gear7">№7</div>
-->
</div>
<!-- конец внедряемого html-кода -->
`;
task.ui.add(UI.rawHtml(html)); // добавляем html-код внутрь задачи
Для привлечения внимания к задаче:
// анимация
var html = `
<!-- вращающиеся слова -->
<style>
@-webkit-keyframes rotationA {
0% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
}
@-moz-keyframes rotationA {
0% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes rotationB {
0% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
100% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
}
@-moz-keyframes rotationB {
0% {
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
100% {
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
}
.gears {
float: none;
position: absolute;
text-align: center;
font-weight: bold;
font-size: 14px;
-moz-animation-timing-function: linear;
-moz-animation-iteration-count: infinite;
-moz-animation-direction: normal;
-moz-animation-delay: 0;
-moz-animation-play-state: running;
-moz-animation-fill-mode: forwards;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal;
-webkit-animation-delay: 0;
-webkit-animation-play-state: running;
-webkit-animation-fill-mode: forwards;
}
#gear01 {
height: 15px;
right: 0px;
top: 35px;
width: 30px;
color: red;
-moz-animation-name: rotationA;
-moz-animation-duration: 5s;
-webkit-animation-name: rotationA;
-webkit-animation-duration: 5s;
}
#gear02 {
height: 30px;
left: 175px;
top: 75px;
width: 50px;
color: purple;
-moz-animation-name: rotationB;
-moz-animation-duration: 8s;
-webkit-animation-name: rotationB;
-webkit-animation-duration: 8s;
}
#gear03 {
height: 103px;
left: 10px;
top: 10px;
width: 103px;
-moz-animation-name: rotationA;
-moz-animation-duration: 13.5s;
-webkit-animation-name: rotationA;
-webkit-animation-duration: 13.5s;
}
#gear04 {
height: 144px;
left: 46px;
top: 20px;
width: 20px;
-moz-animation-name: rotationB;
-moz-animation-duration: 20.2s;
-webkit-animation-name: rotationB;
-webkit-animation-duration: 20.2s;
}
#gear05 {
height: 85px;
left: 30px;
top: 30px;
width: 85px;
-moz-animation-name: rotationA;
-moz-animation-duration: 10s;
-webkit-animation-name: rotationA;
-webkit-animation-duration: 10s;
}
#gear06 {
height: 125px;
left: 40px;
top: 40px;
width: 125px;
-moz-animation-name: rotationB;
-moz-animation-duration: 16.84s;
-webkit-animation-name: rotationB;
-webkit-animation-duration: 16.84s;
}
#gear07 {
height: 103px;
left: 50px;
top: 50px;
width: 103px;
-moz-animation-name: rotationA;
-moz-animation-duration: 13.5s;
-webkit-animation-name: rotationA;
-webkit-animation-duration: 13.5s;
}
</style>
<div class="gears" id="gear01">!!!</div>
<!--
<div class="gears" id="gear02">Б</div>
<div class="gears" id="gear03">В</div>
<div class="gears" id="gear04">Г</div>
<div class="gears" id="gear05">Д</div>
<div class="gears" id="gear06">Е</div>
<div class="gears" id="gear07">Ж</div>
-->
<!-- конец вращающиеся слова -->
`; // for IE use regular string with '' instead of ``
Stickers.onPin = function (task, sticker, value) {
// ниже прописываем системное значение стикера, которое можно узнать через Notifier.warn(value); если добавить строкой выше
if (value === 'ab1234567890') { // если добавляем особый стикер...
task.ui.add(UI.rawHtml(html)); // ...включить анимацию
return true; // и приклеить стикер
}
};
Stickers.onUnpin = function (task, sticker) { // если снимаем этот стикер...
task.ui.clear(); // ...выключить анимацию
return true; // и удалить стикер
};
Располагается под панелью стикеров
/**
* Создаем панель для самых важных истин, чтобы они были всегда перед глазами.
*/
const button1 = UI.button('кнопка 1');
button1.onClick = function() {
Notifier.warn('Миссия');
};
button1.style = {
marginLeft: '58px',
marginRight: '5px',
borderRadius: '10px',
border: '1px solid Orchid',
color: '#fff',
background: 'Indigo',
fontSize: '12px'
};
const button2 = UI.button('кнопка 2');
button2.onClick = function() {
Notifier.warn('Ценность');
};
button2.style = {
marginLeft: '5px',
marginRight: '5px',
borderRadius: '10px',
border: '1px solid Orchid',
color: '#fff',
background: 'Indigo',
fontSize: '12px'
};
const button3 = UI.button('кнопка 3');
button3.onClick = function() {
Notifier.warn('Цель');
};
button3.style = {
marginLeft: '5px',
marginRight: '5px',
borderRadius: '10px',
border: '1px solid Orchid',
color: '#fff',
background: 'Indigo',
fontSize: '12px'
};
const drawButton = function() {
if (Current.board) {
Current.board.ui.clear();
Current.board.ui.add(button1);
Current.board.ui.add(button2);
Current.board.ui.add(button3);
}
};
drawButton();
Current.onBoardChange = function() {
drawButton() // при смене доски восстановить кнопки
}
<!-- пульсирующий текст
<style>
.pulse{
position:relative;
display: block;
top:50%;
left:50%;
margin-left:-50px; /* компенсация ширины пульсара - половина его ширины */
margin-top:10px; /* отступ сверху */
padding-top: 5px; /* коррекция текста по высоте */
padding-bottom: 20px;
width:100px;
height:30px;
font-size:1em;
font-weight:bold;
color:#f00;
/* text-shadow:0 1px 0 #1f4c76; */
border:1px solid #FF5300;
border-radius:100%;
background:rgba(255, 145, 65, 0.4);
cursor:pointer;
-webkit-animation: pulse 1.5s infinite cubic-bezier(0.5, 1, 1, 1);
}
.pulse:hover{
-webkit-animation:none}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0px rgba(255, 108, 0, 0.5);
}
100% {
box-shadow: 0 0 0 15px rgba(255, 108, 0, 0);
}
}
</style>
<p class="pulse">Just do it!</p>
конец пульсирующего текста -->
<!-- элемент летает по кругу
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box; /* но ломает фон доски */
}
#world {
width: 100%;
height: 100%;
perspective: 1000px;
perspective-origin: 50% 40%;
position: relative;
}
#mooseRotator {
position: absolute;
left: 50%;
top: 50%;
animation: mooseRotation 4s infinite linear;
}
#mooseTranslator {
transform: translateX(100px);
}
#moose {
position: absolute;
left: 0;
top: 0;
cursor: pointer;
}
#mooseBody {
animation: mooseBounce .4s infinite;
}
#mooseFront {
position: absolute;
top: 0px;
left: 0;
}
#mooseFront {
transform: translateZ(8px);
}
.mooseFrontItem {
position: absolute;
background-color: black;
}
#mooseFront_a {
width: 10px;
height: 10px;
left: -24px;
top: -48px;
}
@keyframes mooseRotation {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
</style>
<div id="world">
<div id="mooseRotator">
<div id="mooseTranslator">
<div id="moose">
<div id="mooseBody">
<div id="mooseFront">
<div id="mooseFront_a" class="mooseFrontItem"></div>
</div>
</div>
</div>
</div>
</div>
</div>
конец летающего элемента -->
// добавить картинку к задаче
var img01 = UI.image('https://site.com/bg.jpg');
task.ui.add(img01);
за цвет фона задачи отвечает слой tasks-item-head ui-elem
цвет текста по умолчанию #0a0a0a или #2b3541
// вариант вывод сообщений чата
console.log('task:', task.name);
console.log(ChatMessage); // выводит все сообщения чата
for (let i = 0; i < TaskChatMessages.length; i++) {
for (let i = 0; i < 2; i++) {
console.log(ChatMessage[i]); выводит сообщения одно за другим
console.log(i); //сколько раз
}
// узнаем системное значение нужного стикера при его добавлении
Stickers.onPin = function (task, sticker, value) {
Notifier.warn(value);
return true; // prevent adding sticker
};
// пишет в лог Консоли DevTools все сообщения из чата некой задачи
var task = Items.get(' --- ID задачи ---');
var messages = Chat.listMessages(task);
// alert(messages);
const chatmessage = Array.from(messages, ({text}) => text);
console.log('task:', task.name);
for (let i = 0; i < messages.length; i++) {
console.log(chatmessage[i]);
}
// откроет доску (сделает активной), можно подвязать к кнопке
var board = Items.get('---board --- ');
board.open();
// делает активным проект с указанным именем, можно подвязать к кнопке
Current.company.find('--- имя проекта буквами ---').open();
// запрещает ручное(!) перемещение задачи в другие колонки и вверх-вниз, но эту задачу можно сдвигать другими задачами
Items.allowDrag = function (object) {
//if (unmovedtask1.id === '--- ID ---') {
if (object.type === 'Task' && object.id === '---ID задачи---') { // если ID задачи совпадает с заданным
return false; // запретить перетаскивание
}
return true;
};
🙈🙉🙊