4 |
5 | An adaptation of Sarah Drasner's Night Owl VS Code Theme
6 | https://github.com/sdras/night-owl-vscode-theme
7 |
8 | Copyright (c) 2018 Sarah Drasner
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
28 | */
29 |
30 | .tiptap-editor .ProseMirror {
31 | .hljs {
32 | background: theme('colors.gray.800');
33 | color: #d6deeb;
34 | padding: 0.5rem 1rem;
35 | border-radius: 0.5rem;
36 | font-size: 0.875rem;
37 | }
38 |
39 | /* General Purpose */
40 |
41 | .hljs-keyword {
42 | color: #c792ea;
43 | }
44 |
45 | .hljs-built_in {
46 | color: #addb67;
47 | }
48 |
49 | .hljs-type {
50 | color: #82aaff;
51 | }
52 |
53 | .hljs-literal {
54 | color: #ff5874;
55 | }
56 |
57 | .hljs-number {
58 | color: #F78C6C;
59 | }
60 |
61 | .hljs-regexp {
62 | color: #5ca7e4;
63 | }
64 |
65 | .hljs-string {
66 | color: #ecc48d;
67 | }
68 |
69 | .hljs-subst {
70 | color: #d3423e;
71 | }
72 |
73 | .hljs-symbol {
74 | color: #82aaff;
75 | }
76 |
77 | .hljs-class {
78 | color: #ffcb8b;
79 | }
80 |
81 | .hljs-function {
82 | color: #82AAFF;
83 | }
84 |
85 | .hljs-title {
86 | color: #DCDCAA;
87 | }
88 |
89 | .hljs-params {
90 | color: #7fdbca;
91 | }
92 |
93 | /* Meta */
94 |
95 | .hljs-comment {
96 | color: #637777;
97 | }
98 |
99 | .hljs-doctag {
100 | color: #7fdbca;
101 | }
102 |
103 | .hljs-meta {
104 | color: #82aaff;
105 | }
106 |
107 | .hljs-meta .hljs-keyword {
108 |
109 | color: #82aaff;
110 | }
111 |
112 | .hljs-meta .hljs-string {
113 | color: #ecc48d;
114 | }
115 |
116 | /* Tags, attributes, config */
117 |
118 | .hljs-section {
119 | color: #82b1ff;
120 | }
121 |
122 | .hljs-tag,
123 | .hljs-name {
124 | color: #7fdbca;
125 | }
126 |
127 | .hljs-attr {
128 | color: #7fdbca;
129 | }
130 |
131 | .hljs-attribute {
132 | color: #80cbc4;
133 | }
134 |
135 | .hljs-variable {
136 | color: #addb67;
137 | }
138 |
139 | /* Markup */
140 |
141 | .hljs-bullet {
142 | color: #d9f5dd;
143 | }
144 |
145 | .hljs-code {
146 | color: #80CBC4;
147 | }
148 |
149 | .hljs-emphasis {
150 | color: #c792ea;
151 | font-style: italic;
152 | }
153 |
154 | .hljs-strong {
155 | color: #addb67;
156 | font-weight: bold;
157 | }
158 |
159 | .hljs-formula {
160 | color: #c792ea;
161 | }
162 |
163 | .hljs-link {
164 | color: #ff869a;
165 | }
166 |
167 | .hljs-quote {
168 | color: #697098;
169 | }
170 |
171 | /* CSS */
172 |
173 | .hljs-selector-tag {
174 | color: #ff6363;
175 | }
176 |
177 | .hljs-selector-id {
178 | color: #fad430;
179 | }
180 |
181 | .hljs-selector-class {
182 | color: #addb67;
183 | }
184 |
185 | .hljs-selector-attr,
186 | .hljs-selector-pseudo {
187 | color: #c792ea;
188 | }
189 |
190 | /* Templates */
191 |
192 | .hljs-template-tag {
193 | color: #c792ea;
194 | }
195 |
196 | .hljs-template-variable {
197 | color: #addb67;
198 | }
199 |
200 | /* diff */
201 |
202 | .hljs-addition {
203 | color: #addb67ff;
204 | font-style: italic;
205 | }
206 |
207 | .hljs-deletion {
208 | color: #EF535090;
209 | font-style: italic;
210 | }
211 | }
212 |
213 | [wire\:key*="filament_tiptap_source"] {
214 | .fi-fo-component-ctn {
215 | height: 100%;
216 |
217 | > div {
218 | height: 100%;
219 |
220 | .fi-fo-field-wrp {
221 | height: 100%;
222 |
223 | > div {
224 | height: 100%;
225 | grid-template-rows: auto 1fr;
226 |
227 | .source_code_editor * {
228 | height: 100% !important;
229 | }
230 | }
231 | }
232 | }
233 | }
234 | }
235 |
236 | .sorting .tiptap-wrapper {
237 | pointer-events: none;
238 | }
239 |
240 | .tiptap-wrapper.tiptap-fullscreen {
241 | position: fixed;
242 | top: 0;
243 | left: 0;
244 | bottom: 0;
245 | right: 0;
246 | z-index: 40;
247 | display: flex;
248 | flex-direction: column;
249 | height: 100%;
250 |
251 | .tiptap-toolbar {
252 | border-radius: 0;
253 | }
254 |
255 | .tiptap-prosemirror-wrapper {
256 | max-height: 100%;
257 | padding-block-end: 3rem;
258 | }
259 | }
260 |
261 | .tiptap-editor .tiptap-content {
262 | display: flex;
263 | flex-direction: column;
264 | }
265 |
266 | .tiptap-prosemirror-wrapper {
267 | &.prosemirror-w-sm { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.sm')) / 2)); }
268 | &.prosemirror-w-md { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.md')) / 2)); }
269 | &.prosemirror-w-lg { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.lg')) / 2)); }
270 | &.prosemirror-w-xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.xl')) / 2)); }
271 | &.prosemirror-w-2xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.2xl')) / 2)); }
272 | &.prosemirror-w-3xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.3xl')) / 2)); }
273 | &.prosemirror-w-4xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.4xl')) / 2)); }
274 | &.prosemirror-w-5xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.5xl')) / 2)); }
275 | &.prosemirror-w-6xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.6xl')) / 2)); }
276 | &.prosemirror-w-7xl { padding: 0 max(theme('padding.4'), calc((100% - theme('maxWidth.7xl')) / 2)); }
277 | &.prosemirror-w-none { padding: 0 theme('padding.4'); }
278 | }
279 |
280 | .tiptap-editor .ProseMirror {
281 | border-bottom-left-radius: 0.375rem;
282 | border-bottom-right-radius: 0.375rem;
283 | flex: 1 1 0;
284 | padding-block: 1rem;
285 | margin-inline: auto;
286 | position: relative;
287 | width: 100%;
288 | color: theme('colors.black');
289 |
290 | &.ProseMirror-focused .ProseMirror-selectednode {
291 | @apply outline-2 outline-offset-2 outline-dashed outline-gray-700 dark:outline-gray-300;
292 | }
293 |
294 | .tiptap-block-wrapper {
295 | @apply rounded-md overflow-hidden bg-gray-100 dark:bg-gray-800;
296 |
297 | .tiptap-block {
298 | .tiptap-block-heading {
299 | @apply flex items-center justify-between py-1 px-3 leading-none text-gray-900 bg-gray-200 dark:text-white dark:bg-gray-950;
300 |
301 | .tiptap-block-title {
302 | @apply text-sm uppercase font-bold opacity-80;
303 | }
304 | }
305 |
306 | .tiptap-block-actions {
307 | @apply flex items-center gap-2;
308 |
309 | button {
310 | @apply opacity-75 hover:opacity-100 focus:opacity-100 hover:text-primary-500 focus:text-primary-500;
311 | }
312 | }
313 |
314 | .preview {
315 | @apply p-4;
316 | }
317 | }
318 | }
319 |
320 | .filament-tiptap-hurdle {
321 | width: 100%;
322 | max-width: 100vw;
323 | padding-block: 1rem;
324 | background-color: theme('colors.gray.800');
325 | position: relative;
326 |
327 | &::before,
328 | &::after {
329 | content: '';
330 | position: absolute;
331 | display: block;
332 | width: 100%;
333 | top: 0;
334 | bottom: 0;
335 | background-color: inherit;
336 | }
337 |
338 | &::before {
339 | left: -100%;
340 | }
341 |
342 | &::after {
343 | right: -100%;
344 | }
345 |
346 | &[data-color="gray_light"] {
347 | color: theme('colors.gray.900');
348 | background-color: theme('colors.gray.300');
349 | }
350 |
351 | &[data-color="gray"] {
352 | color: white;
353 | background-color: theme('colors.gray.500');
354 | }
355 |
356 | &[data-color="gray_dark"] {
357 | color: white;
358 | background-color: theme('colors.gray.800');
359 | }
360 |
361 | &[data-color="primary"] {
362 | color: theme('colors.gray.900');
363 | background-color: theme('colors.primary.500');
364 | }
365 |
366 | &[data-color="secondary"] {
367 | color: theme('colors.gray.900');
368 | background-color: theme('colors.warning.500');
369 | }
370 |
371 | &[data-color="tertiary"] {
372 | color: white;
373 | background-color: theme('colors.success.500');
374 | }
375 |
376 | &[data-color="accent"] {
377 | color: white;
378 | background-color: theme('colors.danger.500');
379 | }
380 | }
381 |
382 | &.ProseMirror-focused {
383 | outline: none;
384 | }
385 |
386 | > * + * {
387 | margin-block-start: 1rem;
388 | }
389 |
390 | > * + h1,
391 | > * + h2,
392 | > * + h3,
393 | > * + h4,
394 | > * + h5,
395 | > * + h6 {
396 | margin-block-start: 2rem;
397 | }
398 |
399 | img {
400 | display: inline-block;
401 | }
402 |
403 | h1,
404 | h2,
405 | h3,
406 | h4,
407 | h5,
408 | h6 {
409 | font-weight: bold;
410 | }
411 |
412 | h1 {
413 | font-size: 1.75rem;
414 | line-height: 1.1;
415 | }
416 |
417 | h2 {
418 | font-size: 1.5rem;
419 | line-height: 1.1;
420 | }
421 |
422 | h3 {
423 | font-size: 1.25rem;
424 | line-height: 1.25;
425 | }
426 |
427 | h4 {
428 | font-size: 1.125rem;
429 | }
430 |
431 | .lead {
432 | font-size: 1.375rem;
433 | line-height: 1.3;
434 | }
435 |
436 | small {
437 | font-size: 0.75rem;
438 | }
439 |
440 | ul,
441 | ol {
442 | @apply space-y-2;
443 | padding-inline-start: 1rem;
444 | margin-inline-start: 1rem;
445 | }
446 |
447 | ul {
448 | list-style: disc;
449 | }
450 |
451 | ol {
452 | list-style: decimal;
453 | }
454 |
455 | ul.checked-list {
456 | list-style-type: none;
457 | margin-inline-start: 0;
458 | }
459 |
460 | ul.checked-list li {
461 | display: flex;
462 | align-items: baseline;
463 | gap: 0.375em;
464 | }
465 |
466 | ul.checked-list li::before {
467 | content: '✓';
468 | width: 1.25rem;
469 | height: 1.25rem;
470 | flex-shrink: 0;
471 | }
472 |
473 | blockquote {
474 | border-left: 0.25rem solid theme("colors.gray.400");
475 | padding-inline-start: 0.5rem;
476 | margin-inline-start: 1rem;
477 | font-size: 1.25rem;
478 | }
479 |
480 | hr {
481 | border-color: theme("colors.gray.400");
482 | }
483 |
484 | a {
485 | color: theme("colors.blue.600");
486 | text-decoration: underline;
487 | }
488 |
489 | a[id] {
490 | color: theme('colors.black');
491 | text-decoration: none;
492 | &::before {
493 | content: '# ';
494 | color: theme("colors.gray.500");
495 | opacity: 50;
496 | }
497 | }
498 |
499 | a[data-as-button="true"] {
500 | background-color: theme("colors.gray.900");
501 | color: white !important;
502 | text-decoration: none;
503 | display: inline-block;
504 | @apply rounded-md py-2 px-5;
505 |
506 | &[data-as-button-theme="primary"] {
507 | background-color: theme("colors.primary.600");
508 | }
509 |
510 | &[data-as-button-theme="secondary"] {
511 | background-color: theme("colors.warning.600");
512 | }
513 |
514 | &[data-as-button-theme="tertiary"] {
515 | background-color: theme("colors.success.600");
516 | }
517 |
518 | &[data-as-button-theme="accent"] {
519 | background-color: theme("colors.danger.600");
520 | }
521 | }
522 |
523 | sup {
524 | font-size: 65%;
525 | }
526 |
527 | img {
528 | border: dashed 2px transparent;
529 |
530 | &.ProseMirror-selectednode {
531 | border-radius: theme("borderRadius.DEFAULT");
532 | outline-offset: 2px;
533 | outline: theme("colors.gray.900") dashed 2px;
534 | }
535 | }
536 |
537 | table {
538 | border-collapse: collapse;
539 | margin: 0;
540 | overflow: hidden;
541 | table-layout: fixed;
542 | width: 100%;
543 | position: relative;
544 | }
545 |
546 | table td,
547 | table th {
548 | border: 1px solid theme("colors.gray.400");
549 | min-width: 1em;
550 | padding: 3px 5px;
551 | vertical-align: top;
552 | background-clip: padding-box
553 | }
554 |
555 | table td > *,
556 | table th > * {
557 | margin-bottom: 0;
558 | }
559 |
560 | table th {
561 | background-color: theme("colors.gray.200");
562 | color: theme("colors.gray.700");
563 | font-weight: 700;
564 | text-align: left;
565 | }
566 |
567 | table .selectedCell {
568 | position: relative;
569 | }
570 |
571 | table .selectedCell:after {
572 | background: rgba(200, 200, 255, 0.4);
573 | content: "";
574 | left: 0;
575 | right: 0;
576 | top: 0;
577 | bottom: 0;
578 | pointer-events: none;
579 | position: absolute;
580 | z-index: 2;
581 | }
582 |
583 | table .column-resize-handle {
584 | background-color: #adf;
585 | bottom: -2px;
586 | position: absolute;
587 | right: -2px;
588 | pointer-events: none;
589 | top: 0;
590 | width: 4px;
591 | }
592 |
593 | table p {
594 | margin: 0;
595 | }
596 |
597 | .tableWrapper {
598 | padding: 1rem 0;
599 | overflow-x: auto;
600 | }
601 |
602 | .resize-cursor {
603 | cursor: col-resize;
604 | }
605 |
606 | pre {
607 | padding: .75rem 1rem;
608 | border-radius: .25rem;
609 | font-size: .875rem;
610 |
611 | code {
612 | border-radius: 0;
613 | padding-inline: 0;
614 | }
615 | }
616 |
617 | code {
618 | background-color: theme("colors.gray.300");
619 | border-radius: 0.25rem;
620 | padding-inline: 0.25rem;
621 | }
622 |
623 | pre.hljs {
624 | direction: ltr;
625 | code {
626 | background-color: transparent;
627 | }
628 | }
629 |
630 | .filament-tiptap-grid,
631 | .filament-tiptap-grid-builder {
632 | display: grid;
633 | gap: 1rem;
634 | box-sizing: border-box;
635 |
636 | .filament-tiptap-grid__column,
637 | .filament-tiptap-grid-builder__column {
638 | box-sizing: border-box;
639 | border-style: dashed;
640 | border-width: 1px;
641 | border-color: theme("colors.gray.400");
642 | padding: 0.5rem;
643 | border-radius: theme("borderRadius.DEFAULT");
644 |
645 | > * + * {
646 | margin-block-start: 1rem;
647 | }
648 | }
649 |
650 | &.ProseMirror-selectednode {
651 | border-radius: theme("borderRadius.DEFAULT");
652 | outline-offset: 2px;
653 | outline: theme("colors.gray.900") dashed 2px;
654 | }
655 | }
656 |
657 | .filament-tiptap-grid[type^="asymetric"] {
658 | grid-template-columns: 1fr;
659 | grid-template-rows: auto;
660 | }
661 |
662 | @media (max-width: theme('screens.sm')) {
663 | .filament-tiptap-grid-builder[data-stack-at="sm"] {
664 | grid-template-columns: 1fr !important;
665 |
666 | .filament-tiptap-grid-builder__column {
667 | grid-column: span 1 !important;
668 | }
669 | }
670 | }
671 |
672 | @media (max-width: theme('screens.md')) {
673 | .filament-tiptap-grid-builder[data-stack-at="md"] {
674 | grid-template-columns: 1fr !important;
675 |
676 | .filament-tiptap-grid-builder__column {
677 | grid-column: span 1 !important;
678 | }
679 | }
680 | }
681 |
682 | @media (max-width: theme('screens.lg')) {
683 | .filament-tiptap-grid-builder[data-stack-at="lg"] {
684 | grid-template-columns: 1fr !important;
685 |
686 | .filament-tiptap-grid-builder__column {
687 | grid-column: span 1 !important;
688 | }
689 | }
690 | }
691 |
692 | .filament-tiptap-grid[type="asymetric-right-thirds"] {
693 | @screen md {
694 | grid-template-columns: 1fr 2fr;
695 | }
696 | }
697 |
698 | .filament-tiptap-grid[type="asymetric-left-thirds"] {
699 | @screen md {
700 | grid-template-columns: 2fr 1fr;
701 | }
702 | }
703 |
704 | .filament-tiptap-grid[type="asymetric-right-fourths"] {
705 | @screen md {
706 | grid-template-columns: 1fr 3fr;
707 | }
708 | }
709 |
710 | .filament-tiptap-grid[type="asymetric-left-fourths"] {
711 | @screen md {
712 | grid-template-columns: 3fr 1fr;
713 | }
714 | }
715 |
716 | .filament-tiptap-grid[type="responsive"] {
717 | grid-template-columns: 1fr;
718 | grid-template-rows: auto;
719 |
720 | &[cols="2"] {
721 | @screen md {
722 | grid-template-columns: repeat(2, 1fr);
723 | }
724 | }
725 |
726 | &[cols="3"] {
727 | @screen md {
728 | grid-template-columns: repeat(3, 1fr);
729 | }
730 | }
731 |
732 | &[cols="4"] {
733 | @screen md {
734 | grid-template-columns: repeat(2, 1fr);
735 | }
736 |
737 | @screen lg {
738 | grid-template-columns: repeat(4, 1fr);
739 | }
740 | }
741 |
742 | &[cols="5"] {
743 | @screen md {
744 | grid-template-columns: repeat(5, 1fr);
745 | }
746 | }
747 | }
748 |
749 | .filament-tiptap-grid[type="fixed"] {
750 | &[cols="2"] {
751 | grid-template-columns: repeat(2, 1fr);
752 | }
753 |
754 | &[cols="3"] {
755 | grid-template-columns: repeat(3, 1fr);
756 | }
757 |
758 | &[cols="4"] {
759 | grid-template-columns: repeat(4, 1fr);
760 | }
761 |
762 | &[cols="5"] {
763 | grid-template-columns: repeat(5, 1fr);
764 | }
765 | }
766 |
767 | [data-youtube-video],
768 | [data-vimeo-video],
769 | [data-native-video] {
770 | border: dashed 1px transparent;
771 |
772 | &.ProseMirror-selectednode {
773 | border-radius: theme("borderRadius.DEFAULT");
774 | outline-offset: 2px;
775 | outline: theme("colors.gray.900") dashed 2px;
776 | }
777 |
778 | iframe,
779 | video {
780 | pointer-events: none;
781 | }
782 | }
783 |
784 | div[data-type="details"] {
785 | box-sizing: border-box;
786 | border-style: dashed;
787 | border-width: 1px;
788 | border-color: theme("colors.gray.400");
789 | border-radius: theme("borderRadius.DEFAULT");
790 | position: relative;
791 |
792 | button {
793 | position: absolute;
794 | z-index: 1;
795 | top: 0.125rem;
796 | right: 0.25rem;
797 | color: theme("colors.gray.400");
798 | }
799 |
800 | summary {
801 | padding: 0.375rem 0.5rem;
802 | font-weight: 700;
803 | border-bottom-style: solid;
804 | border-bottom-width: 1px;
805 | border-bottom-color: theme("colors.gray.200");
806 |
807 | &::marker {
808 | content: "";
809 | display: none;
810 | }
811 | }
812 |
813 | div[data-type="details-content"] {
814 | padding: 0.5rem;
815 | height: auto;
816 |
817 | > * + * {
818 | margin-block-start: 1rem;
819 | }
820 | }
821 | }
822 | }
823 |
824 | .dark {
825 | .tiptap-editor .ProseMirror {
826 | color: theme('colors.gray.200');
827 |
828 | blockquote {
829 | border-left-color: theme("colors.gray.500");
830 | }
831 |
832 | hr {
833 | border-color: theme("colors.gray.500");
834 | }
835 |
836 | a {
837 | color: theme("colors.blue.400");
838 | }
839 |
840 | a[id] {
841 | color: theme('colors.gray.200');
842 | }
843 |
844 | code {
845 | background-color: theme("colors.gray.800");
846 | }
847 |
848 | table td,
849 | table th {
850 | border-color: theme("colors.gray.600");
851 | }
852 |
853 | table th {
854 | background-color: theme("colors.gray.800");
855 | color: theme('colors.gray.100');
856 | }
857 |
858 | .filament-tiptap-grid {
859 | .filament-tiptap-grid__column {
860 | border-color: theme("colors.gray.500");
861 | }
862 |
863 | &.ProseMirror-selectednode {
864 | outline-color: theme("colors.gray.400");
865 | }
866 | }
867 |
868 | img.ProseMirror-selectednode {
869 | outline-color: theme("colors.gray.400");
870 | }
871 |
872 | [data-youtube-video],
873 | [data-vimeo-video],
874 | [data-native-video] {
875 | &.ProseMirror-selectednode {
876 | outline-color: theme("colors.gray.400");
877 | }
878 | }
879 |
880 | div[data-type="details"] {
881 | box-sizing: border-box;
882 | border-color: theme("colors.gray.500");
883 | border-radius: theme("borderRadius.DEFAULT");
884 | position: relative;
885 |
886 | summary {
887 | border-bottom-color: theme("colors.gray.500");
888 | }
889 | }
890 | }
891 |
892 | .tiptap-editor .ProseMirror-focused .ProseMirror-gapcursor:after {
893 | border-top: 1px solid white;
894 | }
895 | }
896 |
897 |
898 | .tiptap-editor p.is-editor-empty:first-child::before {
899 | content: attr(data-placeholder);
900 | float: left;
901 | height: 0;
902 | pointer-events: none;
903 | @apply text-gray-400 dark:text-gray-500;
904 | }
905 |
906 | .tippy-content-p-0 {
907 | @apply -mx-2 -my-1;
908 | }
909 |
910 | span[data-type="mergeTag"] {
911 | @apply bg-gray-100 dark:bg-gray-800 px-2 py-1 mx-1 rounded;
912 | }
913 |
--------------------------------------------------------------------------------
/resources/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomatophp/filament-docs/c584390e2dd98b07de03115860f61ff3c4f30cee/resources/js/.gitkeep
--------------------------------------------------------------------------------
/resources/lang/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomatophp/filament-docs/c584390e2dd98b07de03115860f61ff3c4f30cee/resources/lang/.gitkeep
--------------------------------------------------------------------------------
/resources/lang/ar/messages.php:
--------------------------------------------------------------------------------
1 | [
5 | 'title' => 'الملفات',
6 | 'group' => 'المحتوى',
7 | 'single' => 'ملف',
8 | 'form' => [
9 | 'ref' => 'المرجع',
10 | 'id' => 'مسلسل',
11 | 'model' => 'خاص بـ',
12 | 'document_template_id' => 'القالب',
13 | 'document' => 'الملف',
14 | 'body' => 'المحتوى',
15 | 'is_send' => 'تم الإرسال',
16 | 'template' => 'القالب',
17 | 'values' => 'القيم',
18 | 'var-value' => 'القيمة',
19 | 'var-label' => 'التسمية',
20 | ],
21 | 'actions' => [
22 | 'print' => 'طباعة',
23 | 'document' => [
24 | 'title' => 'إنشاء ملف',
25 | 'notification' => [
26 | 'title' => 'تم إنشاء الملف',
27 | 'body' => 'تم إنشاء الملف',
28 | 'action' => 'عرض الملف',
29 | ],
30 | ],
31 | ],
32 | ],
33 | 'document-templates' => [
34 | 'title' => 'قوالب الملفات',
35 | 'group' => 'المحتوى',
36 | 'single' => 'قالب',
37 | 'form' => [
38 | 'name' => 'الاسم',
39 | 'vars' => 'المتغيرات',
40 | 'vars-key' => 'المفتاح',
41 | 'vars-label' => 'القيمة',
42 | 'is_active' => 'نشط',
43 | 'body' => 'المحتوى',
44 | 'icon' => 'أيقونة',
45 | 'color' => 'لون',
46 | ],
47 | ],
48 | 'vars' => [
49 | 'day' => 'يوم',
50 | 'date' => 'تاريخ',
51 | 'time' => 'وقت',
52 | 'random' => 'عشوائي',
53 | 'uuid' => 'UUID',
54 | ],
55 | ];
56 |
--------------------------------------------------------------------------------
/resources/lang/en/messages.php:
--------------------------------------------------------------------------------
1 | [
5 | 'title' => 'Documents',
6 | 'group' => 'Content',
7 | 'single' => 'Document',
8 | 'form' => [
9 | 'ref' => 'Reference',
10 | 'id' => 'ID',
11 | 'model' => 'Connected To',
12 | 'document_template_id' => 'Template',
13 | 'document' => 'Document',
14 | 'body' => 'Body',
15 | 'is_send' => 'Is Send',
16 | 'template' => 'Template',
17 | 'values' => 'Values',
18 | 'var-value' => 'Value',
19 | 'var-label' => 'Label',
20 | ],
21 | 'actions' => [
22 | 'print' => 'Print',
23 | 'document' => [
24 | 'title' => 'Create Document',
25 | 'notification' => [
26 | 'title' => 'Document Created',
27 | 'body' => 'Document has been created',
28 | 'action' => 'View Document',
29 | ],
30 | ],
31 | ],
32 | ],
33 | 'document-templates' => [
34 | 'title' => 'Document Templates',
35 | 'group' => 'Content',
36 | 'single' => 'Template',
37 | 'form' => [
38 | 'name' => 'Name',
39 | 'vars' => 'Variables',
40 | 'vars-key' => 'Key',
41 | 'vars-label' => 'Value',
42 | 'is_active' => 'Is Active',
43 | 'body' => 'Body',
44 | 'icon' => 'Icon',
45 | 'color' => 'Color',
46 | ],
47 | ],
48 | 'vars' => [
49 | 'day' => 'Day',
50 | 'date' => 'Date',
51 | 'time' => 'Time',
52 | 'random' => 'Random',
53 | 'uuid' => 'UUID',
54 | ],
55 | ];
56 |
--------------------------------------------------------------------------------
/resources/views/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomatophp/filament-docs/c584390e2dd98b07de03115860f61ff3c4f30cee/resources/views/.gitkeep
--------------------------------------------------------------------------------
/resources/views/layout.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ config('app.name', 'Laravel') }}
9 |
10 |
11 |
75 |
76 |
77 |
78 | @if(\TomatoPHP\FilamentDocs\Facades\FilamentDocs::getHeader())
79 |
82 |
83 | @endif
84 |
85 | {{ $slot }}
86 |
87 | @if(\TomatoPHP\FilamentDocs\Facades\FilamentDocs::getFooter())
88 |
89 |
92 | @endif
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/resources/views/print.blade.php:
--------------------------------------------------------------------------------
1 |
2 | @if(isset($record))
3 | {!! $record->body !!}
4 | @else
5 | {!! $this->getRecord()->body !!}
6 | @endif
7 |
8 |
--------------------------------------------------------------------------------
/src/Console/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomatophp/filament-docs/c584390e2dd98b07de03115860f61ff3c4f30cee/src/Console/.gitkeep
--------------------------------------------------------------------------------
/src/Console/FilamentDocsInstall.php:
--------------------------------------------------------------------------------
1 | info('Publish Vendor Assets');
39 | $this->artisanCommand(['migrate']);
40 | $this->artisanCommand(['optimize:clear']);
41 | $this->artisanCommand(['filament:optimize-clear']);
42 | $this->artisanCommand(['icon:cache']);
43 | $this->info('Filament Docs installed successfully.');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Facades/FilamentDocs.php:
--------------------------------------------------------------------------------
1 | requiresConfirmation();
22 | $this->iconButton();
23 | $this->name('document');
24 | $this->icon('heroicon-m-document-text');
25 | $this->label(trans('filament-docs::messages.documents.actions.document.title'));
26 | $this->tooltip(trans('filament-docs::messages.documents.actions.document.title'));
27 | $this->color('success');
28 | $this->form([
29 | Forms\Components\Select::make('document_template_id')
30 | ->preload()
31 | ->label(trans('filament-docs::messages.documents.form.document_template_id'))
32 | ->searchable()
33 | ->options(DocumentTemplate::query()->where('is_active', 1)->pluck('name', 'id')->toArray())
34 | ->columnSpanFull()
35 | ->required(),
36 | ]);
37 | $this->action(function (array $data, $record) {
38 | $body = FilamentDocs::body($data['document_template_id'], $this->getVars());
39 |
40 | $document = Document::query()->create([
41 | 'model_id' => $record->id,
42 | 'model_type' => get_class($record),
43 | 'document_template_id' => $data['document_template_id'],
44 | 'body' => $body,
45 | ]);
46 |
47 | Notification::make()
48 | ->title(trans('filament-docs::messages.documents.actions.document.notification.title'))
49 | ->body(trans('filament-docs::messages.documents.actions.document.notification.body'))
50 | ->actions([
51 | \Filament\Notifications\Actions\Action::make('document')
52 | ->icon('heroicon-o-document-text')
53 | ->label(trans('filament-docs::messages.documents.actions.document.notification.action'))
54 | ->url(DocumentResource::getUrl('edit', ['record' => $document]))
55 | ->openUrlInNewTab(),
56 | ])
57 | ->success()
58 | ->send();
59 | });
60 | }
61 |
62 | /**
63 | * @return $this
64 | */
65 | public function vars(array | \Closure $var): static
66 | {
67 | $this->vars = $var;
68 |
69 | return $this;
70 | }
71 |
72 | protected function getVars(): array
73 | {
74 | if ($this->vars instanceof \Closure) {
75 | return $this->evaluate($this->vars);
76 | }
77 |
78 | return $this->vars;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/Filament/Actions/Notifications/PrintAction.php:
--------------------------------------------------------------------------------
1 | route = $route;
23 |
24 | return $this;
25 | }
26 |
27 | public function getRoute()
28 | {
29 | return $this->evaluate($this->route);
30 | }
31 |
32 | public function title(Closure | string $title): self
33 | {
34 | $this->title = $title;
35 |
36 | return $this;
37 | }
38 |
39 | public function getTitle()
40 | {
41 | return $this->evaluate($this->title);
42 | }
43 |
44 | protected function setUp(): void
45 | {
46 | parent::setUp();
47 |
48 | $this
49 | ->label(trans('filament-docs::messages.documents.actions.print'))
50 | ->icon('heroicon-o-printer')
51 | ->action(function (Livewire $livewire) {
52 | $livewire->js(
53 | << {
66 | document.body.removeChild(iframe);
67 | document.title = orginalTitle;
68 | }, 1000);
69 | };
70 | JS
71 | );
72 | });
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Filament/Actions/PrintAction.php:
--------------------------------------------------------------------------------
1 | route = $route;
23 |
24 | return $this;
25 | }
26 |
27 | public function getRoute()
28 | {
29 | return $this->evaluate($this->route);
30 | }
31 |
32 | public function title(Closure | string $title): self
33 | {
34 | $this->title = $title;
35 |
36 | return $this;
37 | }
38 |
39 | public function getTitle()
40 | {
41 | return $this->evaluate($this->title);
42 | }
43 |
44 | protected function setUp(): void
45 | {
46 | parent::setUp();
47 |
48 | $this
49 | ->label(trans('filament-docs::messages.documents.actions.print'))
50 | ->icon('heroicon-o-printer')
51 | ->action(function (Livewire $livewire) {
52 | $livewire->js(
53 | << {
66 | document.body.removeChild(iframe);
67 | document.title = orginalTitle;
68 | }, 1000);
69 | };
70 | JS
71 | );
72 | });
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Filament/Actions/Table/PrintAction.php:
--------------------------------------------------------------------------------
1 | route = $route;
23 |
24 | return $this;
25 | }
26 |
27 | public function getRoute()
28 | {
29 | return $this->evaluate($this->route);
30 | }
31 |
32 | public function title(Closure | string $title): self
33 | {
34 | $this->title = $title;
35 |
36 | return $this;
37 | }
38 |
39 | public function getTitle()
40 | {
41 | return $this->evaluate($this->title);
42 | }
43 |
44 | protected function setUp(): void
45 | {
46 | parent::setUp();
47 |
48 | $this
49 | ->label(trans('filament-docs::messages.documents.actions.print'))
50 | ->icon('heroicon-o-printer')
51 | ->action(function (Livewire $livewire) {
52 | $livewire->js(
53 | << {
66 | document.body.removeChild(iframe);
67 | document.title = orginalTitle;
68 | }, 1000);
69 | };
70 | JS
71 | );
72 | });
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Filament/RelationManager/DocumentRelationManager.php:
--------------------------------------------------------------------------------
1 | preload()
57 | ->label(trans('filament-docs::messages.documents.form.document_template_id'))
58 | ->searchable()
59 | ->relationship('documentTemplate', 'name')
60 | ->live()
61 | ->afterStateUpdated(function (Forms\Get $get, Forms\Set $set, $record) {
62 | if (! $record) {
63 | $documentTemplate = DocumentTemplate::query()->find($get('document_template_id'));
64 | if ($documentTemplate) {
65 | $documentTemplateVars = $documentTemplate->documentTemplateVars;
66 | $fields = [];
67 | foreach ($documentTemplateVars as $var) {
68 | $fields[] = [
69 | 'var' => $var->var,
70 | 'label' => FilamentDocs::load()->where('key', $var->var)->first()?->label,
71 | 'key' => $var->value,
72 | 'value' => '',
73 | 'model' => FilamentDocs::load()->where('key', $var->var)->first()?->model,
74 | ];
75 | }
76 |
77 | $collect = collect($fields)->sortBy('model')->toArray();
78 | $set('body', $collect);
79 | }
80 | }
81 | })
82 | ->columnSpanFull()
83 | ->required(),
84 | Forms\Components\Section::make(trans('filament-docs::messages.documents.form.document'))
85 | ->hidden(fn (Forms\Get $get) => (! $get('document_template_id')) || ! $get('body'))
86 | ->schema(function ($record) {
87 | if ($record) {
88 | return [
89 | TiptapEditor::make('body')
90 | ->label(trans('filament-docs::messages.documents.form.body'))
91 | ->required(),
92 | ];
93 | } else {
94 | return [
95 | Forms\Components\Repeater::make('body')
96 | ->hidden(fn ($record, Forms\Get $get) => $record || ! $get('body'))
97 | ->schema([
98 | Forms\Components\Hidden::make('var')->live(),
99 | Forms\Components\Hidden::make('model')->live(),
100 | Forms\Components\Hidden::make('key')->live(),
101 | Forms\Components\TextInput::make('label')
102 | ->disabled()
103 | ->label(trans('filament-docs::messages.documents.form.var-label')),
104 | Forms\Components\Select::make('value')
105 | ->label(trans('filament-docs::messages.documents.form.var-value'))
106 | ->searchable()
107 | ->options(function (Forms\Get $get) {
108 | if ($get('model') && $get('var')) {
109 | return $get('model')::query()->pluck(FilamentDocs::load()->where('key', $get('var'))->first()?->column, 'id')->toArray();
110 | } else {
111 | return [];
112 | }
113 | })
114 | ->live()
115 | ->afterStateUpdated(function (Forms\Get $get, Forms\Set $set) {
116 | $body = [];
117 | $groups = [];
118 | foreach ($get('../../body') as $item) {
119 | if (! array_key_exists($item['model'], $groups)) {
120 | if ($item['value']) {
121 | $groups[$item['model']] = $item['value'];
122 | } else {
123 | $groups[$item['model']] = '';
124 | }
125 | } else {
126 | $item['value'] = $groups[$item['model']] ?? null;
127 | }
128 |
129 | $body[] = $item;
130 | }
131 | $set('../../body', $body);
132 | })
133 | ->required(),
134 | ])
135 | ->label(trans('filament-docs::messages.documents.form.values'))
136 | ->addable(false)
137 | ->deletable(false)
138 | ->reorderable(false)
139 | ->columns(2)
140 | ->columnSpanFull()
141 | ->required(),
142 | ];
143 | }
144 |
145 | }),
146 | Forms\Components\TextInput::make('ref')
147 | ->columnSpanFull()
148 | ->nullable(),
149 | ];
150 |
151 | if (filament('filament-docs')::$isScopedToTenant) {
152 | $schema[] = Forms\Components\Select::make('team_id')
153 | ->label(trans('filament-docs::messages.documents.form.team_id'))
154 | ->visible(fn (Forms\Get $get) => $get('team_id') === null)
155 | ->default(filament()->getTenant()?->id)
156 | ->relationship('team', 'name');
157 | }
158 |
159 | return $form
160 | ->schema($schema);
161 | }
162 |
163 | public static function table(Table $table): Table
164 | {
165 | return $table
166 | ->columns([
167 | Tables\Columns\TextColumn::make('id')
168 | ->searchable()
169 | ->prefix('#')
170 | ->label(trans('filament-docs::messages.documents.form.id'))
171 | ->numeric()
172 | ->sortable(),
173 | Tables\Columns\TextColumn::make('ref')
174 | ->searchable()
175 | ->label(trans('filament-docs::messages.documents.form.ref'))
176 | ->numeric()
177 | ->sortable(),
178 | Tables\Columns\TextColumn::make('documentTemplate.name')
179 | ->badge()
180 | ->color('warning')
181 | ->icon(fn ($record) => $record->documentTemplate->icon)
182 | ->label(trans('filament-docs::messages.documents.form.document_template_id'))
183 | ->url(fn ($record) => DocumentTemplateResource::getUrl('edit', ['record' => $record->documentTemplate->id]))
184 | ->sortable(),
185 | Tables\Columns\TextColumn::make('model' . config('filament-docs.displayname_attribute'))
186 | ->label(trans('filament-docs::messages.documents.form.model'))
187 | ->badge()
188 | ->color('info')
189 | ->icon(function ($record) {
190 | $resources = filament()->getCurrentPanel()->getResources();
191 | foreach ($resources as $item) {
192 | $resourceClass = app($item);
193 | if ($resourceClass->getModel() === $record->model_type) {
194 | return $resourceClass::getNavigationIcon();
195 | }
196 | }
197 | })
198 | ->url(function ($record) {
199 | $resources = filament()->getCurrentPanel()->getResources();
200 | foreach ($resources as $item) {
201 | $resourceClass = app($item);
202 | if ($resourceClass->getModel() === $record->model_type) {
203 | try {
204 | return $resourceClass::getUrl('edit', ['record' => $record->model_id]);
205 | } catch (\Exception $e) {
206 | return '#';
207 | }
208 | }
209 | }
210 | })
211 | ->sortable(),
212 | Tables\Columns\ToggleColumn::make('is_send')
213 | ->label(trans('filament-docs::messages.documents.form.is_send')),
214 | Tables\Columns\TextColumn::make('created_at')
215 | ->dateTime()
216 | ->sortable()
217 | ->toggleable(isToggledHiddenByDefault: true),
218 | Tables\Columns\TextColumn::make('updated_at')
219 | ->dateTime()
220 | ->sortable()
221 | ->toggleable(isToggledHiddenByDefault: true),
222 | ])
223 | ->defaultSort('id', 'desc')
224 | ->filters([
225 | Tables\Filters\SelectFilter::make('document_template_id')
226 | ->label(trans('filament-docs::messages.documents.form.document_template_id'))
227 | ->searchable()
228 | ->options(DocumentTemplate::query()->where('is_active', 1)->pluck('name', 'id')->toArray()),
229 | ])
230 | ->actions([
231 | Tables\Actions\Action::make('view')
232 | ->color('info')
233 | ->modalContent(fn ($record) => view('filament-docs::print', [
234 | 'record' => $record,
235 | ]))
236 | ->icon('heroicon-s-eye')
237 | ->iconButton()
238 | ->tooltip(__('filament-actions::view.single.label')),
239 | PrintAction::make('print')
240 | ->icon('heroicon-s-printer')
241 | ->title(fn ($record) => $record->documentTemplate->name . '#' . $record->id)
242 | ->route(
243 | fn ($record) => Pages\PrintDocument::getUrl(['record' => $record])
244 | )
245 | ->color('warning')
246 | ->iconButton()
247 | ->tooltip(trans('filament-docs::messages.documents.actions.print')),
248 | Tables\Actions\EditAction::make()
249 | ->iconButton()
250 | ->tooltip(__('filament-actions::edit.single.label')),
251 | Tables\Actions\DeleteAction::make()
252 | ->iconButton()
253 | ->tooltip(__('filament-actions::delete.single.label')),
254 | Tables\Actions\ReplicateAction::make()
255 | ->iconButton()
256 | ->tooltip(__('filament-actions::replicate.single.label')),
257 | ])
258 | ->bulkActions([
259 | Tables\Actions\BulkActionGroup::make([
260 | Tables\Actions\DeleteBulkAction::make(),
261 | ]),
262 | ]);
263 | }
264 |
265 | public static function getRelations(): array
266 | {
267 | return [
268 | //
269 | ];
270 | }
271 |
272 | public static function getPages(): array
273 | {
274 | return [
275 | 'index' => Pages\ListDocuments::route('/'),
276 | 'create' => Pages\CreateDocument::route('/create'),
277 | 'edit' => Pages\EditDocument::route('/{record}/edit'),
278 | 'print' => Pages\PrintDocument::route('/{record}/print'),
279 | ];
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentResource/Pages/CreateDocument.php:
--------------------------------------------------------------------------------
1 | title($this->getRecord()->ref ?: $this->getRecord()->documentTemplate->name)
20 | ->route(PrintDocument::getUrl(['record' => $this->getRecord()])),
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentResource/Pages/ListDocuments.php:
--------------------------------------------------------------------------------
1 | label(trans('filament-docs::messages.document-templates.title'))
20 | ->tooltip(trans('filament-docs::messages.document-templates.title'))
21 | ->hiddenLabel()
22 | ->icon('heroicon-o-document')
23 | ->color('info')
24 | ->url(DocumentTemplateResource::getUrl('index')),
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentResource/Pages/PrintDocument.php:
--------------------------------------------------------------------------------
1 | record = $this->resolveRecord($record);
18 | }
19 |
20 | public function getLayout(): string
21 | {
22 | return config('filament-docs.views.layout') ?: 'filament-docs::layout';
23 | }
24 |
25 | public function getView(): string
26 | {
27 | return config('filament-docs.views.view') ?: 'filament-docs::print';
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentTemplateResource.php:
--------------------------------------------------------------------------------
1 | pluck('label', 'key')->toArray(),
62 | [
63 | '$UUID' => trans('filament-docs::messages.vars.uuid'),
64 | '$RANDOM' => trans('filament-docs::messages.vars.random'),
65 | '$DAY' => trans('filament-docs::messages.vars.day'),
66 | '$DATE' => trans('filament-docs::messages.vars.date'),
67 | '$TIME' => trans('filament-docs::messages.vars.time'),
68 | ]
69 | );
70 |
71 | $schema = [
72 | Forms\Components\TextInput::make('name')
73 | ->label(trans('filament-docs::messages.document-templates.form.name'))
74 | ->required()
75 | ->columnSpanFull()
76 | ->maxLength(255),
77 | Forms\Components\KeyValue::make('vars')
78 | ->disabled()
79 | ->valueLabel(trans('filament-docs::messages.document-templates.form.vars-label'))
80 | ->keyLabel(trans('filament-docs::messages.document-templates.form.vars-key'))
81 | ->label(trans('filament-docs::messages.document-templates.form.vars'))
82 | ->columnSpanFull()
83 | ->default($keys),
84 | TiptapEditor::make('body')
85 | ->label(trans('filament-docs::messages.document-templates.form.body'))
86 | ->required()
87 | ->columnSpanFull(),
88 | IconPicker::make('icon')
89 | ->label(trans('filament-docs::messages.document-templates.form.icon')),
90 | Forms\Components\ColorPicker::make('color')
91 | ->label(trans('filament-docs::messages.document-templates.form.color')),
92 | Forms\Components\Toggle::make('is_active')
93 | ->label(trans('filament-docs::messages.document-templates.form.is_active')),
94 |
95 | ];
96 |
97 | if (filament('filament-docs')::$isScopedToTenant) {
98 | $schema[] = Forms\Components\Select::make('team_id')
99 | ->label(trans('filament-docs::messages.document-templates.form.team_id'))
100 | ->visible(fn (Forms\Get $get) => $get('team_id') === null)
101 | ->default(filament()->getTenant()?->id)
102 | ->relationship('team', 'name');
103 | }
104 |
105 | return $form
106 | ->schema($schema);
107 | }
108 |
109 | public static function table(Table $table): Table
110 | {
111 | return $table
112 | ->columns([
113 | Tables\Columns\TextColumn::make('name')
114 | ->label(trans('filament-docs::messages.document-templates.form.name'))
115 | ->searchable(),
116 | Tables\Columns\ToggleColumn::make('is_active')
117 | ->label(trans('filament-docs::messages.document-templates.form.is_active')),
118 | IconColumn::make('icon')
119 | ->label(trans('filament-docs::messages.document-templates.form.icon'))
120 | ->searchable(),
121 | Tables\Columns\ColorColumn::make('color')
122 | ->label(trans('filament-docs::messages.document-templates.form.color'))
123 | ->searchable(),
124 | Tables\Columns\TextColumn::make('created_at')
125 | ->dateTime()
126 | ->sortable()
127 | ->toggleable(isToggledHiddenByDefault: true),
128 | Tables\Columns\TextColumn::make('updated_at')
129 | ->dateTime()
130 | ->sortable()
131 | ->toggleable(isToggledHiddenByDefault: true),
132 | ])
133 | ->filters([
134 | //
135 | ])
136 | ->actions([
137 | Tables\Actions\ViewAction::make()
138 | ->iconButton()
139 | ->tooltip(__('filament-actions::view.single.label')),
140 | Tables\Actions\EditAction::make()
141 | ->iconButton()
142 | ->tooltip(__('filament-actions::edit.single.label')),
143 | Tables\Actions\DeleteAction::make()
144 | ->iconButton()
145 | ->tooltip(__('filament-actions::delete.single.label')),
146 | Tables\Actions\ReplicateAction::make()
147 | ->iconButton()
148 | ->tooltip(__('filament-actions::replicate.single.label')),
149 | ])
150 | ->bulkActions([
151 | Tables\Actions\BulkActionGroup::make([
152 | Tables\Actions\DeleteBulkAction::make(),
153 | ]),
154 | ]);
155 | }
156 |
157 | public static function getRelations(): array
158 | {
159 | return [];
160 | }
161 |
162 | public static function getPages(): array
163 | {
164 | return [
165 | 'index' => Pages\ListDocumentTemplates::route('/'),
166 | 'create' => Pages\CreateDocumentTemplate::route('/create'),
167 | 'edit' => Pages\EditDocumentTemplate::route('/{record}/edit'),
168 | ];
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentTemplateResource/Pages/CreateDocumentTemplate.php:
--------------------------------------------------------------------------------
1 | getRecord());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentTemplateResource/Pages/EditDocumentTemplate.php:
--------------------------------------------------------------------------------
1 | pluck('label', 'key')->toArray(),
25 | [
26 | '$UUID' => trans('filament-docs::messages.vars.uuid'),
27 | '$RANDOM' => trans('filament-docs::messages.vars.random'),
28 | '$DAY' => trans('filament-docs::messages.vars.day'),
29 | '$DATE' => trans('filament-docs::messages.vars.date'),
30 | '$TIME' => trans('filament-docs::messages.vars.time'),
31 | ]
32 | );
33 |
34 | return $data;
35 | }
36 |
37 | public function afterSave(): void
38 | {
39 | FilamentDocs::create($this->getRecord());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Filament/Resources/DocumentTemplateResource/Pages/ListDocumentTemplates.php:
--------------------------------------------------------------------------------
1 | resources([
29 | DocumentTemplateResource::class,
30 | DocumentResource::class,
31 | ]);
32 | }
33 |
34 | public function boot(Panel $panel): void
35 | {
36 | //
37 | }
38 |
39 | public static function make(): static
40 | {
41 | return new static;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/FilamentDocsServiceProvider.php:
--------------------------------------------------------------------------------
1 | commands([
18 | \TomatoPHP\FilamentDocs\Console\FilamentDocsInstall::class,
19 | ]);
20 |
21 | // Register Config file
22 | $this->mergeConfigFrom(__DIR__ . '/../config/filament-docs.php', 'filament-docs');
23 |
24 | // Publish Config
25 | $this->publishes([
26 | __DIR__ . '/../config/filament-docs.php' => config_path('filament-docs.php'),
27 | ], 'filament-docs-config');
28 |
29 | // Register Migrations
30 | $this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
31 |
32 | // Publish Migrations
33 | $this->publishes([
34 | __DIR__ . '/../database/migrations' => database_path('migrations'),
35 | ], 'filament-docs-migrations');
36 | // Register views
37 | $this->loadViewsFrom(__DIR__ . '/../resources/views', 'filament-docs');
38 |
39 | // Publish Views
40 | $this->publishes([
41 | __DIR__ . '/../resources/views' => resource_path('views/vendor/filament-docs'),
42 | ], 'filament-docs-views');
43 |
44 | // Register Langs
45 | $this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'filament-docs');
46 |
47 | // Publish Lang
48 | $this->publishes([
49 | __DIR__ . '/../resources/lang' => base_path('lang/vendor/filament-docs'),
50 | ], 'filament-docs-lang');
51 |
52 | $this->app->bind('filament-docs', function () {
53 | return new FilamentDocsServices;
54 | });
55 |
56 | Livewire::component('tomato-p-h-p.filament-docs.filament.relation-manager.document-relation-manager', DocumentRelationManager::class);
57 | }
58 |
59 | public function boot(): void
60 | {
61 | FilamentAsset::register([
62 | Css::make('filament-docs', __DIR__ . '/../publish/public/css/filament-docs.css'),
63 | ], package: 'tomatophp/filament-docs');
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomatophp/filament-docs/c584390e2dd98b07de03115860f61ff3c4f30cee/src/Models/.gitkeep
--------------------------------------------------------------------------------
/src/Models/Document.php:
--------------------------------------------------------------------------------
1 | 'boolean',
35 | ];
36 |
37 | public function model()
38 | {
39 | return $this->morphTo();
40 | }
41 |
42 | public function documentTemplate(): BelongsTo
43 | {
44 | return $this->belongsTo(\TomatoPHP\FilamentDocs\Models\DocumentTemplate::class, 'document_template_id');
45 | }
46 |
47 | public function team(): BelongsTo
48 | {
49 | return $this->belongsTo(config('filament-docs.team_model'), 'team_id');
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Models/DocumentTemplate.php:
--------------------------------------------------------------------------------
1 | 'boolean',
34 | ];
35 |
36 | public function team(): BelongsTo
37 | {
38 | return $this->belongsTo(config('filament-docs.team_model'), 'team_id');
39 | }
40 |
41 | public function documentTemplateVars(): HasMany
42 | {
43 | return $this->hasMany(DocumentTemplateVar::class);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Models/DocumentTemplateVar.php:
--------------------------------------------------------------------------------
1 | 'json',
30 | ];
31 |
32 | public function documentTemplate(): BelongsTo
33 | {
34 | return $this->belongsTo(\TomatoPHP\FilamentDocs\Models\DocumentTemplate::class);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Services/Contracts/DocsVar.php:
--------------------------------------------------------------------------------
1 | key($key);
20 | }
21 |
22 | /**
23 | * @return $this
24 | */
25 | public function key(string $key): static
26 | {
27 | $this->key = $key;
28 |
29 | return $this;
30 | }
31 |
32 | /**
33 | * @return $this
34 | */
35 | public function label(string $label): static
36 | {
37 | $this->label = $label;
38 |
39 | return $this;
40 | }
41 |
42 | /**
43 | * @return $this
44 | */
45 | public function model(string $model): static
46 | {
47 | $this->model = $model;
48 |
49 | return $this;
50 | }
51 |
52 | /**
53 | * @return $this
54 | */
55 | public function column(string $column): static
56 | {
57 | $this->column = $column;
58 |
59 | return $this;
60 | }
61 |
62 | /**
63 | * @return $this
64 | */
65 | public function value(string | \Closure | null $value): static
66 | {
67 | $this->value = $value;
68 |
69 | return $this;
70 | }
71 |
72 | public function toArray(): array
73 | {
74 | return [
75 | 'key' => $this->key,
76 | 'label' => $this->label,
77 | 'model' => $this->model,
78 | 'column' => $this->column,
79 | 'value' => $this->value,
80 | ];
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/Services/FilamentDocsServices.php:
--------------------------------------------------------------------------------
1 | register($item);
28 | }
29 | } else {
30 | $this->vars[] = $var;
31 | }
32 | }
33 |
34 | public function load(): Collection
35 | {
36 | return collect($this->vars);
37 | }
38 |
39 | public function create(Model $model): void
40 | {
41 | foreach ($this->load()->where('value', null) as $item) {
42 | if (str($model->body)->contains($item->key)) {
43 | $exists = $model->documentTemplateVars()->where('var', $item->key)->first();
44 | if (! $exists) {
45 | $model->documentTemplateVars()->create([
46 | 'var' => $item->key,
47 | 'model' => $item->model,
48 | 'value' => $item->column,
49 | ]);
50 | }
51 | }
52 | }
53 | }
54 |
55 | public function body(int $template, ?array $vars = null): string
56 | {
57 | $templateBody = '';
58 | $getDocumentTemplate = DocumentTemplate::query()->find($template);
59 | if ($getDocumentTemplate) {
60 | $templateBody = $getDocumentTemplate->body;
61 | if (! empty($vars)) {
62 | foreach ($vars as $var) {
63 | if (is_array($var) && isset($var['var'])) {
64 | $templateBody = str($templateBody)->replace($var['var'], is_array($var['model']::query()->find($var['value'])?->toArray()[$var['key']]) ? $var['model']::query()->find($var['value'])?->toArray()[$var['key']][app()->getLocale()] : $var['model']::query()->find($var['value'])?->toArray()[$var['key']])->toString();
65 | }
66 | }
67 | }
68 |
69 | Carbon::setLocale(app()->getLocale());
70 | $templateBody = str($templateBody)
71 | ->replace('$DAY', Carbon::now()->translatedFormat(config('filament-docs.dates.day')))
72 | ->replace('$DATE', Carbon::now()->translatedFormat(config('filament-docs.dates.date')))
73 | ->replace('$TIME', Carbon::now()->translatedFormat(config('filament-docs.dates.time')))
74 | ->replace('$UUID', Str::uuid())
75 | ->replace('$RANDOM', Str::random(6))
76 | ->toString();
77 |
78 | $fixedVars = array_merge(FilamentDocs::load()->where('value', '!=', null)->toArray(), $vars ?? []);
79 | foreach ($fixedVars as $item) {
80 | if (! is_array($item)) {
81 | $value = '';
82 | if ($item->value instanceof \Closure) {
83 | $value = call_user_func($item->value);
84 | } else {
85 | $value = $item->value;
86 | }
87 | $templateBody = str($templateBody)->replace($item->key, $value)->toString();
88 | }
89 | }
90 | }
91 |
92 | return $templateBody;
93 | }
94 |
95 | public function header(string $header)
96 | {
97 | $this->header = $header;
98 | }
99 |
100 | public function getHeader()
101 | {
102 | if ($this->header) {
103 | return view($this->header)->render();
104 | }
105 | }
106 |
107 | public function footer(string $footer)
108 | {
109 | $this->footer = $footer;
110 | }
111 |
112 | public function getFooter()
113 | {
114 | if ($this->footer) {
115 | return view($this->footer)->render();
116 | }
117 | }
118 |
119 | public function css(string $css)
120 | {
121 | $this->css = $css;
122 | }
123 |
124 | public function getCss()
125 | {
126 | if ($this->css) {
127 | return view($this->css)->render();
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/Traits/InteractsWithDocs.php:
--------------------------------------------------------------------------------
1 | morphMany(\TomatoPHP\FilamentDocs\Models\Document::class, 'model');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/testbench.yaml:
--------------------------------------------------------------------------------
1 | providers:
2 | - BladeUI\Icons\BladeIconsServiceProvider
3 | - BladeUI\Heroicons\BladeHeroiconsServiceProvider
4 | - Filament\Actions\ActionsServiceProvider
5 | - Filament\FilamentServiceProvider
6 | - Filament\Forms\FormsServiceProvider
7 | - Filament\Infolists\InfolistsServiceProvider
8 | - Filament\Notifications\NotificationsServiceProvider
9 | - Filament\Support\SupportServiceProvider
10 | - Filament\Tables\TablesServiceProvider
11 | - Filament\Widgets\WidgetsServiceProvider
12 | - RyanChandler\BladeCaptureDirective\BladeCaptureDirectiveServiceProvider
13 | - TomatoPHP\FilamentIcons\FilamentIconsServiceProvider
14 | - FilamentTiptapEditor\FilamentTiptapEditorServiceProvider
15 | - TomatoPHP\FilamentDocs\FilamentDocsServiceProvider
16 | - TomatoPHP\FilamentDocs\Tests\AdminPanelProvider
17 | workbench:
18 | welcome: true
19 | install: true
20 | start: /
21 | guard: testing
22 | discovers:
23 | web: true
24 | api: false
25 | commands: false
26 | views: true
27 |
--------------------------------------------------------------------------------
/tests/Pest.php:
--------------------------------------------------------------------------------
1 | in(__DIR__);
6 |
--------------------------------------------------------------------------------
/tests/database/database.sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomatophp/filament-docs/c584390e2dd98b07de03115860f61ff3c4f30cee/tests/database/database.sqlite
--------------------------------------------------------------------------------
/tests/database/factories/DocumentFactory.php:
--------------------------------------------------------------------------------
1 | $this->faker->word(),
16 | 'body' => $this->faker->text(),
17 | 'is_send' => $this->faker->boolean(),
18 | 'model_id' => $this->faker->uuid(),
19 | 'model_type' => $this->faker->word(),
20 | ];
21 | }
22 |
23 | public function withId($id)
24 | {
25 | return $this->state([
26 | 'document_template_id' => $id,
27 | ]);
28 | }
29 |
30 | public function withTeam($id)
31 | {
32 | return $this->state([
33 | 'team_id' => $id,
34 | ]);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/database/factories/DocumentTemplateFactory.php:
--------------------------------------------------------------------------------
1 | $this->faker->word(),
16 | 'body' => $this->faker->text(),
17 | 'is_active' => $this->faker->boolean(),
18 | 'icon' => 'heroicon-o-document-text',
19 | 'color' => $this->faker->word(),
20 | ];
21 | }
22 |
23 | public function withTeam($id)
24 | {
25 | return $this->state([
26 | 'team_id' => $id,
27 | ]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/database/factories/DocumentTemplateVarFactory.php:
--------------------------------------------------------------------------------
1 | $this->faker->word(),
16 | 'model' => $this->faker->word(),
17 | 'value' => $this->faker->text(),
18 | ];
19 | }
20 |
21 | public function withId($id)
22 | {
23 | return $this->state([
24 | 'document_template_id' => $id,
25 | ]);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/database/factories/UserFactory.php:
--------------------------------------------------------------------------------
1 | $this->faker->name(),
17 | 'email' => $this->faker->unique()->safeEmail(),
18 | 'email_verified_at' => now(),
19 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
20 | 'remember_token' => Str::random(10),
21 | ];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/src/AdminPanelProvider.php:
--------------------------------------------------------------------------------
1 | default()
26 | ->id('admin')
27 | ->path('admin')
28 | ->login()
29 | ->pages([
30 | Pages\Dashboard::class,
31 | ])
32 | ->plugin(
33 | FilamentDocsPlugin::make()
34 | )
35 | ->middleware([
36 | EncryptCookies::class,
37 | AddQueuedCookiesToResponse::class,
38 | StartSession::class,
39 | AuthenticateSession::class,
40 | ShareErrorsFromSession::class,
41 | VerifyCsrfToken::class,
42 | SubstituteBindings::class,
43 | DisableBladeIconComponents::class,
44 | DispatchServingFilamentEvent::class,
45 | ])
46 | ->authMiddleware([
47 | Authenticate::class,
48 | ]);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/src/DebugTest.php:
--------------------------------------------------------------------------------
1 | each->not->toBeUsed();
5 | });
6 |
--------------------------------------------------------------------------------
/tests/src/DocumentResourceTest.php:
--------------------------------------------------------------------------------
1 | create());
19 | });
20 |
21 | it('can render document resource', function () {
22 | get(DocumentResource::getUrl())->assertSuccessful();
23 | });
24 |
25 | it('can list documents', function () {
26 | Document::query()->delete();
27 | $template = DocumentTemplate::factory()->create();
28 | $documents = Document::factory()->count(10)->withId($template->id)->create();
29 |
30 | livewire(Pages\ListDocuments::class)
31 | ->loadTable()
32 | ->assertCanSeeTableRecords($documents)
33 | ->assertCountTableRecords(10);
34 | });
35 |
36 | it('can render document type/for/key column in table', function () {
37 | $template = DocumentTemplate::factory()->create();
38 | $documents = Document::factory()->count(10)->withId($template->id)->create();
39 |
40 | livewire(Pages\ListDocuments::class)
41 | ->loadTable()
42 | ->assertCanRenderTableColumn('id')
43 | ->assertCanRenderTableColumn('ref')
44 | ->assertCanRenderTableColumn('is_send')
45 | ->assertCanRenderTableColumn('documentTemplate.name');
46 | });
47 |
48 | it('can render document list page', function () {
49 | livewire(Pages\ListDocuments::class)->assertSuccessful();
50 | });
51 |
52 | it('can render view document page', function () {
53 | $template = DocumentTemplate::factory()->create();
54 |
55 | livewire(Pages\ListDocuments::class, [
56 | 'record' => Document::factory()->withId($template->id)->create(),
57 | ])
58 | ->mountAction('view')
59 | ->assertSuccessful();
60 | });
61 |
62 | it('can render document create page', function () {
63 | livewire(Pages\ListDocuments::class)
64 | ->mountAction('create')
65 | ->assertSuccessful();
66 | });
67 |
68 | it('can create new document', function () {
69 | $template = DocumentTemplate::factory()->create();
70 | $newData = Document::factory()->withId($template->id)->make();
71 |
72 | livewire(Pages\CreateDocument::class)
73 | ->fillForm([
74 | 'document_template_id' => $template->id,
75 | 'body' => [],
76 | 'ref' => $newData->ref,
77 | ])
78 | ->call('create')
79 | ->assertHasNoFormErrors();
80 |
81 | assertDatabaseHas(Document::class, [
82 | 'body' => $template->body,
83 | 'ref' => $newData->ref,
84 | ]);
85 | });
86 |
87 | it('can validate document input', function () {
88 | livewire(Pages\CreateDocument::class)
89 | ->fillForm([
90 | 'document_template_id' => null,
91 | 'body' => null,
92 | 'ref' => null,
93 | 'is_send' => null,
94 | ])
95 | ->call('create')
96 | ->assertHasFormErrors([
97 | 'document_template_id' => 'required',
98 | ]);
99 | });
100 |
101 | it('can render document edit action', function () {
102 | $template = DocumentTemplate::factory()->create();
103 |
104 | livewire(Pages\ListDocuments::class, [
105 | 'record' => Document::factory()->withId($template->id)->create(),
106 | ])
107 | ->mountAction('edit')
108 | ->assertSuccessful();
109 | });
110 |
111 | it('can render document edit page', function () {
112 | $template = DocumentTemplate::factory()->create();
113 | get(DocumentResource::getUrl('edit', [
114 | 'record' => Document::factory()->withId($template->id)->create(),
115 | ]))->assertSuccessful();
116 | });
117 |
118 | it('can retrieve document data', function () {
119 | $template = DocumentTemplate::factory()->create();
120 | $document = Document::factory()->withId($template->id)->create();
121 |
122 | livewire(Pages\EditDocument::class, [
123 | 'record' => $document->getRouteKey(),
124 | ])
125 | ->assertFormSet([
126 | 'document_template_id' => $document->document_template_id,
127 | 'ref' => $document->ref,
128 | ]);
129 | });
130 |
131 | it('can validate edit document input', function () {
132 | $template = DocumentTemplate::factory()->create();
133 | $document = Document::factory()->withId($template->id)->create();
134 |
135 | livewire(Pages\EditDocument::class, [
136 | 'record' => $document->getRouteKey(),
137 | ])
138 | ->fillForm([
139 | 'document_template_id' => null,
140 | 'body' => null,
141 | 'ref' => null,
142 | 'is_send' => null,
143 | ])
144 | ->call('save')
145 | ->assertHasFormErrors([
146 | 'document_template_id' => 'required',
147 | ]);
148 | });
149 |
150 | it('can save document data', function () {
151 | $template = DocumentTemplate::factory()->create();
152 | $document = Document::factory()->withId($template->id)->create();
153 | $newData = Document::factory()->withId($template->id)->make();
154 |
155 | livewire(Pages\EditDocument::class, [
156 | 'record' => $document->getRouteKey(),
157 | ])
158 | ->fillForm([
159 | 'document_template_id' => $template->id,
160 | 'body' => [],
161 | 'ref' => $newData->ref,
162 | ])
163 | ->call('save')
164 | ->assertHasNoFormErrors();
165 |
166 | expect($document->refresh())
167 | ->document_template_id->toBe($newData->document_template_id);
168 | });
169 |
170 | it('can delete document', function () {
171 | $template = DocumentTemplate::factory()->create();
172 | $document = Document::factory()->withId($template->id)->create();
173 |
174 | livewire(Pages\ListDocuments::class)
175 | ->callTableAction('delete', $document)
176 | ->assertHasNoTableActionErrors();
177 |
178 | assertModelMissing($document);
179 | });
180 |
--------------------------------------------------------------------------------
/tests/src/Models/Document.php:
--------------------------------------------------------------------------------
1 | 'boolean',
39 | ];
40 |
41 | public function model()
42 | {
43 | return $this->morphTo();
44 | }
45 |
46 | public function documentTemplate(): BelongsTo
47 | {
48 | return $this->belongsTo(\TomatoPHP\FilamentDocs\Models\DocumentTemplate::class, 'document_template_id');
49 | }
50 |
51 | public function team(): BelongsTo
52 | {
53 | return $this->belongsTo(config('filament-docs.team_model'), 'team_id');
54 | }
55 |
56 | protected static function newFactory(): DocumentFactory
57 | {
58 | return DocumentFactory::new();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tests/src/Models/DocumentTemplate.php:
--------------------------------------------------------------------------------
1 | 'boolean',
37 | ];
38 |
39 | public function team(): BelongsTo
40 | {
41 | return $this->belongsTo(config('filament-docs.team_model'), 'team_id');
42 | }
43 |
44 | public function documentTemplateVars(): HasMany
45 | {
46 | return $this->hasMany(DocumentTemplateVar::class);
47 | }
48 |
49 | protected static function newFactory(): DocumentTemplateFactory
50 | {
51 | return DocumentTemplateFactory::new();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/src/Models/DocumentTemplateVar.php:
--------------------------------------------------------------------------------
1 | 'json',
33 | ];
34 |
35 | public function documentTemplate(): BelongsTo
36 | {
37 | return $this->belongsTo(\TomatoPHP\FilamentDocs\Models\DocumentTemplate::class);
38 | }
39 |
40 | protected static function newFactory(): DocumentTemplateVarFactory
41 | {
42 | return DocumentTemplateVarFactory::new();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/src/Models/User.php:
--------------------------------------------------------------------------------
1 | plugins([
10 | FilamentDocsPlugin::make(),
11 | ]);
12 |
13 | expect($panel->getPlugin('filament-docs'))
14 | ->not()
15 | ->toThrow(Exception::class);
16 | });
17 |
--------------------------------------------------------------------------------
/tests/src/TestCase.php:
--------------------------------------------------------------------------------
1 | label('User ID')
41 | ->model(User::class)
42 | ->column('name'),
43 | ]);
44 | }
45 |
46 | protected function getPackageProviders($app): array
47 | {
48 | return [
49 | ActionsServiceProvider::class,
50 | BladeCaptureDirectiveServiceProvider::class,
51 | BladeHeroiconsServiceProvider::class,
52 | BladeIconsServiceProvider::class,
53 | FilamentServiceProvider::class,
54 | FormsServiceProvider::class,
55 | InfolistsServiceProvider::class,
56 | LivewireServiceProvider::class,
57 | NotificationsServiceProvider::class,
58 | SupportServiceProvider::class,
59 | TablesServiceProvider::class,
60 | WidgetsServiceProvider::class,
61 | FilamentIconsServiceProvider::class,
62 | FilamentTiptapEditorServiceProvider::class,
63 | FilamentDocsServiceProvider::class,
64 | AdminPanelProvider::class,
65 | ];
66 | }
67 |
68 | protected function defineDatabaseMigrations(): void
69 | {
70 | $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations');
71 | }
72 |
73 | public function getEnvironmentSetUp($app): void
74 | {
75 | $app['config']->set('filament-users.model', User::class);
76 | $app['config']->set('database.default', 'testing');
77 | $app['config']->set('filament-icons.cache', false);
78 |
79 | $app['config']->set('view.paths', [
80 | ...$app['config']->get('view.paths'),
81 | __DIR__ . '/../resources/views',
82 | ]);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------