update
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SyncPoliFromJson extends Command
|
||||
{
|
||||
protected $signature = 'poli:sync-json {--path= : Path file JSON poli, default database/seeders/data/poli.json} {--dry-run : Cek data tanpa menulis ke database}';
|
||||
|
||||
protected $description = 'Update atau create data poli dari file JSON berdasarkan id tanpa truncate.';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$path = $this->resolvePath($this->option('path') ?: database_path('seeders/data/poli.json'));
|
||||
$data = $this->readJson($path);
|
||||
|
||||
$updated = 0;
|
||||
$created = 0;
|
||||
$unchanged = 0;
|
||||
|
||||
DB::transaction(function () use ($data, &$updated, &$created, &$unchanged) {
|
||||
foreach ($data as $row) {
|
||||
$id = (int) $row['id'];
|
||||
$payload = [
|
||||
'poli' => $row['poli'] ?? null,
|
||||
'subpoli' => $row['subpoli'] ?? null,
|
||||
'subsubpoli' => $row['subsubpoli'] ?? null,
|
||||
'modaliti' => $row['modaliti'] ?? null,
|
||||
'kelompok' => $row['kelompok'] ?? null,
|
||||
'modaliti2' => isset($row['modaliti2']) ? (string) $row['modaliti2'] : null,
|
||||
'created_at' => $row['created_at'] ?? now(),
|
||||
'updated_at' => $row['updated_at'] ?? now(),
|
||||
];
|
||||
|
||||
$existing = DB::table('poli')->where('id', $id)->first();
|
||||
|
||||
if ($existing === null) {
|
||||
$created++;
|
||||
|
||||
if (!$this->option('dry-run')) {
|
||||
DB::table('poli')->insert(array_merge(['id' => $id], $payload));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isSameRow($existing, $payload)) {
|
||||
$unchanged++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$updated++;
|
||||
|
||||
if (!$this->option('dry-run')) {
|
||||
DB::table('poli')->where('id', $id)->update($payload);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$mode = $this->option('dry-run') ? 'DRY RUN' : 'DONE';
|
||||
$this->info("{$mode}: {$created} created, {$updated} updated, {$unchanged} unchanged.");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function resolvePath(string $path): string
|
||||
{
|
||||
if ($path !== '' && $path[0] === '/') {
|
||||
return $path;
|
||||
}
|
||||
|
||||
return base_path($path);
|
||||
}
|
||||
|
||||
private function readJson(string $path): array
|
||||
{
|
||||
if (!is_file($path)) {
|
||||
throw new \RuntimeException("File JSON poli tidak ditemukan: {$path}");
|
||||
}
|
||||
|
||||
$json = file_get_contents($path);
|
||||
|
||||
if ($json === false) {
|
||||
throw new \RuntimeException("Gagal membaca file JSON poli: {$path}");
|
||||
}
|
||||
|
||||
$data = json_decode($json, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
throw new \RuntimeException("Format JSON poli tidak valid: {$path}");
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
|
||||
foreach ($data as $index => $row) {
|
||||
if (!is_array($row) || !isset($row['id'])) {
|
||||
throw new \RuntimeException('Data poli baris '.($index + 1).' tidak memiliki id.');
|
||||
}
|
||||
|
||||
$id = (int) $row['id'];
|
||||
|
||||
if (isset($ids[$id])) {
|
||||
throw new \RuntimeException("Duplikasi id poli pada JSON: {$id}");
|
||||
}
|
||||
|
||||
$ids[$id] = true;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function isSameRow(object $existing, array $payload): bool
|
||||
{
|
||||
foreach ($payload as $key => $value) {
|
||||
if ((string) ($existing->{$key} ?? '') !== (string) ($value ?? '')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -846,7 +846,7 @@ class DokterController extends Controller
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (str_starts_with($normalized, 'data bd di terima')) {
|
||||
if (str_starts_with($normalized, 'data bd di terima') || str_starts_with($normalized, 'data bd diterima')) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -858,26 +858,31 @@ class DokterController extends Controller
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (str_starts_with($normalized, 'otor maldi (un verified)')) {
|
||||
if (str_starts_with($normalized, 'data malditof diterima') || str_starts_with($normalized, 'data malditof di terima')) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (str_starts_with($normalized, 'preliminary results')) {
|
||||
if (str_starts_with($normalized, 'otor maldi (un verified)')) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (str_starts_with($normalized, 'data vitek di terima')) {
|
||||
if (str_starts_with($normalized, 'preliminary results')) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
if (str_starts_with($normalized, 'expertise saved (un verified)')) {
|
||||
if (str_starts_with($normalized, 'data vitek di terima') || str_starts_with($normalized, 'data vitek diterima')) {
|
||||
return 9;
|
||||
}
|
||||
|
||||
if (in_array($normalized, ['expertise', 'selesai', 'final result'], true)) {
|
||||
if (str_starts_with($normalized, 'id/ast pending result') || $normalized === 'sedang id+ast') {
|
||||
return 10;
|
||||
}
|
||||
|
||||
if (str_starts_with($normalized, 'expertise saved (un verified)')
|
||||
|| in_array($normalized, ['expertise', 'selesai', 'final result'], true)) {
|
||||
return 11;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
protected function normalizePeriksaStatus($status): string {
|
||||
@@ -897,10 +902,6 @@ class DokterController extends Controller
|
||||
'menunggu kultur yg lain',
|
||||
'menunggu kultur yang lain',
|
||||
'proses identifikasi dan uji kepekaan',
|
||||
'id/ast pending result',
|
||||
'data malditof diterima',
|
||||
'data malditof di terima',
|
||||
'sedang id+ast',
|
||||
'sedang malditof',
|
||||
'pertumbuhan primer',
|
||||
];
|
||||
|
||||
@@ -8,11 +8,14 @@ class Poli extends Model
|
||||
{
|
||||
protected $table = "poli";
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'poli',
|
||||
'subpoli',
|
||||
'subsubpoli',
|
||||
'modaliti',
|
||||
'kelompok',
|
||||
'modaliti2',
|
||||
'modaliti',
|
||||
'kelompok',
|
||||
'modaliti2',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (!Schema::hasTable('poli')) {
|
||||
Schema::create('poli', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('poli', 250)->nullable();
|
||||
$table->string('subpoli', 250)->nullable();
|
||||
$table->string('subsubpoli', 250)->nullable();
|
||||
$table->string('modaliti', 150)->nullable();
|
||||
$table->string('kelompok', 150)->nullable();
|
||||
$table->string('modaliti2', 150)->nullable();
|
||||
$table->timestamp('created_at')->nullable();
|
||||
$table->timestamp('updated_at')->nullable();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('poli', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('poli', 'poli')) {
|
||||
$table->string('poli', 250)->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'subpoli')) {
|
||||
$table->string('subpoli', 250)->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'subsubpoli')) {
|
||||
$table->string('subsubpoli', 250)->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'modaliti')) {
|
||||
$table->string('modaliti', 150)->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'kelompok')) {
|
||||
$table->string('kelompok', 150)->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'modaliti2')) {
|
||||
$table->string('modaliti2', 150)->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'created_at')) {
|
||||
$table->timestamp('created_at')->nullable();
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('poli', 'updated_at')) {
|
||||
$table->timestamp('updated_at')->nullable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Kolom poli dipakai data production, rollback tidak menghapus kolom.
|
||||
}
|
||||
};
|
||||
@@ -1,6 +1,18 @@
|
||||
# MyLIS Flutter
|
||||
# Mikrobiology Laboratory Information System (MyLIS)
|
||||
|
||||
MyLIS Flutter adalah aplikasi pendamping untuk Laravel LIS lokal. Aplikasi ini fokus pada akses mobile/desktop untuk login, dashboard Early Warning Sistem, daftar pemeriksaan, detail pemeriksaan, dan pengisian expertise per template DLP.
|
||||
MyLIS Flutter adalah aplikasi pendamping untuk Laravel LIS lokal milik Rumah Sakit Umum Daerah Dr. Saiful Anwar. Aplikasi ini fokus pada akses mobile/desktop untuk login, dashboard Early Warning Sistem, daftar pemeriksaan, detail pemeriksaan, dan pengisian expertise per template DLP.
|
||||
|
||||
Nama panjang aplikasi:
|
||||
|
||||
```text
|
||||
Mikrobiology Laboratory Information System (MyLIS)
|
||||
```
|
||||
|
||||
Pemilik aplikasi:
|
||||
|
||||
```text
|
||||
Rumah Sakit Umum Daerah Dr. Saiful Anwar
|
||||
```
|
||||
|
||||
Default URL Laravel lokal:
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application
|
||||
android:label="mylis"
|
||||
android:label="MyLIS"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
|
||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 20 KiB |
@@ -7,7 +7,7 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Mylis</string>
|
||||
<string>MyLIS</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>mylis</string>
|
||||
<string>MyLIS</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
|
||||
@@ -25,6 +25,13 @@ part '../screens/expertise/expertise_form.dart';
|
||||
part '../data/expertise_data.dart';
|
||||
part '../widgets/common_widgets.dart';
|
||||
|
||||
const String kAppShortName = 'MyLIS';
|
||||
const String kAppLongName =
|
||||
'Mikrobiology Laboratory Information System (MyLIS)';
|
||||
const String kHospitalName = 'Rumah Sakit Umum Daerah Dr. Saiful Anwar';
|
||||
const String kAppLogoAsset = 'assets/branding/logo.png';
|
||||
const String kHospitalLogoAsset = 'assets/branding/logo_rssa.png';
|
||||
|
||||
const String kDefaultBaseUrl = String.fromEnvironment(
|
||||
'LIS_BASE_URL',
|
||||
defaultValue: 'https://lis.swandhana.test/',
|
||||
@@ -36,7 +43,7 @@ class MyLisApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'MyLIS Mobile',
|
||||
title: kAppLongName,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
|
||||
@@ -43,7 +43,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Dashboard'),
|
||||
title: const Text(kAppShortName),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: _reload,
|
||||
@@ -131,9 +131,44 @@ class HeaderPanel extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 54,
|
||||
height: 54,
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Image.asset(kHospitalLogoAsset, fit: BoxFit.contain),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
kAppShortName,
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
kHospitalName,
|
||||
style: TextStyle(color: Colors.white70, fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
Text(
|
||||
user['nama']?.toString() ?? '-',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
|
||||
@@ -120,19 +120,38 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.biotech_outlined,
|
||||
size: 72,
|
||||
color: Color(0xFF0F766E),
|
||||
Center(
|
||||
child: Image.asset(
|
||||
kAppLogoAsset,
|
||||
height: 96,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'MyLIS Mobile',
|
||||
kAppLongName,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.headlineMedium
|
||||
?.copyWith(fontWeight: FontWeight.w700),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: 12),
|
||||
Center(
|
||||
child: Image.asset(
|
||||
kHospitalLogoAsset,
|
||||
height: 54,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
kHospitalName,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: const Color(0xFF0F766E),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Login petugas',
|
||||
textAlign: TextAlign.center,
|
||||
|
||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 5.7 KiB |
@@ -5,10 +5,10 @@
|
||||
// 'flutter create' template.
|
||||
|
||||
// The application's name. By default this is also the title of the Flutter window.
|
||||
PRODUCT_NAME = mylis
|
||||
PRODUCT_NAME = MyLIS
|
||||
|
||||
// The application's bundle identifier
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.mylis
|
||||
|
||||
// The copyright displayed in application information
|
||||
PRODUCT_COPYRIGHT = Copyright © 2026 com.example. All rights reserved.
|
||||
PRODUCT_COPYRIGHT = Copyright © 2026 Rumah Sakit Umum Daerah Dr. Saiful Anwar. All rights reserved.
|
||||
@@ -1,5 +1,5 @@
|
||||
name: mylis
|
||||
description: "A new Flutter project."
|
||||
description: "Mikrobiology Laboratory Information System (MyLIS)"
|
||||
# The following line prevents the package from being accidentally published to
|
||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
@@ -60,6 +60,10 @@ flutter:
|
||||
# the material Icons class.
|
||||
uses-material-design: true
|
||||
|
||||
assets:
|
||||
- assets/branding/logo.png
|
||||
- assets/branding/logo_rssa.png
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
|
||||
@@ -17,7 +17,10 @@ void main() {
|
||||
await tester.pumpWidget(const MyLisApp());
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('MyLIS Mobile'), findsOneWidget);
|
||||
expect(
|
||||
find.text('Mikrobiology Laboratory Information System (MyLIS)'),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(find.text('Login'), findsOneWidget);
|
||||
expect(find.text('Username'), findsOneWidget);
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 80 KiB |
@@ -18,18 +18,18 @@
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||
<meta name="description" content="A new Flutter project.">
|
||||
<meta name="description" content="Mikrobiology Laboratory Information System (MyLIS) milik Rumah Sakit Umum Daerah Dr. Saiful Anwar.">
|
||||
|
||||
<!-- iOS meta tags & icons -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="mylis">
|
||||
<meta name="apple-mobile-web-app-title" content="MyLIS">
|
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||
|
||||
<title>mylis</title>
|
||||
<title>Mikrobiology Laboratory Information System (MyLIS)</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "mylis",
|
||||
"short_name": "mylis",
|
||||
"name": "Mikrobiology Laboratory Information System (MyLIS)",
|
||||
"short_name": "MyLIS",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background_color": "#0175C2",
|
||||
"theme_color": "#0175C2",
|
||||
"description": "A new Flutter project.",
|
||||
"background_color": "#F7FAF9",
|
||||
"theme_color": "#0F766E",
|
||||
"description": "Mikrobiology Laboratory Information System (MyLIS) milik Rumah Sakit Umum Daerah Dr. Saiful Anwar.",
|
||||
"orientation": "portrait-primary",
|
||||
"prefer_related_applications": false,
|
||||
"icons": [
|
||||
|
||||