Yougile - скрипты для настройки, расширения функций и удобства (самодельные и подсмотренные)

Делалось Deva V. для собственных нужд в Конфигураторе Yougile https://yougile.com/

Видео о работе с Конфигуратором - https://www.youtube.com/watch?v=UOKxyTRv0Bo

Быстрое открытие окна Конфигуратора - Ctrl+Shift+~ (тильда)

Пользовательская информация на досках и в задачах не затрагивается.

> Применяя идеи, содержащиеся на этой странице, вы сами несете полную личную ответственность за полученный результат.



Часть 1. Удобство работы

Автоматика для стикера №1

Модификация скрипта из стандартного примера

Приклеиваем нужный стикер при попадании задачи в определенную колонку

/**
  * При перемещении задачи в колонку, присваивать стикер "сегодня",
  * при перемещении задачи из колонки, убирать стикер.
  * Замените на своё: 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; // и затем переместить задачу (не возвращать ее на место)
  }
};    

Автоматика для стикера №2

Модификация скрипта из стандартного примера

Приклеиваем нужный стикер при добавлении задачи в определенную колонку

/**
  * При добавлении задачи в нужную колонку, присваивать стикер "сегодня"
  * Замените на своё: 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; // добавить задачу (не отменять процедуру создания задачи)
};    

Автоматика для стикера №3

Модификация скрипта из стандартного примера

Задаем нужный стикер во время постановки задачи

/**
 * Если при создании задачи сначала написать особый символ, то она сразу получит определенный стикер 
*/

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); // приклеиваем стикер
  }
};

Часть 2. Задачи

Контейнер с текстом и кнопкой внутри задачи

Модификация скрипта из стандартного примера

заготовка на будущее

/**
 * Добавляет панель (контейнер) с кнопкой и текстом в задачу.
*/

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();

Часть 3. Украшательства

Эмоджи

Добавьте эмоджи в названия колонок, в задачи и стикеры Это придает свежести и помогает уникальности. В 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-код внутрь задачи

Аналогично предыдущему, но анимация включается при добавлении особого стикера

Для привлечения внимания к задаче:

  1. создать новый особый стикер, который будет связан с анимацией
  2. узнать системное значение его value (см. в коде) и прописать в коде
  3. при добавлении этого стикера вместе с ним в задаче появятся и вращающиеся символы "!!!""
  4. при снятии стикера анимация исчезает
  5. вместо !!! внутри слоя можно использовать эмоджи и т.п.
  6. недоделка: при отключении/включении этого скрипта анимация выключается и не восстанавливается, стикеры надо ставить заново (проще всего кликнув по стикеру внутри задачи)
  7. при большом количестве таких стикеров на слабых компьютерах возможна повышенная нагрузка на процессор - поэтому используем такой особый стикер только в особых случаях :)
  8. тонкая настройка вращения: height - радиус вращения, width - ширина места для слова
// анимация
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() // при смене доски восстановить кнопки 
}

Еще js, html и ccs3 плюшки (на будущее)

<!-- пульсирующий текст
<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;
};

🙈🙉🙊


Select a repo