PageSourceSearch

https://prattcenter.net/assets/gray_matter/modules/cell_group-66d7…88e7e89ef13dde65743b0b96af5fcb53d0a2c301.js

js prattcenter.net collected 2026-10-02 03:37:13 UTC 7,765 bytes, 230 lines download raw bytes

1// Copyright (c) 2021-2025 GrayBits LLC
2
3import * as InitializerCallbacks from 'gray_matter/modules/initializable/initializer_callbacks'
4import * as Builder from 'gray_matter/utility/builder'
5import * as EventHelpers from 'gray_matter/utility/event_helpers'
6import * as Notification from 'gray_matter/utility/notification'
7import * as ItemForm from 'gray_matter/forms/item_form'
8import CopyFrom from 'gray_matter/modules/copy_from'
9import PopInInterface from 'gray_matter/utility/pop_in_interface'
10import cellPreview from 'gray_matter/modules/cell_preview'
11import axios from 'axios'
12
13export default class CellGroup{
14  constructor(e){
15    this.element = e;
16    this.element.cell_group = this;
17    this.parent_type = e.dataset.type;
18    this.attribute = e.dataset.attribute;
19    this.child_index = e.querySelectorAll('.cell').length;
20    this.cells_list = e.querySelector('ul');
21    this.initAddButtons(e.querySelector('.cell_group_top'));
22    this.form = e.closest('form.item_form');
23    
24    let go_to_bottom = e.querySelector('.go_to_bottom');
25    if (go_to_bottom){
26      e.querySelector('.go_to_bottom').addEventListener('click', (e) => this.goToBottom(e));
27    }
28    let copy_from = e.querySelector('.copy_from');
29    if (copy_from){
30      e.querySelector('.copy_from').addEventListener('click', (e) => this.copyFrom(e));
31    }
32    if (e.classList.contains('single_cell_type')){
33      e.querySelector('.cell_group_top label').addEventListener('click', (e) => this.addCell(e));
34      e.querySelector('.cell_group_top .add').addEventListener('click', (e) => this.addCell(e));
35      e.querySelector('.single_cell_type_bottom .add').addEventListener('click', (e) => this.addCell(e, true));
36    }
37    this.cells_list.querySelectorAll('li.cell').forEach((cell) => this.initializeCell(cell));
38    this.setBlankClass();
39  }
40
41  initAddButtons(e){
42    e.querySelectorAll('.cell_group_add_buttons .add').forEach((button) => { 
43      button.addEventListener('click', (e) => this.addCell(e)); 
44    });
45  }
46
47  openAddButtons(e){
48    e.target.closest('.cell_group_add_buttons').classList.toggle('closed');
49  }
50
51  deleteCell(e){
52    let button = e.target.closest('button');
53    let cell = e.target.closest('.cell');
54    button.disabled = true;
55    this.addDestroyFields(cell);
56    cell.addEventListener('transitionend', (e) => this.removeAfterTransition(e));
57    cell.classList.add('poppedout');
58    cell.offsetHeight;
59  }
60
61  addDestroyFields(cell){
62    let cell_id = cell.querySelector('input[type="hidden"].cell_id');
63    let cell_destroy = cell.querySelector('input[type="hidden"].cell_destroy');
64    if (cell_id.value * 1 > 0){
65      cell_destroy.value = 'true';
66      cell_destroy.classList.add('to_clear');
67      cell_id.classList.add('to_clear');
68      this.form.appendChild(cell_destroy);
69      this.form.appendChild(cell_id);
70    }
71  }
72
73  removeAfterTransition(e){
74    if (e.propertyName == 'opacity'){
75      e.target.remove();
76      this.setBlankClass();
77    }
78  }
79  
80  async addCell(e, add_to_bottom){
81    let cell = e.target.closest('.cell');
82    let type = e.target.closest('button');
83    let params = { attribute: this.attribute, child_index: this.child_index };
84    
85    if (this.element.dataset.belongsToAttribute){
86      params['belongs_to_attribute'] = this.element.dataset.belongsToAttribute;
87    }
88
89    if (type){
90      type = type.dataset.type || 'nested';
91    } else {
92      type = e.target.closest('.cell_group_top').querySelector('.button.add').dataset.type || 'nested';
93    }
94    this.child_index += 1;
95    try{
96      const response = await axios.get(
97        `/${this.form.dataset.routesPrefix}/association/cells/${this.parent_type}/${type}`, 
98        { params: params });
99      let new_cell = Builder.createFromHTML(response.data.cell);
100      if (add_to_bottom){
101        this.cells_list.append(new_cell);
102      } else if (cell){
103        Builder.insertAfter(cell, new_cell);
104      } else {
105        this.cells_list.prepend(new_cell);
106      }
107      this.cells_list.dispatchEvent(new Event('inserted'));
108      this.initializeCell(new_cell);
109      this.setBlankClass();
110      return new_cell;
111    } catch (error){
112      Notification.showResponseError(error);
113    }
114  }
115  
116  initializeCell(cell){
117    if (!cell.initialized){
118      cell.offsetHeight;
119      InitializerCallbacks.applyAll(cell);
120      this.initAddButtons(cell);
121      cell.querySelector('.cell_bar_single .delete, .cell_bar .delete').addEventListener('click', (e) => this.deleteCell(e));
122      cell.classList.remove('prepop');
123      let open_button = cell.querySelector('.cell_group_add_buttons .open.button');
124      if (open_button){
125        open_button.addEventListener('click', (e) => this.openAddButtons(e));
126      }
127      cell.initialized = true;
128    }
129  }
130
131  setBlankClass(){
132    this.element.classList.toggle('with_cells', this.cells_list.childElementCount > 0);
133  }
134
135  goToBottom(){
136    this.cells_list.lastElementChild.scrollIntoView();
137  }
138
139  async copyFrom(){
140    let belongs_to_attribute = '';
141    if (this.element.dataset.belongsToAttribute){
142      belongs_to_attribute = `/${this.element.dataset.belongsToAttribute}`;
143    }
144    this.copy_from = new PopInInterface(
145      this.element, 
146      { 
147        url: `${ItemForm.basePath(this.form)}/copy_from/${this.attribute}${belongs_to_attribute}`, 
148        setup: (pop_in_interface) => {
149          CopyFrom.init(pop_in_interface.element, (e) => this.copyHandler(e), this.child_index);
150        }
151      }
152    );
153  }
154
155  copyHandler(response){
156    this.cells_list.querySelectorAll('.cell').forEach((cell) => this.addDestroyFields(cell));
157    this.cells_list.innerHTML = '';
158    response.data.cells.forEach((cell) => {
159      let new_cell = Builder.createFromHTML(cell);
160      this.cells_list.append(new_cell);
161      this.initializeCell(new_cell);
162    });
163    this.cells_list.dispatchEvent(new Event('inserted'));
164    this.setBlankClass();
165    this.copy_from.cancel();
166  }
167
168  static goToTop(){
169    this.closest('.cell_group').querySelector('.cell_group_top').scrollIntoView();
170  }
171
172  static toggleCell(e){
173    if (e.target.checked) {
174      CellGroup.expandCell(e.target.closest('.cell'));
175    } else {
176      CellGroup.collapseCell(e.target.closest('.cell'));
177    }
178  }
179
180  static toggleCellGroup(e){
181    let group = this.closest('.cell_group').cell_group;
182    if (e.target.checked) {
183      [].slice.call(group.cells_list.children).forEach(CellGroup.expandCell);
184    } else {
185      [].slice.call(group.cells_list.children).forEach(CellGroup.collapseCell);
186    } 
187  }
188
189  static expandCell(cell){
190    if (cell.classList.contains('collapsed')){
191      cell.classList.remove('collapsed');
192      cell.querySelector('.cell_toggle').toggle.check();
193      let cell_preview = cell.querySelector('.cell_preview');
194      cell_preview.innerHTML = cell.default_preview;
195    }
196  }
197
198  static collapseCell(cell){
199    if (!cell.classList.contains('collapsed')){
200      cell.classList.add('collapsed');
201      cell.querySelector('.cell_toggle').toggle.uncheck();
202      let cell_preview = cell.querySelector('.cell_preview');
203      cell.default_preview = cell_preview.innerHTML;
204      cell_preview.innerHTML = `<span class="preview_type_icon">${cell_preview.textContent.substring(0, 1)}</span>`;
205      cell_preview.innerHTML += cellPreview(cell);
206    }
207  }
208  
209  static initInstance(e){
210    if (!e.initilized){
211      new this(e);
212    }
213  }
214
215  static init(){
216    let form = document.querySelector('form.item_form');
217    if (!form) return;
218    
219    document.querySelectorAll('.cell_group').forEach((e) => CellGroup.initInstance(e));  
220    EventHelpers.register(form, {
221      change: {
222        cell_toggle: CellGroup.toggleCell,
223        cell_group_toggle: CellGroup.toggleCellGroup
224      },
225      click: {
226        go_to_top: CellGroup.goToTop
227      }
228    });
229  }
230};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.