Skip to content

Commit e530e88

Browse files
committed
Clipboard in Core
1 parent d78297e commit e530e88

File tree

5 files changed

+163
-123
lines changed

5 files changed

+163
-123
lines changed

docs/Frontend/IDEA.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ or override only specific sections:
162162

163163
The core of the frontend system, integrating entities, themes, and routes.
164164

165+
### Localization
166+
167+
Localization is a core feature of Moox. It is implemented in the `Localization` package. To help implement automatic routing, we might use https://github.com/mcamara/laravel-localization.
168+
165169
### Performance Optimization
166170

167171
Initially, Moox Frontend will use standard Laravel routes. Future optimizations may include cached permalinks (`Cache::put('moox_slugs', $array)`) for high-speed lookups, JSON-based caching for ultra-fast retrieval, or static route file generation for extreme performance.

docs/Website/IDEA.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,93 @@ A temporary list of packages to fill in the docs (75 packages):
121121
- deploy@moox.org
122122
- admin@moox.org
123123
- alf@moox.org
124+
125+
### Homepage
126+
127+
Use ready made packages and install a CMS in minutes. Multilingual, SEO friendly, extremely fast, simple to extend with a lot of Moox packages or other Filament and Laravel packages.
128+
129+
-- Video Install Command --
130+
131+
- `php artisan moox:install --demo --preset=cms`
132+
- Explain preset, packages while installing
133+
- `--demo` is seeded including admin user
134+
- `--preset=cms` is fast, preset for a CMS
135+
- direct links to frontend and admin
136+
- fast login as admin prefilled user and pass
137+
- show the backend, publish a page, show the frontend
138+
139+
Or build your own CMS or any other application you want. Use the Build Command to create own packages with powerful Moox Entities, Taxonomies, Modules and Themes.
140+
141+
-- Video Build Command --
142+
143+
- `php artisan moox:build --demo`
144+
- `--demo` is seeded
145+
- direct links to files (Code Editor)
146+
- direct links to frontend and admin
147+
- show the backend, publish a ???, show the frontend
148+
- click to open resource, model, migration, factory and frontend
149+
- shoot a prompt to add and remove some fields
150+
151+
Or simply pick just one or some of our packages. Moox is extremely modular and can be used in any Filament project.
152+
153+
-- Most Popular Packages --
154+
155+
Help us grow Moox
156+
157+
- Tell -> https://moox.org/tell
158+
- Star us -> https://github.com/mooxphp/moox
159+
- Sponsor us -> https://github.com/sponsors/mooxphp
160+
- Contribute code -> https://moox.org/docs/contribute
161+
- Translate to a language -> https://moox.org/docs/translate
162+
163+
### Tell
164+
165+
- `Tell` a Friend - send a notification or use social media.
166+
- Show & `Tell` - what have you built with Moox? Screenshot or Link.
167+
- `Tell` us more - what do you think about Moox? What do you miss?
168+
169+
Basically three forms 1) Social Media 2) On Moox.org 3) Private Message
170+
171+
### License and Copyright
172+
173+
Moox is an Open Source project with additional commercial offerings. On this page, we want to explain all used licenses and the copyrights of the Moox project.
174+
175+
#### MIT License
176+
177+
All freely available Moox packages are licensed under the `MIT License`, except Themes and the Moox.org website.
178+
179+
- You are free to:
180+
181+
- Use the software for any purpose
182+
- Modify the software
183+
- Distribute the software
184+
- Sublicense the software
185+
- Use the software privately or commercially
186+
187+
- Under the following terms:
188+
189+
- Include the original copyright notice and license text in any copy or substantial portion of the software
190+
191+
See [MIT License](https://opensource.org/licenses/MIT) for details.
192+
193+
### CC-BY-SA 4.0
194+
195+
Moox Themes, the Moox.org website and the Moox Documentation are licensed under `CC-BY-SA 4.0`.
196+
197+
- You are free to:
198+
199+
- Share — copy and redistribute the material in any medium or format
200+
- Adapt — remix, transform, and build upon the material for any purpose, even commercially.
201+
202+
- Under the following terms:
203+
204+
- Attribution — You must give appropriate credit, please leave our footer link intact.
205+
- ShareAlike — If build upon the theme, you must distribute that under CC-BY-SA 4.0, too.
206+
207+
See [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) for details.
208+
209+
### Pay to Open
210+
211+
Moox Pro packages and themes are licensed under the `Pay to Open License`, our Open Source friendly commercial license.
212+
213+
See [Pay to Open](https://moox.org/pay-to-open) for details.

docs/_devlog/Alf.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- [ ] static-locales:280 - GET https://moox.test/storage/%7B%221%22:%7B%22file_name%22:%22Alf-Hamburg-Profil-High.jpg%22,%22title%22:%22Alf-Hamburg-Profil-High%22,%22description%22:null,%22internal_note%22:null,%22alt%22:%22Alf-Hamburg-Profil-High%22%7D%7D 404 (Not Found)
66
- [ ] remove debug code
7-
- [ ] remove boilerplate code taxonomy
7+
- [ ] remove boilerplate code taxonomy, finish core implementation
88
- [ ] Implement Item Entity
99
- [x] Item Model
1010
- [x] Item migration
@@ -104,6 +104,7 @@
104104
- [ ] moox:scaffold - change fields of an entity by a config or JSON
105105
- [ ] moox:release or UI - auto release, see notes
106106
- [ ] We need to see if we use moox.json, DB or both.
107+
- [ ] Website: add https://creativecommons.org/licenses/by-sa/4.0/ for our graphics, assets, docs, website and themes.
107108

108109
## Relations
109110

@@ -249,10 +250,6 @@ The result is collected into a json file:
249250
- press
250251
- ...
251252

252-
## Localization
253-
254-
https://github.com/mcamara/laravel-localization
255-
256253
```
257254
https://www.example.com:8080/some/page?search=apple#section2
258255
\______/ \___________/ \__/\______/ \_________/ \_________/
@@ -326,7 +323,7 @@ https://www.example.com:8080/some/page?search=apple#section2
326323
{slug} // the current item's slug
327324
{item.slug} // the related item's slug
328325
{year}/{month}/{day} // date related
329-
{parent.slug} // the parent item's slug
326+
{parent.slug} // the parent item's slugxx
330327
{category.slug} // refers to a category's slug
331328
{post.slug} // refers to a post's slug
332329

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Moox\Core\Forms\Components;
4+
5+
use Filament\Forms\Components\Actions\Action;
6+
use Filament\Forms\Components\TextInput;
7+
8+
class CopyableField extends TextInput
9+
{
10+
protected function setUp(): void
11+
{
12+
parent::setUp();
13+
14+
$this->disabled()
15+
->suffix('')
16+
->live()
17+
->suffixAction(
18+
Action::make('copy')
19+
->icon('heroicon-s-clipboard')
20+
->action(function ($livewire, $state) {
21+
$livewire->dispatch('copy-to-clipboard-'.$this->getName(), text: $state);
22+
})
23+
)
24+
->extraAttributes([
25+
'x-data' => '{
26+
copyToClipboard(text) {
27+
const textArea = document.createElement("textarea");
28+
textArea.value = text;
29+
textArea.style.position = "fixed";
30+
textArea.style.opacity = "0";
31+
document.body.appendChild(textArea);
32+
textArea.select();
33+
try {
34+
document.execCommand("copy");
35+
$tooltip("Copied to clipboard", { timeout: 1500 });
36+
} catch (err) {
37+
$tooltip("Failed to copy", { timeout: 1500 });
38+
}
39+
document.body.removeChild(textArea);
40+
}
41+
}',
42+
'x-on:copy-to-clipboard-'.$this->getName().'.window' => 'copyToClipboard($event.detail.text)',
43+
]);
44+
}
45+
46+
public static function make(string $name): static
47+
{
48+
$component = app(static::class, ['name' => $name]);
49+
$component->configure();
50+
51+
return $component;
52+
}
53+
54+
public function defaultValue(string|\Closure $value): static
55+
{
56+
return $this->default($value);
57+
}
58+
}

packages/item/src/Moox/Entities/Items/Item/ItemResource.php

Lines changed: 8 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use Filament\Tables\Table;
2626
use Illuminate\Database\Eloquent\Builder;
2727
use Moox\Core\Entities\Items\Item\BaseItemResource;
28+
use Moox\Core\Forms\Components\CopyableField;
2829
use Moox\Core\Traits\Taxonomy\HasResourceTaxonomy;
2930
use Moox\Item\Models\Item;
3031

@@ -119,7 +120,7 @@ public static function form(Form $form): Form
119120
->placeholder(__('core::core.status'))
120121
->options(['Probably' => 'Probably', 'Never' => 'Never', 'Done' => 'Done', 'Maybe' => 'Maybe']),
121122
]),
122-
Section::make('Taxonomies')
123+
Section::make('')
123124
->schema($taxonomyFields),
124125
Section::make('')
125126
->schema([
@@ -133,125 +134,15 @@ public static function form(Form $form): Form
133134
]),
134135
Section::make('')
135136
->schema([
136-
TextInput::make('id')
137+
CopyableField::make('id')
137138
->label('ID')
138-
->default(fn ($record): string => $record->id ?? '')
139-
->disabled()
140-
->suffixAction(
141-
\Filament\Forms\Components\Actions\Action::make('copyId')
142-
->icon('heroicon-s-clipboard')
143-
->action(function ($livewire, $state) {
144-
$livewire->dispatch('copy-to-clipboard-id', text: $state);
145-
})
146-
)
147-
->extraAttributes([
148-
'x-data' => '{
149-
copyToClipboard(text) {
150-
if (navigator.clipboard && navigator.clipboard.writeText) {
151-
navigator.clipboard.writeText(text).then(() => {
152-
$tooltip("ID copied to clipboard", { timeout: 1500 });
153-
}).catch(() => {
154-
$tooltip("Failed to copy", { timeout: 1500 });
155-
});
156-
} else {
157-
const textArea = document.createElement("textarea");
158-
textArea.value = text;
159-
textArea.style.position = "fixed";
160-
textArea.style.opacity = "0";
161-
document.body.appendChild(textArea);
162-
textArea.select();
163-
try {
164-
document.execCommand("copy");
165-
$tooltip("ID copied to clipboard", { timeout: 1500 });
166-
} catch (err) {
167-
$tooltip("Failed to copy", { timeout: 1500 });
168-
}
169-
document.body.removeChild(textArea);
170-
}
171-
}
172-
}',
173-
'x-on:copy-to-clipboard-id.window' => 'copyToClipboard($event.detail.text)',
174-
]),
175-
TextInput::make('uuid')
139+
->defaultValue(fn ($record): string => $record->id ?? ''),
140+
CopyableField::make('uuid')
176141
->label('UUID')
177-
->default(fn ($record): string => $record->uuid ?? '')
178-
->disabled()
179-
->suffixAction(
180-
\Filament\Forms\Components\Actions\Action::make('copyUuid')
181-
->icon('heroicon-s-clipboard')
182-
->action(function ($livewire, $state) {
183-
$livewire->dispatch('copy-to-clipboard-uuid', text: $state);
184-
})
185-
)
186-
->extraAttributes([
187-
'class' => 'font-mono',
188-
'x-data' => '{
189-
copyToClipboard(text) {
190-
if (navigator.clipboard && navigator.clipboard.writeText) {
191-
navigator.clipboard.writeText(text).then(() => {
192-
$tooltip("UUID copied to clipboard", { timeout: 1500 });
193-
}).catch(() => {
194-
$tooltip("Failed to copy", { timeout: 1500 });
195-
});
196-
} else {
197-
const textArea = document.createElement("textarea");
198-
textArea.value = text;
199-
textArea.style.position = "fixed";
200-
textArea.style.opacity = "0";
201-
document.body.appendChild(textArea);
202-
textArea.select();
203-
try {
204-
document.execCommand("copy");
205-
$tooltip("UUID copied to clipboard", { timeout: 1500 });
206-
} catch (err) {
207-
$tooltip("Failed to copy", { timeout: 1500 });
208-
}
209-
document.body.removeChild(textArea);
210-
}
211-
}
212-
}',
213-
'x-on:copy-to-clipboard-uuid.window' => 'copyToClipboard($event.detail.text)',
214-
]),
215-
TextInput::make('ulid')
142+
->defaultValue(fn ($record): string => $record->uuid ?? ''),
143+
CopyableField::make('ulid')
216144
->label('ULID')
217-
->default(fn ($record): string => $record->ulid ?? '')
218-
->disabled()
219-
->suffixAction(
220-
\Filament\Forms\Components\Actions\Action::make('copyUlid')
221-
->icon('heroicon-s-clipboard')
222-
->action(function ($livewire, $state) {
223-
$livewire->dispatch('copy-to-clipboard-ulid', text: $state);
224-
})
225-
)
226-
->extraAttributes([
227-
'class' => 'font-mono',
228-
'x-data' => '{
229-
copyToClipboard(text) {
230-
if (navigator.clipboard && navigator.clipboard.writeText) {
231-
navigator.clipboard.writeText(text).then(() => {
232-
$tooltip("ULID copied to clipboard", { timeout: 1500 });
233-
}).catch(() => {
234-
$tooltip("Failed to copy", { timeout: 1500 });
235-
});
236-
} else {
237-
const textArea = document.createElement("textarea");
238-
textArea.value = text;
239-
textArea.style.position = "fixed";
240-
textArea.style.opacity = "0";
241-
document.body.appendChild(textArea);
242-
textArea.select();
243-
try {
244-
document.execCommand("copy");
245-
$tooltip("ULID copied to clipboard", { timeout: 1500 });
246-
} catch (err) {
247-
$tooltip("Failed to copy", { timeout: 1500 });
248-
}
249-
document.body.removeChild(textArea);
250-
}
251-
}
252-
}',
253-
'x-on:copy-to-clipboard-ulid.window' => 'copyToClipboard($event.detail.text)',
254-
]),
145+
->defaultValue(fn ($record): string => $record->ulid ?? ''),
255146

256147
Section::make('')
257148
->schema([

0 commit comments

Comments
 (0)